BFで"L"って出力したいなぁ。"L"ってASCIIコードで何番だっけ?
せっかくだからBFでASCIIコード表出力プログラムを作ってそれを見よう。
-[>+.<-]
おそろしく短いですね。でもこれ実行してみると分かるんですけど、とても分かりづらいんですよね。なので分かりやすい物を作りました。
++++++[>>>>++++++++>++++++++>++++++++<<<<<<-] >>>++++++++++<<<++++++[>>>>>>>++++++++++<<<<<<<-] >>>>>>>+<<<<<<<++++++[>>>>>>>>>>>>+++++++++<<<<<<<<<<<<-] >>>>>>>>>>>>++++<<<<<<<<<<<<>-[>>>>>+>>[-]>[-]<<<[>>+>+<<<-] >>>[<<<+>>>-]>[-]>[-]>[<+<+>>-]<[>+<-]>>[-]+<<<[-<<->>]<<[>>>>>-<<<<<[-]] >>[>>>-<<<[-]]>>>[[-]<<<<<<<[-]<<<<<<++++++[>>>>>>++++++++<<<<<<-]>>>>>+>>> [-]>[-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]>[-]>[-]>[<+<+>>-]<[>+<-]>>[-]+<<<[-<<->>] <<[>>>>>-<<<<<[-]]>>[>>>-<<<[-]]>>>[[-]<<<<<<<<[-]<<<<<++++++ [>>>>>++++++++<<<<<-]>>>>+>>>>>>>>>]]<<<<<<<<<.>.>.>.<<<<<+.>.<<-]
おそろしく長いですね。BFでこんなに長いと何がなんだかまったくわかりません。というわけで、コメントをつけてみました。
#1 = LoopCounter #2 = ItemLoopCounter #3 = ItemData #4 = ConstNewLineCode(0x0A) #5:6:7 = ItemCounter #8 = ConstEqual(0x3D) #9:10:11:12 = Temp #13 = ConstMaxItemCounterSize(10::0x3A) #14 = IfFlag #Initialize ItemCounter(000::0x30:0x30:0x30) ++++++[>>>>++++++++>++++++++>++++++++<<<<<<-] #Create ConstNewLine(0x0A) >>>++++++++++ <<< #Create ConstEqual(0x3D) ++++++[>>>>>>>++++++++++<<<<<<<-]>>>>>>>+ <<<<<<< #Create ConstMaxItemCounterSize(10::0x3A) ++++++[>>>>>>>>>>>>+++++++++<<<<<<<<<<<<-]>>>>>>>>>>>>++++ <<<<<<<<<<<< #Set ItemLoopCounter To Max(255::0xFF) >- #Start Output Item [ #ItemCounter3 Process >>>>>+ #Increment ItemCounter3 >>[-]>[-] #Temp1 Temp2 Clear <<<[>>+>+<<<-] #Copy ItemCounter3 To Temp1 Temp2 And ItemCounter3 Clear >>>[<<<+>>>-] #Copy Temp2 To ItemCounter3 >[-]>[-] #Temp3 Temp4 Clear >[<+<+>>-] #Copy ConstMaxItemCounterSize To Temp3 Temp4 And ConstMaxItemCounterSize Clear <[>+<-] #Copy Temp4 to ConstMaxItemCounterSize >>[-]+ #IfFlag On <<< #Position Temp3 [-<<->>]<< #========================= [>>>>>-<<<<<[-]]>> # If Temp1 *EQ Temp3 Then [>>>-<<<[-]]>>> #========================= [ [-] #IfFlag Off <<<<<<<[-] #Set ItemCounter3 To 0(0x00) <<<<<< #Position LoopCounter ++++++[>>>>>>++++++++<<<<<<-] #Initialize ItemCounter3(0::0x30) #ItemCounter2 Process >>>>>+ #Increment ItemCounter2 >>>[-]>[-] #Temp1 Temp2 Clear <<<<[>>>+>+<<<<-] #Copy ItemCounter2 To Temp1 Temp2 And ItemCounter2 Clear >>>>[<<<<+>>>>-] #Copy Temp2 To ItemCounter2 >[-]>[-] #Temp3 Temp4 Clear >[<+<+>>-] #Copy ConstMaxItemCounterSize To Temp3 Temp4 And ConstMaxItemCounterSize Clear <[>+<-] #Copy Temp4 to ConstMaxItemCounterSize >>[-]+ #If Flag On <<< #Position Temp3 [-<<->>]<< #========================= [>>>>>-<<<<<[-]]>> # If Temp1 *EQ Temp3 Then [>>>-<<<[-]]>>> #========================= [ [-] #If Flag Off <<<<<<<<[-] #Set ItemCounter2 To 0(0x00) <<<<< #Position LoopCounter ++++++[>>>>>++++++++<<<<<-] #Initialize ItemCounter2(0::0x30) >>>>+ #Increment ItemCounter1 >>>>>>>>> #Position IfFlag ] ] #Output Process <<<<<<<<<. #Output ItemCounter1 >. #Output ItemCounter2 >. #Output ItemCounter3 >. #Output ConstEqual <<<<<+. #Increment ItemData And Output ItemData >. #Output ConstNewLine <<- #ItemLoopCounter Decrement ]
数字の繰り上がり処理を作るのに苦労しました。
説明はそのうち書くかもしれません。ちなみにここに書いてある英語みたいなのは、めちゃめちゃ適当に書いたものです。偽英語ですね。
ちなみに、同様の出力結果になるプログラムをCで書いてみると以下のようになります。
#include <stdio.h> int main() { for (int i = 0;i < 255;i++) { printf("%03d=%s\n", i, (char *)&i); } return 0; }
数値が0の時のデクリメントは、処理系によっては255にならない場合があります。1バイトが9bitだったり、0の時にデクリメントするとエラーになるように作られていたり…。その辺を頭に入れておいてください。
BrainFuck ENSI規格によると、
Cells can hold values from 0 to 255.
訳:セルは0〜255に値を固定することができます。
となってました。
canは酷いだろ、っつーかこの訳あってんのか?
まぁそれはいいとして、255の値をインクリメントしたら0にしてはいけないとか、0の値をデクリメントしたら255にしてはいけないとか、そんなことは書いてないようです。そのかわり0〜255に固定するのはやってもよさそうな感じですね。でも「固定することができます」だからなんとも言えないけど…。
上記のものはBrainFuck ENSI規格というよりは、BrainFuckGolfのルールでした。まぁいいや。
そのルールの中に、
No over- or underflow allowed.
訳:オーバーまたはアンダーフローは許可されません。
ってのもありました。
えーっとどういうことだ?許可されないってどういう風にとればいいんだ?エラーにしろって事か?255を越えずに固定にするって事か?255を超えたら0にするって事か?もう少し調べてみよう。
上のものは単純にBrainFuckGolfに投稿されるプログラムではオーバーアンダーフローを使用しちゃいけないってだけですね。
なんでそんな単純なことに気づかないんだ…私は…。