新宿Scala座 第6回をやってきました。
今回はライブコーディングに挑戦してみようと思い、最近話題の新入女子社員のコードを直すやつをScalaを利用して実践してきました。
事前にコードを書いていって、解説をしながら改めてコーディングを行いましたが、説明って結構難しいですね。設計の説明と、どうやって実装をしているのか、Scalaの関数の役割説明etc...。Scalaを知らない人でも分かるように、と心がけたつもりでしたがまだまだですね。
以下コードです。Listの最大値を得るmax
の存在はid:white-azaleaさんに教えてもらいました。List系の関数は沢山あって、把握するのが大変ですね。
//readlineで標準入力から1行える。" "で区切った配列を作り、各要素をIntとした配列に変換する val line = readLine.split(" ").map(_.toInt) //配列の先頭要素を商品数、末尾要素をキャンペーン日数とする val (products, days) = (line.head, line.last) //商品数分だけ標準入力から数値を得て配列とする val prices = for( i <- 1 to products) yield { readInt } //キャンペーン日数分だけ標準入力から数値をえて配列とする val settingPrices = for( i <- 1 to days) yield { readInt } //商品価格リストから2つの要素を選ぶ組み合わせを全て生成し、 //各組み合わせの合計値を求め、リストを作る val sums = prices.combinations(2) .map(_.sum) .toList //キャンペーンの設定値リストを、求めるリストへ変換する val ansers = settingPrices.map{ sPrice => //商品合計値のリストから、設定値を上回るものを消す val filterdPrice = sums.filter(_ <= sPrice) //フィルターしたリストから最大の要素を得る //フィルターした結果、リストが空なら0とする val retval = filterdPrice match { case Nil => 0 case _ => { //filterdPrice.sortBy(sPrice - _).head filterdPrice.max } } retval } //出力用に整形する val ans = ansers.mkString("\n") println(ans)
さすがScalaですね!コメントを除いて30行程度で書けました。問題は、新入女子社員のコードを直すやつはScalaの提出を受け付けてないことですね!!
Scalaじゃ新入女子社員を救えなかったよ・・・。
ちょっと解説
今回の肝はcombinations
です。引数に渡した要素数の組み合わせをリストから取得し、全ての組み合わせを求めてリストとして返してくれます。他の言語でも、combinations
に該当するものの実装が完了すれば簡単に解ける問題ですね。
ちなみに、Rubyにも同様の実装があるそうです。Javaは多分無いので自前で用意しました。C#もLinqとか使えばいけそうな気がします。
新入女子社員へ
Scalaはリストなどのデータ構造に対する処理を完結に記述できるのでお勧めです。