Brainfuckで「酒が飲めるぞー!」
下のtogetterが面白かったので、悪名高い?Brainfuckでやってみることにしました。
プログラマーはプログラミング言語で酒が飲めるぞー!酒が飲める飲めるぞー!酒が飲めるぞー! - Togetterまとめ
といっても140字には収まるわけないのですが。
自作の短縮化した"Hello, world."で何とか113byte、という大変な言語です。
--[>+++>+>+>+>+++++>+++<<<<<<+++++++]>--.>---------.>--..>+.>++++++.------------.>+++++++++++++.<<.+++.<.<-.>>>+. #Brainf*ck
文字制限を考えなければ機械的に作ることも可能ですが、それじゃ面白く無いという事で出来るだけ短縮化しました。
という訳でソースコードです。673byteに収めました。
>>>+[>->>>>>+>+>+>>+>+>>+>->+>>+>>>+>->+>+>+>+>+>+>+>->>++>++<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+++]+[>++>+>+>+>>+>+>+>>+>-->>+>>+>->+>->>+>+>+>-->+>++>+>>+>-->>++> ++<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+++++]>-->++++++++>[+++++++++++++++>]<++++>>++++>++++++>>------->++++++>+>>>->>>>-------->>>+>>------>>+>->++++++>->++++>>--->- -----><[<]<[<]<[<]>[------>>]>[------>>]<<[<]<[<]<[<]<[<]<++++++<++[>+++>>+++++++++++++++++>----------<<<[>>.>.+[>]>.>.[>]>>>.>.[<]<[<]<<.>.[>]>[>]>>>>>.>.[>]>[> ]>[>]>+++>>+<<[<<[<]<[<]<[<]<<.>.[>]>.>.[<]<<<<.>.[>]>[>]>.>.>.>.>.>.>.>.>.>.[<]<[<][>]>[>]>[>]>[>]>>>[<<<<[<]<[<]<[<]<<.>.[>]>.>.[<][>]>[>]>[>]>[>]>>>-]<<-][<]< <.><[<]<[<]<[<]<[<]<[<]<-]<-]
実行した結果はこちら。(via Brainfuckインタープリタ:いで庵)
何がなにやら、ということで簡単な解説を書きました。簡単に言うと、「256でループすることを利用した連立方程式」です。
#BFにコメント機能なんて無いのでこの状態だとエラー出ます。 >>> #条件文用メモリ確保 +[>- <+++] #ascii文字生成部の種。オーバーフローによりループさせる。 +[>++>+>+>+<<<<+++++] #文字生成ルーチンの時と合わせ" 1BF"が生成される。 > # # --> #0x0F -> SP(0x20) -> "1"(0x31) ++++++++> #";" -> "1" ... "9" -> "0" [+++++++++++++++>] #"B" < # ++++> #"F" +[>+>+>+> >+>+ <<<<<<+++] #漢字生成部の種。オーバーフローによりループさせる。 +[>+>+>+> >+>--<<<<<<+++++] #文字生成順は"酒が"を最短で作る目的。 > ++++ > #"月" ++++++ > # > #"飲" -------> # ++++++ > #"酒" + > # +[>+>->+> >+> > >+>->+>+ >+>+ >+>+>+>- > >++>++<<<<<<<<<<<<<<<<<<<<+++] +[>+> >+>->+>-> >+>+>+>-->+>++>+> >+>--> >++>++<<<<<<<<<<<<<<<<<<<<+++++] > #平仮名生成部の種。オーバーフローによりループさせる。 #"がはで めるぞー!\r\n" を出力。"で"と"め"にはジャンプ用のnullが入る。(各文字種間にもnullはある) > #"が" -> # > #"は" > # > #"で" --------> # > #null > #"め" +> # > #"る" ------> # > #"ぞ" +> # -> #"ー" ++++++> # -> #"!" ++++> # > ---> #"\r" ------> #"\n" < [<]< #ジャンプ [<]< [<]> [------>>] #平仮名のshiftjisの1バイト目はほぼ0x82のため一括変換する > [------>>] #上に同じ << [<]< #ジャンプ [<]< [<]< [<]< ++++++ #ループ6回 < ++ #二週目用(10〜12) [ > +++ #追加ループ3回(一周目9回・二周目三回。)これで1〜9と10〜12を分岐 >> +++++++++++++++++ #0x0F -> SP(0x20) -> "1"(0x31) > ---------- #";" -> "1" ... "9" -> "0" <<< [ #ループ。while文のようなもの >> #以下文字生成部。「〜月は」「BFで」「酒が飲めるぞー!(酒が)」*3回 .> .+[>]> .>.[>]> >> .>.[<]<[<]<< .>.[>]>[>]> >>>> .>.[>]>[>]>[>]> +++ >>+ << [ <<[<]<[<]<[<]<< .>.[>]> .>.[<] <<<< .>.[>]>[>]> .>.>.>.>.>.>.>.>.>.[<]<[<] [>]>[>]>[>]>[>]>>> [ << <<[<]<[<]<[<]<< .>.[>]> .>.[<] [>]>[>]>[>]>[>]>>> -] << -] [<]<< .> < [<]<[<]<[<]<[<]<[<]< -] < -]