19. C言語での他の超絶技巧事例 (1)
• C コンパイラで SKI コンビネータを遊ぶ
19
#include "ski.c“
S(K(S I I))(S(S(K S)K)(K(S I I)))
#include "ski.c"
IOCCC 2013
“Most lazy SKIer”賞
20. C言語での他の超絶技巧事例 (1)
• C コンパイラで SKI コンビネータを遊ぶ
20
#include "ski.c“
S(K(S I I))(S(S(K S)K)(K(S I I)))
#include "ski.c"
IOCCC 2013
“Most lazy SKIer”賞
ski.c:#ifndef SKI
#define A(x)B(x##0)B(x##1)B(x##2)B(x##3)B(x##4)B(x##5)
#define B(x)C(x##0)C(x##1)C(x##2)C(x##3)C(x##4)C(x##5)
#define C(x)D(x##0)D(x##1)D(x##2)D(x##3)D(x##4)D(x##5)
#define D(x)Z(x##0)Z(x##1)Z(x##2)Z(x##3)Z(x##4)Z(x##5)
#define p(x)(*(*(*(*(*(*x)())())())())())()
#include <stdio.h>
#include <stdlib.h>
#define S (Y(s+6))
#define K (Y(s+4))
#define I (Y(s+2))
#define Z(x)¥
f x;f Y(v);g¥
j;f ¥
x##z( f¥
y){y =y?! x?x= y:Y( m(*( w)&¥
x,(( g)y) (0)) ):x;return y; /*ab c*/}
/**/ typedef void *v ;int
n=0; typedef v* w;typed¥
ef v(*g)();v s[]= {0,0, s+6, s+2,
s+4,s,s+3,s+ 5,s+ 1};w m( v l ,v
r){w e=ma¥
lloc (siz¥
eof( v)*3
);*e =r;e [1
]=l;return (e[2 ]=s, e);} /*de fghi jk*/ typ¥
edef v(p( p(p( p(p( p(p( p(p( p(p(f)))) ))) )))) );A(
x)w u(){ return n --?m (j(0 ),u( )):s+3;}
w z( w e) {w a,b , c,d;for (d =e=m(e,0
);n= (w)d[ 2]-s ,n?* (n>1? n<4? b:a:
c)?n <2?c[ 1]=m (*a, *c), *c=m (*b,
*c):
n>5?
#undef Z
#define Z(x¥
) &x ##z,
a[1]= m(
*a,!*d? d[1] =c=m (0,0 ),n= getchar(),n= n<0?
256:n,c [2]= s+6, *d=u ():* d),*a=d[1]: n<5?n<3?n=z(*
a)-s, putchar( 255< +n?( exit (n-4
*64) ,0):n ),fflush (stdout) ,c[1 ]=
*b:((n-3?b:c )[1] =*a) :(2[* a=z(*a)+1,a
]=s+5),d =e:0 :e;d =d[1 ])c=b,b=a,a=
d;a=
*(w*
)e [1
]; ;;
/*lm no*/ return a;}f( *h [])( )={A (x)0};f Y(v x)
{g y =(g) h[n++] ;y(! y? exit( puts ("out of c" ""
"losure" )),x :x );return(f )y/* pq
r*/;}int main () {z(((g )(S S(
j=(g )S(S (K S)K))(K( S I I)) (S(K(S I))( S(
K K) (S(K (S(S(K(Y(s+1 )) )(S( S S(K I)) (K (Y
(s +5)) ))
)) )K)) )(
#endif
#if (!defined(__INCLUDE_LEVEL__) || !__INCLUDE_LEVEL__) && !defined(SKI)
K(I(I(I(S I I(S(K(S(S(K S)(S(S S S(K(S(K S)))(S(S S S(K(S(K S)))(S(K(S(S(K S)(
S(S(K S)K)(K(S(S(K S)(S(K(S(S(S I(K K))(K K))))(S(K K)(S(S(K S)(S(K(S(S I(K K)
)))(S(K K)(S(S(K K))(K(S(S(S(S(K S)K)))I(S(S(K S)K)I)))))))(S(K K)(S(S(K K))(K
(S(K(S(S(K S)K)I))(S(S(K S)K)(S I I(S(S(K S)K)I)))))))))))(S(K K)(S(K K)(S(S(K
K))(K(S(K(S(S(K S)K)I))(S(S I I)I(S(S(K S)K)I)))))))))))))(S(K K)(S(K K)(S(K(
S(S I(K(S(S I(K(K I)))(K S))))))K)))))(K(K(K K)))))(K(K(K(K I))))))))(S(K(S(K
K)))(S(S(K S)(S(K K)(S(K S)(S(S(K K))I))))(K(S(K(S(S(K S)(S(K(S I))K))))(S(K K
)K))))))(S(S I(K(S I I(S I I(S(S(K S)K)I)))))(K(K K)))S K K K I I I K K K I I
I K K K I I I K K K I I K K K K K S K I I I K I K I I I K I K)I I I K I K I I
I K I I I K I I S K I I I I I K I I I I I K I K I I I K I I I K I I S K I I)I
K I K I I I K I K I I I K I K I I I K I I I K I I S K K K I I I K K K I I I K
K K I I I K K K I I K K K K K S S K I I I K S)K I I K S K K K S K I I K S K I
I I K S S K K K K K S K I I I I S K K K K K S K S K K K K K(K K))
#define SKI
#endif
#ifdef SKI
(Y(s)))))(0));return 0;}
#else
#define SKI
#endif
27. 答え : 冗長化
• 文字列 x と y が一致したとき
どちらも破壊されていない 好きな方を eval すればよい
• 文字列 x と y が異なるとき
長い方は破壊されていない 長い方を eval すればよい
27
x = ”…プログラム…”
y = ”…プログラム…”
eval x if x == y
eval [x, y].max_by {|s| s.size }
次の疑問 :
文字列の外が破壊されたら?
たとえば、ここのダブルクォートが消えたら?