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]]が少しネタかぶりしている。

パッチ

パッチをダウンロード