ラムダ関数を大量に使ったら、ワンライナーくらい簡単にできそうだなと思ったら一応できた。ワンライナーと呼べるほど立派なものでもないことは重々承知してます。
コード例
1と3を出力した後、20からカウントダウンするやつ。もっと複雑なのもできるけど、面倒臭いので……
(lambda main, getnext, code: main({},0,main,getnext,code))(lambda ns, ln, main,getnext,code: main(ns,getnext(ln, code[ln](ns, ln),code),main,getnext,code) if ln >= 0 else 0,
lambda now,next,code: min(list(filter(lambda x:x>now,code.keys()))) if next is None else next,
{
0:lambda ns, ln:print(1),
1:lambda ns, ln:print(3),
2:lambda ns, ln:ns.update({'i':20}),
3:lambda ns, ln:None if ns['i'] else 7,
4:lambda ns, ln:print(ns['i']),
5:lambda ns, ln:ns.update({'i':ns['i']-1}),
6:lambda ns, ln:3,
7:lambda ns, ln:-1,
}
)
複数行だけど、改行は全部消せます。
基本的なアイディアは
- ns:名前空間、ln:行番号でnsはupdateで更新。lnはレジスタのPCを若干意識してます
- code内のラムダ関数を逐次実行
- 関数の返り値は次に実行する行番号を示す。Noneなら次の行を探して実行。
なので、基本的にgotoを使っているのと同じ。チューリング完全を示すのはそんなに難しくなさそうだけど面倒臭いので誰かやって下さい。多分brainf**kと一対一対応するものが見つかるとかそんなノリ。
Pythonでワンライナーできます!!!!っていうより、ラムダ使っていいならワンライナーくらい楽勝だよね、というデモンステレーションです。
Update 12/14
Pythonでのワンライナーを参考にglobal()を消しました。