2013年09月23日(Mon) 良い月夜 [長年日記]
● 結城 浩さんのナムドット問題 (CodeIQ) が解けた!たぶん!!
コード書きたいけどまとまった時間が取れない僕にとって、 CodeIQみたいなサイトは絶好の逃避先なのであります(コリャ)。 前回挑戦したクロッシング問題ではどうにもならなかっただけに、今回はなんとかしたいと思い、 い く 星 霜、 やっとこわかってきたのは 締切まで24時間を切ってからでした。
問題を眺めててすぐに気づいたことは、
- 数字はピリオドで1から5つに分割されている
- 数字はそれぞれの分割のなかで昇順にソートされている
- 分割の最初の数字は全体のなかで昇順にトートされている
- 最後に5があると次の行は.5
ことくらいだったでしょうか。 あとはずーっと、 問題の数字の羅列をノートに書きうつしてみたりviでいじってみたり、 どうやって数字を移動させるのか、 あるいは分割を変化させるのか考えてました。
- 2つ目の分割に入る数字が5から2まで変化していく
のに気づいて、それじゃあ、次は右側の分割のなかに 再帰的に区切りをつくってみたのだけれど、 規則性が微妙に異なるんですよね。
ピリオドを区切りに表みたいなものを作ってみてやっと気づきました。 結局のところ、
- 最初に右側にあった数字から順に、入る分割が変化していく
- 最初は左から1つ目の分割、次は2つ目、…と増えていく
- 最初に自分の左側にあった数字の入っている分割よりもひとつ余計な分割まで入れる
というルールなのですね。 ぱっとわかると霧が晴れるように全体が見えたのがおもしろかったです。 ついでに、 これまで気づいてたルールがより単純なルールに縮退したのも気持ちよかった。 下記のようなコードで、 数字がピリオド区切りの間を移動していく、変則的なカウンタの数え上げができました。 最大の区切りの求めかたがなんとなく泥臭いし、 計算量も無駄に増えているようには思うのですが、たぶん答えは合ってると思います。
楽しかったです。ありがとうございました。
(追記) 回答にお送りしたコードに、ライセンス文を追加しました。
(追記) 最終的なルールに気づく前に気づいたことを追加しました。
最近のツッコまれどころ