Brainf*ck を Python-oneliner にコンパイルする Python-oneliner

わけのかわらないタイトルですが,そのままです.

import sys;from itertools import ifilterfalse, count;[globals().__setitem__('compile',lambda bf_src : '[globals().__setitem__("dx",0), globals().__setitem__("dseg",[0] * 32768)] '+bf_src.replace('[',' and [ifilterfalse(bool$( dseg#__getitem__(dx) != 0 and [ True ').replace(']','  ] for i in count()))#next() ] ').replace('.',' and [sys#stdout#write(chr(dseg[dx]))] ').replace('+',' and [dseg#__setitem__(dx$dseg[dx] + 1 )] ').replace('-',' and [dseg#__setitem__(dx$dseg[dx] - 1 )] ').replace('>',' and [globals()#__setitem__("dx"$dx + 1 )] ').replace('<',' and [globals()#__setitem__("dx"$dx - 1 )] ').replace(',',' and [globals()#__setitem__("dx"$ord(raw_input(">")[0]))] ').replace('#','.').replace('$',',')),sys.stdout.write('from itertools import ifilterfalse, count;' + compile(sys.argv[2])) if sys.argv[1] == '-s' else eval(compile(sys.argv[1]))]

takano32 のこれを見て
http://taka.no32.tk/diary/20060908.html#p01

  • Python でも出来るかなぁ
  • あ,インデント意識しなきゃだから単純な置き換えじゃ出来なそうだなぁ
  • インタプリタ的に置き換えよう
    • ワンライナだったらいけるんじゃね??

と思って書いてみました.

yoshiori@yoshiori-ubuntu [3]$ python bf.py '>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.'
Hello World!

こんな感じになるのですが,これだけだと面白くないので,コンパイルしたソースも表示出来るようにしました.
引数に [-s] を追加すると中間コード(Python-oneliner)が出力されます.
上記の Hello Workd! を表示する bf は下記のようにコンパイルされます.

yoshiori@yoshiori-ubuntu $ python bf.py -s '>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.'
import sys;from itertools import ifilterfalse, count;[globals().__setitem__("dx",0), globals().__setitem__("dseg",[0] * 32768)]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx - 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [sys.stdout.write(chr(dseg[dx]))]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx - 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx - 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx - 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [globals().__setitem__("dx",dx + 1 )]  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [globals().__setitem__("dx",dx - 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [sys.stdout.write(chr(dseg[dx]))]  and [ifilterfalse(bool,( dseg.__getitem__(dx) != 0 and [ True  and [dseg.__setitem__(dx,dseg[dx] - 1 )]   ] for i in count())).next() ]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [dseg.__setitem__(dx,dseg[dx] + 1 )]  and [sys.stdout.write(chr(dseg[dx]))]

これで,「難解プログラミング言語」は読めねーよ!! って人も読みやすくて有名な Python に変換されるので良かったですね!!


ちなみに id:kazuhookuマジメに素数探索を実行すると
1分くらいかかります.

yoshiori@yoshiori-ubuntu [3]$ time python bf.py '>++++[<++++++++>-]>+++++++[<++++++++>-]<+>+++++++++>>++++++++++[<++++++++++>-]<--[>[-]<[->+>+<<]>>[-<<+>>]<-[>[-]<<[->>+>+<<<]>>>[-<<<+>>>]<+[>>[-]>[-]<<[>+>+<<-]>>[<<+>>-]<>[-]+<[>-<[-]]>[-<<<<[->>+>>+<<<<]>>>>[-<<<<+>>>>]<<+>>]<<-<-]> >[-]+<[[-]>-< ]>[-<>>[-]+<<<<[-]+>>>]<<<-]>>>> >[-]+<[[-]>-< ]>[-<<<<<<<<.>>>[-]++++++[<<++++++++>>-]<<.>>++++++[<<-------->>-]<<<<.>>>>>>>>>]<<<<<<->>[-]<<<[->>+>+<<<]>>>[-<<<+>>>]<>+<[[-]>-<<<->>]>[-<<<+++++++++<->>>>]<<]'
97 89 83 79 73 71 67 61 59 53 47 43 41 37 31 29 23 19 17 13 11 07 05 03 02 
python bf.py   57.01s user 0.04s system 99% cpu 57.496 total