Derive Your Dreams

about me
Twitter: @kinaba

21:26 15/12/11

円周率おぼえ歌 in Ruby

円周率 π = 3.14159265... を語呂合わせで 「産医師異国に向こう…」 として覚えるみたいなのありますよね。 英語では Piphilology と言って、たとえば、こんなの。

How I wish I could recollect pi easily today...

長さ 3 の単語 (How)、長さ 1 の単語 (I)、長さ 4 の単語 (wish)、… という列で数字の列を覚えたりするそうです。 この方式だとゼロの桁の表現に困りそうですが、ゼロの所には巧みに句読点などの記号を配したり、 あるいはもう少し単純に、長さ 10 の単語を当てて表すのだそうな。

と、いうわけで。

in Ruby

長さ 3 のトークン、長さ 1 のトークン、長さ 4 のトークン、 長さ 5 のトークン、長さ 9 のトークン、長さ 2 のトークン、 長さ 6 のトークン、…という列でできている Ruby プログラムを書いてみました。 (ソースコードの全体はこちら)

$ cat entry.rb
big, temp = Array 100000000**0x04e2
srand big
alias $curTerm $initTerm

(中略)

print pi

このプログラムを暗記すれば、トークンの長さで円周率 242 桁分まで覚えられます。 Ruby 付属の Ripper ライブラリでRubyの字句解析を実行して長さを数えると、こんな感じ。

$ ruby -r ripper -e \
  'puts Ripper.tokenize(STDIN).grep(/\S/).map{|t|t.size%10}.join' < entry.rb
31415926535897932384626433832795028841971693993751058209749445923078164062862089
98628034825342117067982148086513282306647093844609550582231725359408128481117450
28410270193852110555964462294895493038196442881097566593344612847564823378678316
52

ちなみに、プログラムを暗記するのが苦手な人は、単純に実行して下さい。

$ ruby entry.rb
31415926535897932384626433832795028841971693993751058209749445923078164062862...

1万桁まで計算して表示してくれます。

TRICK 2015

と、まあ、こんなプログラムを、意味のわからないRubyプログラムを競うコンテスト TRICK 2015 に投稿してました。 2年前の "いろは歌 in Ruby" に続いての参戦になります。なんか連覇できたみたいです。ありがとうございます。

やってみるとわかるんですが、円周率に沿ったトークン長で意図したプログラムを書くというの、 意外と難しいんですよ、これ。

いや、正確には、意図したプログラムを書く「だけ」なら、少なくとも Ruby では難しくないです。 円周率の中にたまたま狙いにあった数列が現れるまで、要らない桁をひたすら捨て続ければいい。 円周率の中に 123456 という部分があったとして、その部分を捨てたければ [改行]1[改行]22[改行]333[改行]4444[改行]55555[改行]666666[改行] とかすれば副作用無しで捨てられる。

ただ、これをやっていると途方もない長さのプログラムになってしまいます。 例えば x = 1024 という文を書きたかったとして、このトークン長にあった 114 が円周率の中に現れるまで捨て続けるとすると、 大雑把にいって1000桁に1度の割合でしか出てこないので、 この文を一つ書くだけで1000トークン捨てないといけないわけです。 この時点で 4096Byte 以内という TRICK の投稿条件をオーバーしてます。 何とかしてコードゴルフ力を駆使して、 円周率の形に合わせつつ短いプログラムを書く必要があります。

という感じで、一日円周率を睨んでいると、ただの数字が本当に ↑↑↑ こんな風な性格を持ったプログラム片に見えてくるようになりました。 おかげで少しは円周率に親しくなれたかなぁという気がします。

presented by k.inaba (kiki .a.t. kmonos.net) under CC0