Most Obfuscated Translator
もっとも難読化された変換器
受賞者:Tony Finch
引用元:https://www.ioccc.org/1998/fanf.c
審査員・作者による説明:https://github.com/ioccc-src/winner/blob/main/1998/fanf.hint
動作
ラムダ式からSKIコンビネータの式に変換する。
$ gcc -E fanf.c > fanftmp1.c
$ gcc -E fanftmp1.c > fanftmp2.c
$ gcc fanftmp2.c -o fanf
$ echo '((\a(\b(\c(d)))) e)' | ./fanf
((K(K(Kd)))e)
$ echo '(\f\g\x
(
(g x) (f x)
) K K z
)' | ./fanf
(((((S(K(SS)))K)K)K)z)
$ echo '(\f(\f\g\x( (f((\a(g(b))) e)) (g x) ) K K z))' | ./fanf
(K(((((S((S(KS))((S(K(S(KS))))((S(K(S(KK))))((S((S(KS))K))(K((S((S(KK))((SI)(Kb))))(Ke))))))))(KI))K)K)z))
$ echo '(Y\f\n
((= n 0)
1
(* n (f (- n 1)))
)
)' | ./fanf
(Y((S(K(S((S((S=)(K0)))(K1)))))((S(K(S*)))((S((S(KS))K))(K((S-)(K1)))))))
解説
おそらく、関数型プログラミングを主題とした初の作品。
このプログラムは2部構成になっている。
前半はOFL(Obfuscated Functional Language)の処理系、後半は上記の式変換を行うOFLプログラム。
l ef E(EOF)
の行より前が前半で、後が後半。
OFLは、SKIコンビネータに入出力のプリミティブやYコンビネータなどを加えた感じの言語で、C言語のマクロで表現される。
ただし、カッコの付き方に制約がある((a b c)
と((a b) c)
は通常のSKIコンビネータ式では同じ意味だが、このプログラムで後者のように書くと動かなかった)。
後半部を(Y(S(K G)(S(K(S P))K)))
に置き換えると入力をエコーするだけのプログラムになる(一番最後のe
は残す必要がある)。
ビルドでは2段階でプリプロセスを行う必要がある。
つまりプリプロセスを行うと、またプリプロセスを行う必要のあるCコードが出力される。
しかし、l ef E(EOF)
のプリプロセス結果が次のように改行まじりになってしまい、壊れた#define
文でエラーになった。
そのためEOF
を-1
に置き換える修正を行った。
#define ef E(
# 85 "fanf.c" 3 4
(-1)
# 85 "fanf.c"
)
[[2013/endoh1]]が少しネタかぶりしている。
パッチ
パッチをダウンロード