Factorial in Lazy K その 2

Lazy K で階乗を計算するのに 1324 byte で充分とか笑っちゃいますよね。改行抜きで 1192 byte で書けるのに。あと、チャーチ数を使えば階乗の計算自体には Y コンビネータ使う必要なんてないですし、センスないですよ。

S(S(K(SII(S(K(S(K(S(S(KS)(S(KK)(S(S(S(SI(K(S(S(KS)(S(K(S(KS)
))(S(K(S(K(S(S(K(S(K(S(S(K(SS(SS)(SS(KI))(S(KS)K)(S(K(SI))K)
))K)))))(S(K(S(KK)))(S(S(KS)(S(KK)(SI(K(S(K(SI))K)))))(KK)))
)))))(S(S(KS)(S(K(S(KS)))(S(KK))))(K(K(S(S(KS)K))))))))(S(K(
S(KK)))(S(S(KS)(S(S(KS)K)(K(S(S(KS)K)))))(K(K(KI))))))))(K(S
(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK))))(K(KI)))(K(KI)))))))(
S(KK)(S(S(KS)(S(KK)(S(KS)(S(K(S(KS)))(S(K(S(KK)))(S(S(KS)(S(
K(SI))(S(KK))))(K(KI))))))))(K(S(KK)(S(K(S(S(KS)(S(K(SI))(S(
KK)(S(S(SI(SS(SS(KI))))(SS(SSI)(SS(KI))))S(S(KS)K)))))))(S(K
K)K))))))))(SII))))(S(S(S(SII(S(K(S(S(KS)(S(K(S(KS)))(S(K(S(
K(S(S(K(SI(KK)))(S(S(SI(KK))(K(SI(K(KI)))))(K(S(SI(SS(SS(KI)
)))(SS(SSI)(SS(KI)))(S(KS)K)(S(K(S(SI(K(KI)))))K)(SS(SS(SS)(
SS(KI)))(S(KS)K)(S(K(S(SI(KK))))K)(SII(S(K(S(K(S(SI(K(KI))))
)K))(SII))))))))))))(S(S(KS)(S(K(S(KS)))(S(S(KS)(S(KK)(S(KS)
K)))(K(S(K(S(S(S(K(S(SI(SS(SS(KI))))(SS(SSI)(SS(KI)))(S(KS)K
)(S(S(SI(K(S(K(SI))(S(KK)(SI(K(S(S(KS)K))))))))(K(K(KI))))(K
I))))(SI(KK)))(K(S(S(KS)K))))))(S(KK)(S(K(SS(SS(SS)(SS(KI)))
(S(KS)K))))))))))(K(K(SI(K(KI)))))))))(KK)))(SII))(KI))(K(SS
(S(S(KS)K))(K(S(S(KS)K))))))(K(KI)))(KI)))(K(S(SI(K(SS(SS(SS
)(SS(KI)))(S(KS)K))))(K(K(SII(SII(S(S(KS)K)I)))))))

以下コンパイル前のソース

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

(lazy-def '9 '(s s(s s)(s s 0)o))
(lazy-def '10 '(s s(s s(s s)(s s 0))o))
(lazy-def '48 '(s(s i(s s(s s 0)))(s s(s s i)(s s 0))o))

(lazy-def '(isnumber char)
          '(nth char (48 (cons #f) (10 (cons #t) (list-of #f)))))

(lazy-def '(1- n)
          '(n (lambda(g h)(h (g 1+))) (k 0) i))

(lazy-def '(chartoi char)
          '(48 1- char))

(lazy-def '(atoi self n str)
          '(isnumber (car str)
                     (self (+ (chartoi (car str)) (* 10 n)) (cdr str))
                     n))

(lazy-def '(factorial n)
          '(n (lambda(fun m)(* m (fun (1+ m)))) (k 1) 1))

(lazy-def '(divmod10 n)
          '(n (lambda(fun a b) (if> 9 b (fun a (1+ b)) (fun (1+ a) 0))) cons
             0 0))

(lazy-def '(tostr self num str)
          '((divmod10 num)
            (lambda(ndiv10 nmod10)
              ((ifnonzero ndiv10 (self ndiv10) i)
               (cons (+ 48 nmod10) str)))))

(print-as-cc (laze '(lambda(str)
                      (Y tostr (factorial (Y atoi 0 str))
                         (cons 10 end-of-output)))))