研究開発者・ellerのTopCoder挑戦記録。言語は主にJavaを使用しています。ドキュメンテーションコメントはSubmit完了後、ブログ掲載前に補完したものです。504.5久々の参加。182.31pt、Ratingは1376に上がりました。00:30問題文:http://www.topcoder.com/stat?c=problem_statement&pm=11096&rd=14514このEasyだけは落とすまいとテストケースを相当書きました。今の自分のRatingでは、Mediumを頑張って通すよりもEasyを確実に通してchallengeで稼ぐ方が確実だと考えるためです。今回はEasyを落とす人が少なかったのでこれだけ通してもあまり嬉しくなかったのですが、方針として大きく誤ってはいないと思うのでしばらくこのEasy死守戦略を続けてみます。HERE}今回は二重ループで解を求める形が最もシンプルで好ましかったのではと思います。ループの回数が足りずに撃墜されているケースもあったので、最低でも何回ループするかをきちんと考えることが重要です。下1桁だけ考えればいいことに着目すると、4で終わる数は少なくとも6個以上にならないこと・7で終わる数は少なくとも10個以上にならないことが言えそう*1ですので、以下のような二重ループにすべきだったのでしょう。20:48GCJは入力の1行目にデータ量、2行目移行に加工対象データが渡されるケースが多そう。した入力形式をどう扱えば良いのか、先人のコードを元に考えてみる。してコードを公開してくださっていることに感謝。<$>とは何か他の箇所は大体理解できるものの、main関数の定義だけは見慣れない<$>演算子が使われていたためよくわからなかった。ひとつずつ分解してみる。getLine<$>演算子はControl.Applicativeで定義されている、fmap関数へのシノニム。わかりやすさのため、fmapに置き換えると以下のようになる。read"の方が優先的に適用される。getLine$より右の式は「入力から得た文字列を空白で区切って[String]に変換し、その各要素を数値に変換することで[数値]を得る」という意味を持っているように見える。実際の型をghciで調べると以下のようにまだIOモナドの形を保っている=入力未実行なので、この解釈は厳密には誤りであろう。雰囲気的にはそんな感じ。「入力をよろしく解釈して[数値]を返すIOモナド」というのが正しいか。[a]実際に使ってみる練習用問題を解いてみる。この問題ではStringを空白で区切って[String]とし、これをreverseすれば目的の出力が得られそう。空白で区切って逆転させるconvert関数をgetLineにfmapすることで、作用させるだけで出力すべき文字列が得られるIOモナドを作ってみる。getLinesubmitしたところcorrectだった。replicateMとforM_を組み合わせた繰り返しはCodeJamでのパターンになりそう。23:00以前Javaで書いた解答はこちら。13メモ化あり参考:http://www.haskell.org/haskellwiki/Memoization2引数関数をメモ化するのはややこしそうだったので、ビットシフトを使って1引数に2引数分の情報を持たせることに。2011にエントリー→フツーに予選落ちの予感→フツーに参加しても面白くないんじゃね?→そうだHaskellにしよう!Haskellは私の「今年の言語」なのだが、なかなか使う機会がなかったので言語のキャッチアップを兼ねようという魂胆。いうことでしばらくの間、以前Javaで解いた問題をHaskellで解き直してみる。解法1文字列置換と再帰を用いた解法。ソートして"NS"を空文字列に置換、その後headとlastがそれぞれ'E','W'ならばそれを取り除いていく。ガードを使用しており個人的にはHaskellっぽくない*1印象。replace関数の引数は第1引数にtargetを持ってきたかったのだが、部分適用を用いるために最後に定義することにした。無名関数を使えば第1引数でも大丈夫なんだろうとは思う。concat解法2まず'E','N','S','W'それぞれの文字数をカウントして、必要な文だけ文字をreplicateしてやる。++にHaskellっぽくない印象を感じるものの個人の趣味の範囲か。解放1より断然シンプル。whereに同じコードが4つも出てくるのでまとめてしまいたいが、Haskellでどうやるのかが謎。"ENSW".toCharArray())とかの採用を検討するところだが。