Cの最高の最小限の使い方
xxxxxxxxxx
typedef struct A*B,*(*C)();struct A{C(*d)();B e;}*v(),*b;C n[256];
# include <stdio.h>
#define a (d->e)
#define o (B)printf
#define X(_){return _;}
#define Y(_,A)B _(d,e)B d,e;X(A)
#define Z(P)C P(f,g,h,i)C f,g,h,i;X(P)
#define c(_)(b=(B)malloc(sizeof(*b)),b->d=_,b->e=d,b)
#define _(D,E,F,G,H)B D();Y(D/**/f,E)Y(D/**/g,F)Y(D/**/h,G)Y(D/**/i,H)Y(D,(*(*d->d)(D/**/f,D/**/g,D/**/h,D/**/i))(d,e))
Z(f)
Z(g)
Z(h)
Z(i)
_(j,d,d,j a,j a)
_(k,d,c(h),c(h),c(h))
_(l,c(i),d,c(i),c(i))
_(m,c(g),c(f),l(m a),k(m a))
_(p,d,l(m(d)),k(p a),l(m a))
_(q,l(p(d)),m(d),l a,k(q a))
_(r,m(d),k(mf a),l(r a),k a)
_(s,d,e,o("0",s a),o("1",s a))
_(t,d,p(e),k(t(a,e)),v(k(t(a,e)),e))
_(u,k(e),l(r(e)),k(v(a,e)),l(v(a,e)))
_(v,e,r(e),u(e,a),u(q(e),a))
_(w,o("0"),d,s(d),s(d))
_(x,(*n[getchar()])(d),o("-1"),w(p(d,o("-"))),xh(d))
_(y,xf(mg()),v(d,p(yf())),v(d,yf()),t(d,yf()))
_(z,xf(yf()),(*(*j(d)->d)(w,x))(d),xf(k(d)),xf(l(d)))
main(){
n['(']=zf;n['x']=yi;n['-']=yg;
n['+']=yh;n['0']=zh;n['1']=zi;
n[' ']=xf;n[')']=n['\n']=kf;
o("\n",zg(yf()));}
引用元:https://www.ioccc.org/1989/robison.c
審査員・作者による説明:https://github.com/ioccc-src/winner/blob/main/1989/robison.hint
極小のAPLインタプリタ。2進数の足し算、引き算、掛け算ができる。
$ gcc -o robison robison.c
$ echo "101 x 111 - 100" | ./robison
1111
APLではこれは5 x (7 - 4) = 15を表すとのこと。
$ echo "(101 x 111) - 100" | ./robison
11111
これは(5 x 7) - 4 = 31になっている。
[[1988/robison]]に続き、C言語の利用構文を制限して書かれている(作者はこれをC--と言っている)。
robison.hintに書かれた作者コメントによると、関数呼び出し、間接参照、配列代入、コンマ、sizeof
だけを使用して多倍長2進数計算を実現しているとのこと。
マクロ定義中のD/**/f
をD##f
などに置き換える変更が必要だった。
xxxxxxxxxx
--- robison.c
+++ robison.c
#define Y(_,A)B _(d,e)B d,e;X(A)
#define Z(P)C P(f,g,h,i)C f,g,h,i;X(P)
#define c(_)(b=(B)malloc(sizeof(*b)),b->d=_,b->e=d,b)
-#define _(D,E,F,G,H)B D();Y(D/**/f,E)Y(D/**/g,F)Y(D/**/h,G)Y(D/**/i,H)Y(D,(*(*d->d)(D/**/f,D/**/g,D/**/h,D/**/i))(d,e))
+#define _(D,E,F,G,H)B D();Y(D##f,E)Y(D##g,F)Y(D##h,G)Y(D##i,H)Y(D,(*(*d->d)(D##f,D##g,D##h,D##i))(d,e))
Z(f)
Z(g)
Z(h)