ルーズリーフ

公私におよぶ経験値獲得履歴的ななにか。

POH6京子ちゃん問題をScalaで解いた

最近プログラミングさせてもらえてないので憂さ晴らしに、
同僚に教えてもらった問題に挑戦。

POH6「女子高生プログラマーの大バトル〜コボール文明の逆襲〜」

paiza.jp

Scala使ったとはいえ・・・・激しく残念な使い方をしてます。
本当はかっこいいScalaコードには程遠いけど、

なんだ実はScalaってこんなもんか!全然怖くないじゃん!

って思ってもらえればいいやと開き直って、最近ブログ書いてないし晒しておきます。

マサカリは歓迎します、むしろ待ってます。
社内で自分が書いたScalaコードのレビューってしてもらったことないせいかなかなか進歩がない...

import scala.collection.mutable.ListBuffer

object Main extends App {
  val sc = new java.util.Scanner(System.in)
  
  val n = sc.nextInt
  val nList = List.fill(n)(sc.nextInt)
  val m = sc.nextInt
  val mList = List.fill(m)(sc.nextInt)

  val goal = ListBuffer.empty[Int];
  val tp = ListBuffer.empty[Int];

  def last(elm :Int, pre :Int) :Int = {
    if (elm == 0) -1 // End
    else {
      val now = elm + pre
      val ni = now - 1
      now match {
        case x if x == n => x // Goal
        case x if x > n | x < 1 => -1 // Over
        case x if tp.contains(x) => -1 // Loop
        case x => tp += x; last(nList(ni), x) // Next
      }
    }
  }

  mList.foreach { elm =>
    tp.clear()
    if (goal.contains(elm)) println("Yes")
    else {
      last(elm, 1) match {
        case x if x == n => goal += elm; println("Yes")
        case _ => println("No")
      }
    }
  }
}

色々詰まったり迷った部分

  • 場所をインデックスで持つか何マス目で持つか、迷ったあげく「何マス目」かで持ちまわることに

  • テストでタイムアウトが出てしまい、一度計算してゴールできることがわかっている結果は goal に入れることに

    • ついでにダメって判明した数字も別のリストに入れておけばよかったなと今更反省
  • 移動が無限ループしてしまうのを避けるために、一度通ったマスは tp に入れることに

    • ここに気付くのに時間かかったあげくclearしなきゃいけないとかカッコ悪い泣きたい

そもそも if-else と match を入れ子にするとかイヤだ吐きそう・・・・。
相変わらず、関数型の強みを理解しきれていないせいで、カッコいい書き方思いつかない。
カッコよく書くとどうなるのか知りたいので、ぜひ模範解答ください!!!

とまあ泣き言も書きましたが、別にこの程度でも「Scalaつかったよ!」って言えるのがScalaの凄いところでもあります。
ほんと、とりあえず書いてみればいいんじゃないかな!!w

もうちょっとカッコよくかけたらまた更新!
その時は変数名ももう少し考えてあげます...w