Lazy Kのクワインを約半分に短縮

http://d.hatena.ne.jp/fumiexcel/20120402 のクワインを46085bytesから25677bytesに短縮した。

こっちが古いコード。

(lazy-def '(++ self xs ys) '(s (null? xs) (o (cons (car xs)) (self (cdr xs))) ys))

(lazy-def 'syms '(cons 115 (cons 96 (cons 107 (cons 105 ()))))) ; ['s', '`', 'k', 'i']

(lazy-def 'f '(s o i (o (s o i (cons 96)) (cons 115)))) ; ``s``s
(lazy-def 'g '(o (cons 96) (cons 107))) ;`k
(lazy-def 'h '(s (o o (o (cons 96))) (o (cons 115)) (cons 107))) ;`ksk

;``s``si`k[a]`k[b]
(lazy-def '(cons-show a b) '(o f (cons 105) (Y ++ (g a) (g b))))

(lazy-def 'quote-unit '(cons 96 ((s o i (cons 107)) end-of-output)))
(lazy-def '(quote-n self origin) '(s cons (o self (o f h)) origin))
(lazy-def 'quote-nums '(s (o cons g) (Y quote-n) (cons 105 ())))

(lazy-def '(quote-show self input) '(if (null? input) quote-unit (cons-show (nth (car input) quote-nums) (self (cdr input)))))

(lazy-def '(show self input) '(if (null? input) () (cons (nth (car input) syms) (self (cdr input)))))

(lazy-def '(main input) '(s (o (Y ++) (Y show)) (Y quote-show) code))

(print-as-unlambda (laze 'main))

そしてこっちが新しいコード。

(load "lazier.scm")
(load "prelude.scm")
(load "prelude-numbers.scm")

(lazy-def '(++ self xs ys) '(s (null? xs) (o (cons (car xs)) (self (cdr xs))) ys))

(lazy-def 'syms '(cons 115 (cons 96 (cons 107 (cons 105 ()))))) ; ['s', '`', 'k', 'i']
(lazy-def '(show self input) '(if (null? input) end-of-output (cons (nth (car input) syms) (self (cdr input)))))

(lazy-def 'f '(s o i (o (s o i (cons 1)) (cons 0)))) ; ``s``s
(lazy-def 'g '(o (cons 1) (cons 2))) ;`k
(lazy-def 'h '(s (o o (o (cons 1))) (o (cons 0)) (cons 2))) ;`ksk

(lazy-def '(cons-show a b) '(o f (cons 3) (Y ++ (g a) (g b)))) ;``s``si`k[a]`k[b]

(lazy-def 'repr-unit '(cons 1 ((s o i (cons 2)) ())))
(lazy-def '(repr-n self origin) '(s cons (o self (o f h)) origin))
(lazy-def 'repr-nums '(s (o cons g) (Y repr-n) (cons 3 ())))

(lazy-def '(repr self input) '(if (null? input) repr-unit (cons-show (nth (car input) repr-nums) (self (cdr input)))))

(lazy-def '(main input) '(Y show (s (Y ++) (Y repr) code)))

(print-as-unlambda (laze 'main))

変更点は至って簡単。コードに何回も何回も

`k```s``s`k```sii``s`k``s`k`s``s`ks``si`k`k`k`ki``s`k`s``s`ks```ss`s``s`ks``s`kk``s`ks``s`k`si```ss`si`kk`kk``s``s`ksk`k``si`k`ki``sii```sii``s`k``s`k`s``s``si`k`k`k`ki`k`kk``s`k`s``s`ks``s`k`si``s`kk``s`k``si`kk``s``s``si`kk`k``si`k`ki`k``s``si`k``s``s`ksk``s`k``s``s`kski``s``s`ksk``s`k``s``s`kski``s``s`ksk```sii``s``s`ksk``s``s`kski`k``s``si`k``s`k``s`k``s``s`kski``s``s`ksk``s``s`kski```s``siii``s``s`kski`k``s``si`k`````sii``s``s`ksk``s``s`kski`s``s`ksk``s`k``s``s`ksk```sii``s``s`kski```s``siii``s``s`kski`k``s``si`k``s``s`ksk``s`k```sii``s``s`kski``s``s`ksk```s``s`kski``s``s`ksk```sii``s``s`kski`k`kk``s`k`s`kk``s``s`ksk`k``si`k`ki``sii```sii``s`k``s`k`s``s``si`k`k`k`ki`k``s``si`k[96]`k````s``s`kski``s`k`s``si`k[107]k`k```sii```sii``s``s`kski``s`k`s`k``s`k```s``s`kski``s`k```s``s`kski``s`k`s``si`k[96]k``s`k`s``si`k[115]k``s`k`s``si`k[105]k``s`k`s``s`k```sii``s`k``s`k`s``s`ks``si`k`k`k`ki``s`k`s``s`ks```ss`s``s`ks``s`kk``s`ks``s`k`si```ss`si`kk`kk``s``s`ksk`k``si`k`ki``sii``s`k``s`k`s``si`k[96]k``s`k``s`k`s``si`k[107]k``s`k``si`kk``s``s``si`kk`k``si`k`ki`k```s``s`k``s``s`ks``s`kk``s`ks``s`k`sik`kk``s`k``s`k`s``si`k[96]k``s`k`s``si`k[107]k```sii``s`k``s`k`s``s``s`ks``s`kk``s`ks``s`k`sik`kk``s``s`ksk`k``s`k```s``s`kski``s`k```s``s`kski``s`k`s``si`k[96]k``s`k`s``si`k[115]k```s``s`k``s`ksk`s`k``s`k`s``si`k[96]k`s`k``s`k`s``si`k[115]k``s`k`s``si`k[107]k``sii``s``si`k[105]`k`kk``s`k`s`k``s`k`s``si`k[96]k``s`k`s`k``s`k`s``si`k[107]k``s``s`ksk`k``si`k`ki``sii[code]

出てくる大きなチャーチ数を一回しか出ないようにしたのだ。

quote-showはチャーチ数のリストをその表現に直す関数だが、せっかく0~3のチャーチ数にs、`、k、iの記号を対応させるshow関数を作ったのだからそれに食わせないともったいない(なぜ気づかなかった!)。
新たに、チャーチ数のリストをshowで表現できる形式にするrepr関数を作り、データとデータの表現を結合してshowを適用するようにした。

ideoneで動くサンプル。 http://ideone.com/dD6Uh