λx. x K S K @はてな

このブログ内に記載された文章およびコードの著作権は,すべて Keisuke Nakano に帰属します.

2の平方根

SPOJ の Open Contest 2007 にはほとんど OCaml で参戦していましたが, 成績的にはあんまりでした.ocamlopt で勝負させてほしいなぁという感じもしますが….実は,ocamlopt でコンパイルされているらしい.なんだか妙に遅いが…

で,最も盛り上がっていた(?)2 の平方根を求める問題について, yowa さんが Ruby のコードを公開しているので, こちらも Ruby 版を公開(OCaml版もこれのほぼ直訳です). SPOJ では別に golf しなくてもいいんですが,golf し(てしまっ)たものを公開します. Pell number を使えば,

a=7+b=5
$><<'1.'<<10**60000.times{a+=b+b=a}*b/a
で,47B ((Pell number 的には a=2;b=1 が自然ですが,少しでも先を計算するために a=12;b=5(の golf 版)から開始しています.)).ただ,ループの回数が足りないので, 小数点以下 45,934 桁までしか正しい答えを返さず,それ以降はゴミになってしまいます. 実行時間の制約もあったので,このバイト数でこれ以上の精度を出すのは難しかったですね. 間違った桁を表示したくなければ,Pell number を 1 つおきに計算することにより,
a=7+b=5
$><<'1.'<<10**40000.times{a+=2*b+=2*a}*b/a
と,50B で小数点以下 40,000 桁まで正しい答えを返せます. 40,000 を 1,999,998 にすれば 2,000,000 桁出力できて満点がとれますが時間的に無理なので, golf としてはこれくらいが(私の中では)限界です. まぁ,SPOJ ではバイト数は全く評価の対象にならないわけですが….

あ,それから 今年の準備が整ったようなので 参戦される方は前もって登録を.

非ネタばらし

ハミング数を出力する問題OCaml の記録が大幅に縮んだので, 試しに Ruby で書き直したところ,あっさり一位になってしまいました(その後,すぐに flagitious さんに抜かれました.バイナリの 3B って何?). その後,碌に技を知らない Perl,二行以上プログラムを書いたことのない awk*1,初めて書いた PythonPHP でも同様の方法で記録更新. 経験豊富な人からすればまだ縮める余地がありそうなコードなので,すぐに抜かれると思いますが….

ついでに,期限付きのテトリスの問題にもエントリ.OCaml では答えを埋め込んでしまうという狡い方法を使っているので,罪滅ぼし(?)に Perl でまじめな解答を出しておきました. 今のところ,期限付きのものは二問とも(OCaml では)埋め込みの方が短くなってしまう問題なので,もう少し複雑な入出力がよかったなぁ.

[追記1] テトリスには Ruby でも(インチキで)参戦しました.nihaさんに丁寧な解説をしていただきました

[追記2] shebangを見落としていたようで….あとmも余計でしたね.しかし「524/~/#/%?\xca」までは全く考ませんでした.勉強になります.

*1:xgawk と mawk のコードは同じバイト数ですが異なります.実際,一方のコードは他方では動きません.

e の一部のネタバレ

jijixiさんのところで「誰かが100B切ったらヒントを公開」することを宣言してしまった矢先に, airoboさんが95Bを出してくれたので,一部のネタをバラします. と思ったら,jijixiさんも94B出しましたね

続きを読む