頭の体操にLook and Say数列をPythonで書いてみたよ
突然ですが、みなさんは”Please, Don’t Touch Anything”というゲームをご存知でしょうか?このゲームは画面の推移がほぼ無いかなりシンプルな謎解き(?)ゲームなのですが、その謎解きのネタの1つに”Look and Say数列”という数列を使用するものがあります。
まあ、そんな背景は一切関係ないのですが、今回はそんなLook and Say数列を生成するコードを頭の体操を兼ねて書いてみたので、記事にしてみました。ただそれだけです。
OS : MacOS Sierra
Python : 3.6.0
1. Look and Say数列とは?
書いたコードを紹介する前に”Look and Say数列”について簡単に紹介しておきます。”Look and Say”…直訳で「見て言う」です。”Look and Say数列”はその名の通り、ある数列に対して見て言うを繰り返すだけの数列です。
まずは”1″という数列に対して「見て言う」をやってみます。この数列は”1″つの”1″で構成されています。つまり、生成される数列は”11″となります。これだけでは意味不明ですね。では続けて今生成された”11″という数列に対して「見て言う」をやってみます。この数列は”2″つの”1″で構成されています。つまり、生成される数列は”21″となります。続けて”21″もやって見ます。これは”1″つの”2″と”1″つの”1″で構成されているため、生成される数列は”1211″となります。
つまり”Look and Say数列”とは、与えられた数列を頭から見て行き、その数字が何個続いているかを書いていくというめちゃくちゃ単純な数列です。
余談ですが、この数列には色々面白い性質があるみたいです。聞いた話だと、”出力される数列部分は全て1,2,3で構成されている”や”1から始めるとずっと右端の数字が1になる”などがあるみたいです。詳しくは検索してみてください。
2. 実際に書いてみた
さて簡単にですが、”Look and Say数列”についてわかってもらえたかとおもいます。本記事ではこの数列を生成するコードをPythonを使って書いたものを掲載しようと思います。
掲載するコートは特別なライブラリを使用しないという方針で書きました。ちなみに書き方はコードの短さを最優先にしているため、めちゃくちゃ汚いです。ですのであくまで”おまけ”程度にご覧ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#coding: utf-8 def look_and_say(x): r = [] l = [1, x[0]] for n in (x+"x")[1:]: if n is l[1]: l[0] += 1 else: r.append("".join(str(n) for n in l)) l = [1, n] return "".join(r) # テストコード s = 1 for i in range(10): print(s, end=" ") s = look_and_say(str(s)) print(s) |
時間を空けてから見たらおそらく、自分でも「おぅ…」となってしまう機がするので、未来の自分のために簡単な解説を書いておきます。
まず返り値になる”r”は文字列を返すのですが、いちいち文字列を連結していくと(Pythonの仕様上)処理時間がかかるので、リストに格納していき最後に文字列としてまとめます。次に”l”は[lookしている数字の個数, lookしている数字]を格納しているリストです。そうです、変数を2個使えばいいだけなので完全に無駄リストです。
次にfor文の対象となる部分((x+”x”)[1:])です。まず(x+”x”)の部分です。これはいわゆる”門番”の役割を持たせています。といえば格好がつくかもですが、実際には、最後の一文字を結果に反映するために加えただけです。最後に”x”を加えることで、必ずLookしていた数字とは異なるため、Lookしていた数字が結果のリストに追加されることを期待しています。次に”[1:]”ですが、これは一番目の要素は”l”の初期化時に考慮することができるため、二番目から処理を行えばいいためそのように書きました。
最後に、””.join(str(n) for n in l)の部分です。この部分は”Say”に対応する部分なのですが、文字列にするため”str”や”join”を使っています。本当でしたら個数の部分にだけ”str”をすれば解決なのですが、なんかこっちの方が好きだったので、このような結果になりました。
検索するとJavascriptや関数型言語で書かれているものなど、色々な人が色々な言語で色々な書き方をしているので、結構面白いです。
おわりに
Look and Say数列の生成コードはちょっとした時間つぶしにはちょうどいい感じでした。また、プログラミングの勉強やアルゴリズムを考えてコードにする練習にはいいのでしょうか。
今回はPython3.x系でのコードを掲載しましたが、以下のサイトさんにたくさんの種類における数列生成コードの模範解答が掲載されているので、気になる人は、見にいってみてください。自分なんかより賢い方の綺麗なコードを見ることができます。
冒頭でも紹介したゲームもおすすめなのでぜひ遊んでみてください。
「Look-and-say sequence(「ルック&セイ」数列) をJavaで試してみる」