CPPのもっとも完全な使い方
xxxxxxxxxx
# define S(M, L, N, R) J(M, P) (L, N, R )
# define QL(L, R)/* L,*/QR(L, /*N,*/ R)//
# define P( L, N, R) L, N, R//
# define LP( L, N, R) U L, D L, (N, R)
# define R( L, R)W (Y(J(E,X)(K(L, R ))))
# define RP( L, N, R)(L, N), H R, T R//
# define HP( L, N, R) L, N, R//
# define K( L, R)/* L,*/J(F, V)(L, R)J \
( Q,sym_ ( K, M ( L, B R))) (L, R )
# define Q( L, R)/* L,*/QR(L, /*N,*/ R)//
# define E( X)E3(X)
# define break H ,
# define E0(/**/X)X
# define I( X, E) K
# define EX(X)E3(X)
#define E1(_I_)E0 (E0(E0(E0(E0(E0(E0 (E0( _I_ ))))))))
#define E2(_O_)E1 (E1(E1(E1(E1(E1(E1 (E1( _O_ ))))))))
#define E3(_C_)E2 (E2(E2(E2(E2(E2(E2 (E2( _C_ ))))))))
#define E4(_C_)E3 (E3(E3(E3(E3(E3(E3 (E3( _C_ ))))))))
#define E5(_C_)E4 (E4(E4(E4(E4(E4(E4 (E4( _C_ ))))))))
#define E6(_2_)E5 (E5(E5(E5(E5(E5(E5 (E5( _2_ ))))))))
#define E7(_0_)E6 (E6(E6(E6(E6(E6(E6 (E6( _0_ ))))))))
#define E8(_1_)E7 (E7(E7(E7(E7(E7(E7 (E7( _1_ ))))))))
#define E9(_5_)E8 (E8(E8(E8(E8(E8(E8 (E8( _5_ ))))))))
#define QS( L, R) (S (M( L, B R),\
A R , A J(G(L, _) ,B R), C R ))
#define QR( L, R) I sym_(,)(O, (C, \
C)) (C J(G(L, _) ,B R),QS(L, R ))
#define sym__(_ , __ ) _
#define A(A, B , C ) A
#define F(A, _) sym_(_,)
#define sym_(__ , _ ) _
#define B(A, B , C ) B
#define J(A, J) G(A, J)
#define sym___( ___, __)
#define C(A, B , C ) C
#define G(J, G) J ## G
#define RY(Y) Y
#define Y( Y) Y
#define LY(Y) Y
# define Z( L, R) J (B L, /*N,*/ Y)
# define N( L, R) J (G(L, _), B R)
# define HY(L ) (A L, halting)
# define T( R, L) G(sym_, R)(L, (,))
# define H( R, L) G(sym_, R)(R, _ )
# define M( L, R) B J( G(L, _), R )
# define D( L, R) G(sym_, R)(R, _ )
# define U( L, R) G(sym_, R)(L, (,))
# define F0(L, R) F( L, /*N,*/R )
# define F1(L, R) F0( L, /*N,*/R)~
# define F2(L, R) F1( L, /*N,*\R)~
# define F3(L,*/R )R\t<L[B R]>\t-> \
Z (/*)*/ N( L, R) , R) (N( L, R) )\n
# define FV(L, R) F( L, /*N,*/R )
# define QH(L, R) QS( L, /*N,*/ R)
int puts (char*);
# define W(W)O(W)
int main () {puts
# define O(W)#W//
( R ( A, tape));}
引用元:https://www.ioccc.org/2015/muth/prog.c
審査員・作者による説明:https://www.ioccc.org/2015/muth/hint.html
プリプロセッサでチューリングマシン。
5×2を計算する例らしい。
$ gcc -include "machine_times2.h" -include "tape_five.h" prog.c -o prog
$ ./prog
(((((((((((((,), 1), 1), 1), 1), 1), 1), 1), 1), 1), 1), _), _, (,))
他にもいろいろマシンやテープの定義があるので参照のこと。
#if
も再帰#include
もせず、プリプロセッサを繰り返し適用することもなくチューリングマシンを実現しようという試み。
[[2001/herrmann1]]の改善と言えるか。
実際のところプリプロセッサはチューリング完全ではないので、デフォルトでは8^3 = 512ステップだけ遷移を行う。
それで終わらなかったら、途中状態のテープが出力されるとのこと。
なお、このステップ数上限はビルドオプションの-DX=n
で8^n回に変更できる。
また、-DV=1
でステップごとに~
を表示したり、-DV=2
でステップごとのテープの状態を表示したりすることもできる。