1989 International Obfuscated C Code Contest Winners
Landon Curt Noll
chongo at tolerant.com
Tue Oct 10 00:34:25 AEST 1989
I am reposting the 1989 International Obfuscated C Code Contest Winners
since it seems that many people did not receive the first posting.
Send comments and questions about the 1989 winners to:
...!{sun,pacbell,uunet,pyramid,amdahl}!hoptoad!judges
judges at toad.com
Please note that the 1990 contest will not open until about March 15, 1990.
Wait for the 1990 contest rules to be posted before sending in entires.
You can send email to the above address if you think you missed the
posting, assuming it is after March 15, 1990 of course. :-)
chongo <For a good prime, call: 391581 * 2^216193 -1> /\cc/\
###########################################################################
# This is a shell archive. Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file". (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# 1989/Makefile 1989/README 1989/fubar.c 1989/fubar.hint 1989/fubar.orig.c
# 1989/fubar.orig.sh 1989/fubar.sh 1989/jar.1.c 1989/jar.1.hint
# 1989/jar.1.orig.c 1989/jar.1.orig.sh 1989/jar.1.sh 1989/jar.2.c
# 1989/jar.2.hint 1989/ovdluhe.c 1989/ovdluhe.hint 1989/paul.c 1989/paul.hint
# 1989/robison.c 1989/robison.hint 1989/rowmer.c 1989/rowmer.hint 1989/rules
# 1989/tromp.bsd.c 1989/tromp.hint 1989/tromp.s5.c 1989/vanb.c 1989/vanb.hint
# 1989/westley.c 1989/westley.hint
: =-=-=-=-=-=-= first line of shar 1 of 1 =-=-=-=-=-=-=-=-=-
echo mkdir ./1989
mkdir ./1989
echo x - 1989/Makefile
sed -e 's/^X//' > "1989/Makefile" << '//E*O*F 1989/Makefile//'
X# %W% %G% %U%
X#
X# 1989 makefile
X
XSHELL=/bin/sh
XCFLAGS=-O
XCC=cc
X
XWINNERS=ovdluhe jar.1 jar.2 fubar westley paul robison rowmer vanb tromp.bsd
XALTERNATE=jar.1.orig fubar.orig tromp.s5
X
Xall: ${WINNERS}
X
Xovdluhe: ovdluhe.c
X ${CC} ${CFLAGS} $? -o $@
X
X# NOTE: jar.1.c outputs its string in one section
X# this program may not print well on some terminals
Xjar.1: jar.1.c jar.1.sh
X rm -f jar.1
X cp jar.1.sh jar.1
X chmod +x jar.1
X# NOTE: The jar.1.orig file is the original entry
Xjar.1.orig: jar.1.orig.c jar.1.orig.sh
X rm -f jar.1.orig
X cp jar.1.sh jar.1.orig
X chmod +x jar.1.orig
X
Xjar.2: jar.2.c
X ${CC} ${CFLAGS} $? -o $@
X
X# NOTE: fubar.c uses the /bin/sh shell
Xfubar: fubar.c fubar.sh
X rm -f fubar
X cp fubar.sh fubar
X chmod +x fubar
X# NOTE: The fubar.orig.c file is the original entry
Xfubar.orig: fubar.orig.c fubar.orig.sh
X rm -f fubar.orig
X cp fubar.orig.sh fubar.orig
X chmod +x fubar.orig
X
Xwestley: westley.c
X ${CC} ${CFLAGS} -Dtrgpune=putchar $? -o $@
X
Xpaul: paul.c
X ${CC} ${CFLAGS} $? -o $@
X
Xrobison: robison.c
X ${CC} ${CFLAGS} $? -o $@
X
Xrowmer: rowmer.c
X ${CC} ${CFLAGS} $? -o $@
X
X# NOTE: this version requires BSD style signals and setitimer
X# this may not work well on low baud rate terminals
X# the file tromp.bsd.c is the original version
Xtromp: tromp.bsd.c
X ${CC} ${CFLAGS} $? -o $@
X touch HI
X -chmod 0666 HI
X# NOTE: sites without BSD style signals and setitimer (e.g. System V.3)
X# should use this version
Xtromp.s5: tromp.s5.c
X ${CC} ${CFLAGS} $? -o $@
X touch HI
X -chmod 0666 HI
X
Xvanb: vanb.c
X ${CC} ${CFLAGS} $? -o $@
X
Xclean:
X rm -f ovdluhe.o jar.2.o fubar.o westley.o paul.o robison.o
X rm -f rowmer.o tromp.o vanb.o
X rm -f x x1 ouroboros.c ouroboros.o fubar.orig.o tromp.bsd.o tromp.s5.o core
Xclobber: clean
X rm -f ${WINNERS}
X rm -f jar.1.o HI
X rm -f ${ALTERNATE}
Xnuke: clobber
X @true
Xinstall: all
X cat ${WINNERS} > /dev/null
//E*O*F 1989/Makefile//
echo x - 1989/README
sed -e 's/^X//' > "1989/README" << '//E*O*F 1989/README//'
X1989 marked the "The Sixth International Obfuscated C Code Contest"
X
XInstructions for use: Run make to compile entries (it is possible
Xthat on System V or non-unix systems the makefile needs to be
Xchanged). Look at the source and try to figure out what the programs
Xdo, and run them with various inputs. If you want to, look at the
Xhints files for (minor) spoilers.
X
XThis year, the Grand Prize was given to the most useful program.
X
XThe "Strangest abuse of the rules" award was given this year to stress
Xthe fact that starting in 1990, compiling entries must result an
Xexecutable regular file.
X
XIn two other cases, we included System V portable versions of winning
Xprograms. The makefile always uses the portable version of the "Best
Xself modifying program" because there as no loss of functionality in
Xusing it. In the case of the "Best game" winner, however, some
Xfunctionality is lost in the portable version and so the makefile uses
Xthe original program. System V users may need to change the makefile
Xto use the s5 version. See the hint files or the Makefile for details.
X
XRules and results were posted to comp.lang.c, comp.sources.unix, and
Xalt.sources. They have been made available on a wide number of Usenet
Xarchive sites such as uunet. The 1989 winners will be published in the
XMicro/Systems Journal.
//E*O*F 1989/README//
echo x - 1989/fubar.c
sed -e 's/^X//' > "1989/fubar.c" << '//E*O*F 1989/fubar.c//'
X
X#include <stdio.h>
X#define QQ 1
X#define TT 1
X#define cc main(c,v) int c; char **v;{char tt[12],qq[7]; int q=0,o=1,l=1,m=1;struct {int c;} f;
X#define ouroboros qq[6]='\0';tt[11]='\0';if(QQ==atoi(v[1])+1){(void)fprintf(stderr,"%s factorial = %d\n",v[1], TT);exit(1);}o=c+f
X#define x ;while(EOF!=(o=getchar())){if(l && q=='Q' && o=='Q'){l=0;(void)getchar();(void)fread(qq,6,1,stdin);(void)printf("Q %6d",atoi(qq)+1);}else
Xif(m && q=='T' && o=='T'){m=0;(void)fread(tt,11,1,stdin);(void)printf("T %9d\n",atoi(tt)*QQ);}else {q=o;(void)putchar(o);}}exit(0);}
Xcc ouroboros.c -o x
X#define zxc ;{/*
Xcat ouroboros.c | x $1 > x1
Xif [ $? -ne 0 ]; then
Xexit
Xfi
Xmv x1 ouroboros.c
Xchmod +x ouroboros.c
Xexec ouroboros.c $1
Xexit
X*/
//E*O*F 1989/fubar.c//
echo x - 1989/fubar.hint
sed -e 's/^X//' > "1989/fubar.hint" << '//E*O*F 1989/fubar.hint//'
XBest self-modifying program: <sequent!fubar> Jay Vosburgh
X
X Jay Vosburgh
X Sequent Computer Systems, Inc
X 15450 SW Koll Parkway
X Beaverton, OR
X 97006
X USA
X
XJudges notes:
X
X Run this with a single digit argument (or wait a long time).
X
X There are 2 versions of this program, the one that was entered,
X and one that was changed by the judges to be more portable. The
X makefile runs the latter version by default.
X
X The blank line at the beginning of the source is mandatory.
X Do you know why?
X
X The shell script run by the makefile joins lines that may be
X cut up by mailers. The file "fubar.orig.c", for example, needs
X the 6th and 7th lines joined together (with a space between
X them) to recreate the original entry. If you fix the file, you
X will need to change the last 8 linnes of "fubar.orig.sh" to read:
X
X cp fubar.orig.c ouroboros.c
X chmod +x ouroboros.c
X csh ouroboros.c $1
X rm -f ouroboros.c x1 x
X
X The more portable version, "fubar.c", can be fixed by joining the
X 7th and 8th lines in the same way. As well, if you fix "fubar.c"
X you will need to also change the last 8 lines to "fubar.sh" to read:
X
X cp fubar.c ouroboros.c
X chmod +x ouroboros.c
X csh ouroboros.c $1
X rm -f ouroboros.c x1 x
X
XSelected notes from the author:
X
X In a nutshell, this is probably the slowest and most
X obnoxious factorial program ever written. Unfortunately,
X the name of the C source must be "ouroboros.c"; the name is
X hard-coded into the program.
X
X The source is a legal shell script and a legal C program.
X The shell script compiles itself, and then executes the
X resulting binary, giving the source as input. The program
X works by successively modifying #define lines each pass through.
X
X Both "indent" and "cb" will damage the program, "indent"
X much more so.
//E*O*F 1989/fubar.hint//
echo x - 1989/fubar.orig.c
sed -e 's/^X//' > "1989/fubar.orig.c" << '//E*O*F 1989/fubar.orig.c//'
X#include <stdio.h>
X#define QQ 1
X#define TT 1
X#define cc main(c,v) int c; char **v;{char tt[12],qq[7]; int q=0,o=1,l=1,m=1;struct {int c;} f;
X#define incest qq[6]='\0';tt[11]='\0';if(QQ==atoi(v[1])+1){(void)fprintf(stderr,"%s factorial = %d\n",v[1], TT);exit(1);}o=c+f
X#define x ;while(EOF!=(o=getchar())){if(l && q=='Q' && o=='Q'){l=0;(void)getchar();(void)fread(qq,6,1,stdin);(void)printf("Q %6d",atoi(qq)+1);}else
Xif(m && q=='T' && o=='T'){m=0;(void)fread(tt,11,1,stdin);(void)printf("T %9d\n",atoi(tt)*QQ);}else {q=o;(void)putchar(o);}}exit(0);}
Xcc incest.c -o x
X#define zxc ;{/*
Xcat incest.c | x $1 >! x1
Xif ($status != 0) then
Xexit
Xendif
Xmv x1 incest.c
Xchmod +x incest.c
Xexec incest.c $1
Xexit
X*/
//E*O*F 1989/fubar.orig.c//
echo x - 1989/fubar.orig.sh
sed -e 's/^X//' > "1989/fubar.orig.sh" << '//E*O*F 1989/fubar.orig.sh//'
X:
X# to run fubar in the 'proper' way
X
X# parse args
Xif [ $# -ne 1 ]; then
X echo "usage: $0 number" 1>&2
X exit 1
Xfi
X
X# run/compile it
Xrm -f incest.c x1 x
Xex - <<EOF
Xr fubar.orig.c
X6,7j
Xw incest.c
XEOF
Xchmod +x incest.c
Xcsh incest.c $1
Xrm -f incest.c x1 x
//E*O*F 1989/fubar.orig.sh//
echo x - 1989/fubar.sh
sed -e 's/^X//' > "1989/fubar.sh" << '//E*O*F 1989/fubar.sh//'
X:
X# to run fubar in the 'proper' way
X
X# parse args
Xif [ $# -ne 1 ]; then
X echo "usage: $0 number" 1>&2
X exit 1
Xfi
X
X# run/compile it
Xrm -f ouroboros.c x1 x
Xex - <<EOF
Xr fubar.c
X7,8j
Xw ouroboros.c
XEOF
Xchmod +x ouroboros.c
Xouroboros.c $1
Xrm -f ouroboros.c x1 x
//E*O*F 1989/fubar.sh//
echo x - 1989/jar.1.c
sed -e 's/^X//' > "1989/jar.1.c" << '//E*O*F 1989/jar.1.c//'
Xchar*_="Hello world.\n";
//E*O*F 1989/jar.1.c//
echo x - 1989/jar.1.hint
sed -e 's/^X//' > "1989/jar.1.hint" << '//E*O*F 1989/jar.1.hint//'
XStrangest abuse of the rules: <...!uunet!mcvax!hutcs!jar> Jari Arkko
X
X Jari Arkko
X Laboratory of Information Processing Science
X Helsinki University of Technology
X Otakaari 1
X 02150 Espoo
X Finland
X
XJudges notes:
X
X On many systems the compiler will not allow you to send the
X object file to /dev/tty. The author suggested:
X
X cc -c -o /dev/tty jar.1.c
X
X On systems that have symbolic links, we suggest:
X
X ln -s /dev/tty jar.1.o
X cc -c jar.1.c
X
X if your system has symbolic links. The shell script run
X by the makefile simply cats the .o file to the terminal
X which can be used as a last resort.
X
X Abuse of the rules winners usually result in a change of the
X rules. Starting in 1990, compiling entries must result an
X regular file which can be executed.
X
XSelected notes from the author:
X
X This program is (supposedly) the smallest C program able to
X print "Hello world.". The compilation itself produces the
X desired printout and the program need not be actually run.
//E*O*F 1989/jar.1.hint//
echo x - 1989/jar.1.orig.c
sed -e 's/^X//' > "1989/jar.1.orig.c" << '//E*O*F 1989/jar.1.orig.c//'
Xchar*He="llo world.\n";
//E*O*F 1989/jar.1.orig.c//
echo x - 1989/jar.1.orig.sh
sed -e 's/^X//' > "1989/jar.1.orig.sh" << '//E*O*F 1989/jar.1.orig.sh//'
X:
X# 'run' jar.1.orig
X
X# run/compile it
Xrm -f jar.1.orig.o
Xcc jar.1.orig.c -c
Xcat jar.1.orig.o
Xrm -f jar.1.orig.o
//E*O*F 1989/jar.1.orig.sh//
echo x - 1989/jar.1.sh
sed -e 's/^X//' > "1989/jar.1.sh" << '//E*O*F 1989/jar.1.sh//'
X:
X# 'run' jar.1
X
X# run/compile it
Xrm -f jar.1.o
Xcc jar.1.c -c
Xcat jar.1.o
Xrm -f jar.1.o
//E*O*F 1989/jar.1.sh//
echo x - 1989/jar.2.c
sed -e 's/^X//' > "1989/jar.2.c" << '//E*O*F 1989/jar.2.c//'
X#define d define
X#d a include
X#a <stdio.h>
X#a <string.h>
X#a <ctype.h>
X#d p char*
X#d P ,(p)
X#d T(E) !strcmp(E,"()")
X#d U return
X#d W while
X#d X sbrk(199)
X#d z atof
X#d e isspace
X#d D A(_)
X#d E S(C(_))
X#d B(y) p y(_)p _;{
X#d G(y,V) B(y)p i;U sprintf(i=X,"%lf",z(E)V z(S(C(D)))),i;}
X
X p sbrk(),*S(),*j(),*O,*H;K,Y,M=14;double
X z();Q(_)p _;{int V=0;W(e(*_))_++;H=_;W(V|!(e
X (*H)|*H==')'||(*H=='('&&H-_)))V+=(*H=='(')-(*H==
X ')'),H++;U H-_;}B(C)U _++,Y=Q(_),_=strncpy(X,_,Y),_[
X Y]=0,_;}B(A)_++,_+=Q(_);W(e(*_))_++;U O=X,*O='(',strcpy(
X O+1,_),O;}B(Z)U _;}B(c)U C(E);}B(q)U A(E);}B(t)p i=E;U H=S(C
X(D)),sprintf(O=X,T(H )?"(%s)":"(%s %s",i,H+1)
X
X ,O;}B(F)U S(C(A(T(E)?D:_)));}L(i,s)p
X
Xi,*s;{U isdigit(*i) ? z(i)!=z(s):strcmp(i,s);}
X B(b)U L(E,S(C(D)))?"()":"t";}B(R)U E;}B(o)U z(E)<z(S(C(D)))?
X "t":"()";}G(f,+)G(g,-)G(h,*)p r[4][2]={"function" P R,
X "quote"P C,"lambda"P Z,"defun"P j};B(j)U r[M][1]=D,*
X r[M++]=C(_);}p not[99][2]={"if"P F,"equal"P b,"<"
X P o,"+"P f,"-"P g,"*"P h,"car"P c,"cdr"P q,
X "cons"P t,"t","t"};B(S)int Li,s;p u;if(
X isdigit(*_)|T(_))U _;for(Y=M;Y--;)
X if(!strcmp(_,*r[Y]))U r[Y][1]
X ;u=E,_=D;if(*u-'(')U(*((p(*)())u)
X )(_);s=Li=M;W(!T(_))r[M][1]=E,*r[M++]
X ="",_=D;O=C(u);W(!T(O))*r[Li++]=C(O),O=A(O);U O=S
X (C(A(u))),M=s,O;}main(){H=O=X,Y=0;W(Y|!e(K=getchar()))K==
X EOF?exit(0):0,Y+=(K=='(')-(K==')'),*H++=K;*H=0,puts(S(O))
X ,
X main();{printf("XLISP 4.0\n");}}
//E*O*F 1989/jar.2.c//
echo x - 1989/jar.2.hint
sed -e 's/^X//' > "1989/jar.2.hint" << '//E*O*F 1989/jar.2.hint//'
XBest of show: <...!uunet!mcvax!hutcs!jar> Jari Arkko, Ora Lassila, Esko Nuutila
X
X Jari Arkko, Ora Lassila, Esko Nuutila
X Laboratory of Information Processing Science
X Helsinki University of Technology
X Otakaari 1
X 02150 Espoo
X Finland
X
XJudges notes:
X
X This is the most useful program entered this year. It is a
X rather large subset of lisp. It has no error recovery, and
X performs rather poorly in a number of cases. Even so, placing
X all this functionality in such a small, densely packed program,
X is impressive enough to win the Best of show award.
X
XSelected notes from the author:
X
X This program implements a Lisp interpreter in 1465 bytes of source.
X Some sophisticated features supported, eg. functionals and recursion.
X The special-forms/functions/variables implemented are:
X
X + - * < ()
X car cdr cons defun equal
X function if lambda quote t
X
X Below are sample lisp expressions you might choose to try as input.
X The program implements a conventional lisp listener, i.e. you type in
X lisp expressions (followed by CR), the program evaluates them and
X prints out the return values. End execution by typing an end-of-file
X character.
X
X (+ 2.5 3.1)
X (defun fib (n)
X (if (< n 2)
X 1
X (+ (fib (- n 2)) (fib (- n 1)))))
X (fib 10)
X (defun ! (x) (if (equal x 0) 1 (* x (! (- x 1)))))
X (! 7)
X (defun fn1 (fn) (+ (fn 1 2) (fn 3 4)))
X (defun fn2 (a b) (+ a b))
X (fn1 (function +))
X (fn1 (function fn2))
X (fn1 (function (lambda (z1 z2) (+ z1 z2))))
X (quote a)
X (cons (quote (a b)) (quote (c d e)))
X (cons (quote (f)) ())
X (car (quote (a b c)))
X (cdr (cdr (quote (g h i))))
X
X Please do not leave any whitespace before the first parenthesis when
X you type your input, or any other unnecessary whitespace. Please try to
X avoid any undefined variables or functions, wrong number of arguments
X etc. All these errors are likely to dump core (i.e. there are no error
X checks in the program).
X
X Traditional Lisp implementations use cons cells as the main data
X structure. Lists are organized of pointer chains of these cells.
X In this program, an alternate representation was chosen: char*'s.
X All list operations, including the ones in the interpreter, are
X made using string representations of the lists. These operations
X must count parentheses and skip whitespace. This leads to extremely
X poor performance!
//E*O*F 1989/jar.2.hint//
echo x - 1989/ovdluhe.c
sed -e 's/^X//' > "1989/ovdluhe.c" << '//E*O*F 1989/ovdluhe.c//'
X#include <string.h>
Xtypedef char ape
X#define D define
X#D EA register
X#D EP unsigned
X#D A 1
X#D AP (A<<A)
X#D P (A<<AP)
X#D AE ((P<<P)<<A)
X#D PE (((A<<P)<<P)<<P)
X#D E ((EP)A>>A)
X#D APE {EA EP ape ea=AE;while(ea--) e[ea]=E;}
X;ape a[PE+A],ap,*ae,p[P+A],e[AE];
Xmain(){ape pe,*ep=a;srand((EP)time((long)E));
Xwhile(((*(ep++)=getchar())!=-A)&&((ep-a)<PE));
X*(ae= --ep)=E;for(ap=E;ap<=P;){APE;if(pe=PA())
X{putchar(pe);if(ap<P){p[ap]=pe;ap++;}else{
Xep=p+A;while(*ep) *(ep-A)= *(ep++); *(ep-A)=pe;}}else break;}}
XPA(){EA ape pe,*ep=a,pa,Ap=E;for(ep=a;ep<ae-P;ep++)
Xif(!strncmp(ep,p,ap)){e[*(ep+ap)]++;Ap++;}if(!Ap)return(Ap);
Xpa=rand()%Ap+A;pe=~E,Ap=!Ap;while((Ap+=e[++pe])<pa);return(pe);}
//E*O*F 1989/ovdluhe.c//
echo x - 1989/ovdluhe.hint
sed -e 's/^X//' > "1989/ovdluhe.hint" << '//E*O*F 1989/ovdluhe.hint//'
XMost humorous output: <...!unido!cernvax!ethz!ovdluhe> Oskar von der Luehe
X
X Oskar von der Luehe
X Institut fuer Astronomie
X ETH - Zentrum
X 8092 Zuerich
X Switzerland
X
XJudges notes:
X
X Run this program using your favorite text file as input. Files
X such as mailboxes, man pages and usenet articles are especially
X recommended. You will get different output each time you run it.
X
X Run the program this way:
X
X ovdluhe < textfile
X
X The program stops when it reaches the end of the template buffer
X by chance or is killed.
X
XSelected notes from the author:
X
X This program implements an "Eddington ape" - it generates
X random text from a supplied template. The template text file
X is read through stdin. The larger the template, the better the
X result. A maximum of 2**12 chars are used. From the template,
X the program calculates the statistics of chars that immediately
X follow a given string (correlator string) of a certain length
X (currently 4 - can be varied by changing the definition for P
X accordingly). A character is randomly chosen, weighted by its
X probability to occur after the correlator string. That
X character is printed to stdout and placed at the end of the
X correlator string, whose first character is discarded.
X Meaningful words are therefore usually preserved, the effect on
X sentences can be dramatically random.
X
X You might want to vary the definition of P between 2 and 10 and
X observe the result.
//E*O*F 1989/ovdluhe.hint//
echo x - 1989/paul.c
sed -e 's/^X//' > "1989/paul.c" << '//E*O*F 1989/paul.c//'
X#include <stdio.h>
X#define f int
X#define v (void)printf(
X#define x ),exit(1);
X#define y ){if(n)c=z(n,u),u=n,n=c;o[i]=n?'0'+(1&*n):'0';}
X#define z(a,b) (f*)(~1&*a^(f)b)
X#define k(l) if(!(l=(f*)malloc(sizeof(l))))v 23+m x if(1&(f)l)v 39+m x*l=
Xr(p,q,d)f*p,*q;{char o[81];f*n=p,i=39,*c,*u=d?q:z(p,q);o[40]='0'+(1&*p);
Xfor(;i>=0;i--y u=d?z(p,q):q;n=p;for(i=41;i<79;i++y o[i++]='\r';o[i++]=0;
Xv o);(void)fflush(stdout);sleep(1);}
Xmain(a,c)char**c;{char*u,*malloc(),*m=
X"Usage: black [string]\n\0No more memory\n\0Unusable memory alignment\n\0jt,s at m@ (beleY%XX&Yz {z&z}i|R(|)*((.)i)hiniFiGJ%FG.JJgJ: ;;&;z {z&z}-RS/ROiOV OP+PsaPh+ijainnjmamfmfAlnnnnphppopv%vvgv.aABiB1/BVP11/1.%..&.OhrR-WV V1#1VP1CcC0R\
X\n\n'CVP0\n!\n\n'\nEaEEnEamat!akckk'kwaww'wz,zzozEit +",
X*n=m;f*q,*p=0,*g,b=3,d;
Xif(a>2)v m x n=a>1?c[1]:n;
X/*v"\t\t\t\t\tV\n");*/
Xk(q)0;u=n;a=~1&'j';
Xwhile(a!='x'){
X /*r(q,p,b);*/
X for(;;u+=3){
X u= *u?u:n;
X if((~1&*u)==a&&(1&*q)<<1==(2&u[2]))break;
X }
X a=~1&u[1];
X d=(8&u[2])>>3;
X if(16&u[2])putchar(u[3]);
X if(4&u[2])*q|=1;else*q&=~1;
X if(b==d)g=p;else{
X g=z(q,p);
X if(!g){k(g)(f)q;*q^=(f)g;}
X }
X p=q;q=g;b=1-d;
X}
X/*r(q,p,b);v"\n");*/exit(0);
X}
//E*O*F 1989/paul.c//
echo x - 1989/paul.hint
sed -e 's/^X//' > "1989/paul.hint" << '//E*O*F 1989/paul.hint//'
XMost complex algorithm: <...!oliveb!cirrusl!paul> Paul E. Black
X
X Paul E. Black
X CIRRUS LOGIC, Inc.
X 1463 Centre Pointe Dr.
X Milpitas, CA
X 95035
X USA
X
XJudges notes:
X
X The original source contained a long line which caused many
X mailers to barf. The original file may be re-constructed by
X removeing the trailing "\" on line 12 and joining lines 12 and
X 13 together without a space.
X
X WHAT FOLLOWS IS A DETAILED PROGRAM EXPLINATION AND SPOILER.
X IF YOU WANT A REAL CHALLENGE, DON'T READ ANY FURTHER AND TRY
X TO UNDERSTAND THE PROGRAM VIA THE SOURCE.
X
X
XSelected notes from the author:
X
X This programs computes and prints Fibonacci numbers by
X simulating a Turing machine with the proper program.
X Understanding the C program, i.e., a Turing machine simulator,
X is only the first and simplest step. The Turing machine
X program must be understood, too! (it is trivial, perhaps even
X natural to write incredibly obscure Turing programs.)
X
X If the program is invoked with an operand, the operand is used
X as the Turing program. It includes a "trace" facility,
X subroutine r (commented out for obscurity), to help write and
X debug Turing programs. Just the thing for some fun in a Theory
X of Computation class.
X
X The Turing machine tape is represented as a doubly linked list
X of pointers. The forward and backward links are XOR'd together
X and stored in one pointer. If we always keep one of the links
X on hand, we can recover the other link at any time. The
X variable q is the scan head (and a pointer at some tape cell),
X and p is a "previous" link. The state of the tape is stored in
X the low order bit of the pointer. Since we always allocate an
X even number of bytes, the low order bit carries no information
X (see portability below.) Memory representing a tape cell is
X allocated when the cell is first scanned. Thus the simulation
X begins with a tape effectively the size of virtual memory set
X to all zeros. Since a header can be added to any Turing
X program to write initial data and position the scan head, this
X is little loss of generality.
X
X The simulated Turing machine has a single tape with either an 1
X or a 0 in each cell. The Turing machine language format is a
X string of three bytes. The first byte is the current state.
X The second byte is the next state. (The last bit of states is
X ignored, e.g., B and C are the same state, in an attempt to be
X able to have interesting words in the program.) The third byte
X is composed of bits. Bit 1 (2&byte) is the symbol scanned,
X i.e. an instruction is selected for state and for a match with
X the symbol under the scan head. Bit 2 (4&byte) is the new
X symbol to be written to the cell. Bit 3 (8&byte) is the
X direction to move the scan head: 0 for left and 1 for right.
X If bit 4 (16&byte) is true, the next character is sent to
X stdout. (I added this feature so programs could print
X results.)
X
X The Turing machine has next state 'j' when it begins. The
X cycle is 1) exit if the state is 'x', 2) find the next
X instruction (given the state and the character under the scan
X head). [The program string is searched forward for the next
X matching instruction. If the end of the string is reached, the
X search begins again at the first of the string. Thus states
X can be used as local labels in different places.] 3) change to
X the next state, 4) print a character if indicated, 5) write the
X tape symbol, and 6) move the scan head. The cycle then repeats
X with step 1. A call to the trace routine is just before step
X 2, but is commented out.
X
X The following ROT13'ed text is a quick outline of the actual
X Turing program:
X
X Urer vf n dhvpx bhgyvar bs gur Ghevat cebtenz: gur
X cerivbhf naq pheerag Svobanppv ahzoref ner xrcg va onfr
X 1 sbez jvgu gur pheerag ba gur evtug. Gur svefg guerr
X fgrcf frg hc gur svefg gjb ahzoref, 1 naq 1. Gura
X [ortvaavat jvgu "@ ("] n znexre bs VVV vf perngrq naq
X gur pheerag ahzore vf pbcvrq gb gur evtug bs gur
X znexre. Gura [ortvaavat jvgu "BI "] gur ahzore vf
X pbairegrq gb ovanel ol ercrngrq qvivqvat ol 2 yrnivat V
X sbe erznvaqre 1, naq VV sbe erznvaqre 0. Arkg
X [ortvaavat jvgu "JI "] gur ovanel ercerfragngvba vf
X cevagrq naq vgf flzobyf naq gur znexre ner renfrq.
X Svanyyl [ortvaavat jvgu "RRa"] gur gjb ahzoref ner
X nqqrq naq gur pheerag ahzore pbcvrq gb gur yrsg gb
X orpbzr gur cerivbhf. Gura gur plpyr ercrngf.
X
X The program requires that the lowest bit of a pointer to be 0.
X
X I could have squeezed the program under 1024 bytes without the
X trace subroutine, but I felt it was important for understanding
X the program. Besides it is fun to watch the tape zooming back
X and forth as the program runs. A much better debugger or trace
X could easily be added.
//E*O*F 1989/paul.hint//
echo x - 1989/robison.c
sed -e 's/^X//' > "1989/robison.c" << '//E*O*F 1989/robison.c//'
X typedef struct A*B,*(*C)();struct A{C(*d)();B e;}*v(),*b;C n[256];
X# include <stdio.h>
X#define a (d->e)
X#define o (B)printf
X#define X(_){return _;}
X#define Y(_,A)B _(d,e)B d,e;X(A)
X#define Z(P)C P(f,g,h,i)C f,g,h,i;X(P)
X#define c(_)(b=(B)malloc(sizeof(*b)),b->d=_,b->e=d,b)
X#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))
XZ(f)
XZ(g)
XZ(h)
XZ(i)
X_(j,d,d,j a,j a)
X_(k,d,c(h),c(h),c(h))
X_(l,c(i),d,c(i),c(i))
X_(m,c(g),c(f),l(m a),k(m a))
X_(p,d,l(m(d)),k(p a),l(m a))
X_(q,l(p(d)),m(d),l a,k(q a))
X_(r,m(d),k(mf a),l(r a),k a)
X_(s,d,e,o("0",s a),o("1",s a))
X_(t,d,p(e),k(t(a,e)),v(k(t(a,e)),e))
X_(u,k(e),l(r(e)),k(v(a,e)),l(v(a,e)))
X_(v,e,r(e),u(e,a),u(q(e),a))
X_(w,o("0"),d,s(d),s(d))
X_(x,(*n[getchar()])(d),o("-1"),w(p(d,o("-"))),xh(d))
X_(y,xf(mg()),v(d,p(yf())),v(d,yf()),t(d,yf()))
X_(z,xf(yf()),(*(*j(d)->d)(w,x))(d),xf(k(d)),xf(l(d)))
Xmain(){
Xn['(']=zf;n['x']=yi;n['-']=yg;
Xn['+']=yh;n['0']=zh;n['1']=zi;
Xn[' ']=xf;n[')']=n['\n']=kf;
Xo("\n",zg(yf()));}
//E*O*F 1989/robison.c//
echo x - 1989/robison.hint
sed -e 's/^X//' > "1989/robison.hint" << '//E*O*F 1989/robison.hint//'
XBest minimal use of C: <robison at a.cs.uiuc.edu> Arch D. Robison
X
X Arch D. Robison
X University of Illinois
X 1304 W. Springfield Ave.
X Urbana, IL
X 61801
X USA
X
XJudges notes:
X
X Sites with punch card facilities will be happy to note that
X the source deck can be re-collated with an ASCII sort.
X
X Note that this program uses only a small subset of the
X constructs that the C language supports.
X
XSelected notes from the author:
X
X This program is a handy picoAPL interpreter written in C--. It
X outputs the evaluation of an APL expression from standard
X input. Functions are limited to dyadic +,-,x, and unary -;
X numerals must be binary. Parentheses may be used for
X grouping. For example:
X
X 101x111-100
X
X prints:
X
X 1111
X
X That is 5x(7-4) is 15. (APL groups from right to left.)
X Extending it to the full APL language should be trivial.
X
X The C-- language improves the C language by removing superfluous
X and confusing features: arithmetic, logical operations, shifts,
X relationals, address-of, and flow control. In fact, the only
X expressions retained are function calls, indirection, array
X assignments, the ',' operator, and sizeof. Despite these
X restrictions, the C-- program does arithmetic on arbitrarily
X large binary numbers.
X
X To obtain a C-- reference, simply rip out the irrelevant pages
X from your K&R C manual. To obtain a C-- compiler, simply rip
X out the irrelevant bytes from your cc compiler.
//E*O*F 1989/robison.hint//
echo x - 1989/rowmer.c
sed -e 's/^X//' > "1989/rowmer.c" << '//E*O*F 1989/rowmer.c//'
X
X
X char
X _3141592654[3141
X ],__3141[3141];_314159[31415],_3141[31415];main(){register char*
X _3_141,*_3_1415, *_3__1415; register int _314,_31415,__31415,*_31,
X _3_14159,__3_1415;*_3141592654=__31415=2,_3141592654[0][_3141592654
X -1]=1[__3141]=5;__3_1415=1;do{_3_14159=_314=0,__31415++;for( _31415
X =0;_31415<(3,14-4)*__31415;_31415++)_31415[_3141]=_314159[_31415]= -
X1;_3141[*_314159=_3_14159]=_314;_3_141=_3141592654+__3_1415;_3_1415=
X__3_1415 +__3141;for (_31415 = 3141-
X __3_1415 ; _31415;_31415--
X ,_3_141 ++, _3_1415++){_314
X +=_314<<2 ; _314<<=1;_314+=
X *_3_1415;_31 =_314159+_314;
X if(!(*_31+1) )* _31 =_314 /
X __31415,_314 [_3141]=_314 %
X __31415 ;* ( _3__1415=_3_141
X )+= *_3_1415 = *_31;while(*
X _3__1415 >= 31415/3141 ) *
X _3__1415+= - 10,(*--_3__1415
X )++;_314=_314 [_3141]; if ( !
X _3_14159 && * _3_1415)_3_14159
X =1,__3_1415 = 3141-_31415;}if(
X _314+(__31415 >>1)>=__31415 )
X while ( ++ * _3_141==3141/314
X )*_3_141--=0 ;}while(_3_14159
X ) ; { char * __3_14= "3.1415";
X write((3,1), (--*__3_14,__3_14
X ),(_3_14159 ++,++_3_14159))+
X 3.1415926; } for ( _31415 = 1;
X _31415<3141- 1;_31415++)write(
X 31415% 314-( 3,14),_3141592654[
X _31415 ] + "0123456789","314"
X [ 3]+1)-_314; puts((*_3141592654=0
X,_3141592654)) ;_314= *"3.141592";}
//E*O*F 1989/rowmer.c//
echo x - 1989/rowmer.hint
sed -e 's/^X//' > "1989/rowmer.hint" << '//E*O*F 1989/rowmer.hint//'
XBest layout: <roemer at cs.vu.nl> Roemer B. Lievaart
X
X Lievaart, Roemer B.
X VU-Informatica, Amsterdam
X Marcusstraat 29/2,
X NL 1091 TJ Amsterdam
X Netherlands
X
XJudges notes:
X
X Do you know what this program does? If you do, look again,
X there is more here than meets the PI.
X
XSelected notes from the author:
X
X Passes lint, but not with the strictest options, for it
X contains some "null-statements", as well two identifiers
X which are, if compilers only take 6 characters, the same. It
X also uses write(2), so not totally system independent.
X
X You are very much invited to pass this program through a
X C-beautifier. (First strip newlines and tabs, if your cb can't
X do that.)
//E*O*F 1989/rowmer.hint//
echo x - 1989/rules
sed -e 's/^X//' > "1989/rules" << '//E*O*F 1989/rules//'
XSubject: 6th International Obfuscated C Code Contest Rules
XNewsgroups: comp.lang.c,comp.unix.wizards
XKeywords: rules,1989,obfuscate,contest,IOCCC
X
X Obfuscate: tr.v. -cated, -cating, -cates. 1. a. To render obscure.
X b. To darken. 2. To confuse: his emotions obfuscated his
X judgement. [LLat. obfuscare, to darken : ob(intensive) +
X Lat. fuscare, to darken < fuscus, dark.] -obfuscation n.
X obfuscatory adj.
X
XGOALS OF THE CONTEST:
X
X * To write the most Obscure/Obfuscated C program under the rules below.
X * To show what should NOT be done in C programs.
X * To provide a safe forum for poor C code. :-)
X
XRULES:
X
X To help us handle the vast volume of entries, we ask that you
X follow the rules below. Sorry for the length, but we need all
X the help we can get!
X
X 1) Your source MUST be 1536 bytes or less, and it must be a complete
X program, not just a subroutine.
X
X 2) To help us process your entries, we ask that you submit entries
X in the following format. Please be sure to include the --- lines,
X otherwise our extraction program may skip your entry!
X
X---header items---
Xname: Your name, of course!
Xorg: School/Company/Organization
Xemail address: Email address from a well known site, or in a registered domain
Xpostal address: Postal address
X include your country as well
Xenvironment: Indicate the Hardware
X and OS under which your program was tested
Xentry: 5 <number of entries sent so far including this one>
Xremarks: <see below>
X---how to compile---
XX Give the command(s) needed to compile your program.
XX Follow the same rules as given for the program below except that the
XX command size must be 160 characters or less.
X---program---
XX Place obfuscated source of 1536 characters or less in this section.
XX Add a leading X to each line to avoid problems with mailers.
XX Some mailers don't like files with very long lines. If your entry contains E
XC lines longer 80 chars we ask you to form continuation line sets. To form E
XC a continuation line set, place an 'E' character at the point of a split E
XC and place a C (instead of an X) at the beginning of the next line. E
XC Finally, end the continuation line set as normal.
XX The E\nC's and leading X's will be removed prior to extraction and thus E
XC they don't contribute toward the source character count. All other E
XC characters are considered to be source. Whitespace after 'X' or 'C' E
XC and before the 'E' is significant, we added it here for readability.
XX Newlines and tabs each count as 1 character. Assume 8 character tab stops.
XX If your entry does not end in a newline, leave a final 'E' on the end. E
X---end---
X
X 3) Regarding the header items:
X
X * Any text outside of the above format will be kept confidential.
X
X * All header lines are required, but you may use 'anonymous'
X for any header line other than 'remarks' or 'entry'.
X
X * In the 'remarks' please include:
X - what this program does
X - why you think the program is obfuscated
X - any other remarks you wish to make
X
X 4) Your entry should be written in common C. (K&R + common extensions)
X Due to the lack of ANSI C compilers, it is suggested, but not
X required, that you avoid use of constructs unique to ANSI C.
X
X 5) The program must be of original work. All programs must be
X in the public domain. All copyrighted programs will be rejected.
X
X 6) Entries must be received between 26-Mar-89 0:00 GMT and
X 26-May-89 0:00 GMT. Email your entries to:
X
X ...!{sun,pacbell,uunet,pyramid,amdahl}!hoptoad!obfuscate
X
X We will attempt to Email a confirmation of receipt of contest
X entries, however since Email is not reliable you may not receive it.
X We regret that we can no longer accept entries via postal mail.
X
X 7) Each person may submit up to 8 entries. Multiple entries must
X be sent in separate Email letters.
X
X 8) Entries that can not be built automatically in a portable makefile
X are not allowed. (e.g., don't use #include "/dev/tty")
X
X
XANNOUNCEMENT OF WINNERS:
X
X * First announcement will be at the Summer 89 Usenix BOF.
X
X * Winning entries will be posted in mid June 1989 to
X comp.sources.unix as well as news groups where these rules
X were posted. (depending on the judges work load)
X
X * Winning entries will be deposited into the uunet archives.
X
X * An article containing the winning entries will be published
X in a future issue of the "Micro/Systems Journal".
X
X * Winners receive international fame and flames! :-)
X
X
XJUDGING:
X
X Awards will be given to the best entry in a number of categories.
X The actual category list will vary depending on the types of entries
X we receive. As a guide, consider using the following:
X
X * The best small one line program
X * The most obscure algorithm
X * The strangest source layout
X * The most useful obfuscated program
X * The most creatively obfuscated program
X * Best obfuscated entry smaller than 256 bytes
X * Best obfuscated entry smaller than 1024 bytes
X * <anything else so strange that it deserves an award>
X
XPOINTS TO PONDER:
X
X People are encouraged to examine winners of the previous
X contests. A copy of these entries was posted to
X comp.sources.unix. Contact the comp.sources.unix moderator, or
X some archive site (such as uunet). Keep in mind that rules
X change from year to year, so some winning entries may not be
X valid entries this year. What was unique and novel one year
X might be 'old' the next year. In short, use your best judgement.
X
X We examine each entry on several levels of confusion. For example
X each entry is judged when we:
X
X * look at the original source
X * run it through: sed -e ',^#[ ]*define,d' | /lib/cpp
X * run it through a C beautifier
X * examine the algorithm
X * compile and lint it
X * execute it
X
X One line programs are best when they are short, obscure and concise.
X
X We tend to dislike programs that:
X
X * are very hardware specific
X * are very OS or Un*x version specific
X (index/strchr differences are ok, but
X socket/streams specific code is likely not to be)
X * dump core or have compiler warnings
X (it is ok only if you warn us in the 'remark' header item)
X * won't compile under both BSD or SYS V Un*x
X * use an excessively long compile line to get around the
X size limit
X * are longer than they need to be
X * are similar to previous winners
X * are similar to previous losers :-)
X
X Simply abusing #defines or -Dfoo=bar won't go as far as a program
X that is more well rounded in confusion.
X
X Unless you are cramped for space, or unless you are entering the
X 'best one liner' category, we suggest that you format your program
X in a more creative way than simply forming excessively long lines.
X
X We like programs that:
X
X * are as concise and small as they need to be
X * do something quasi-interesting
X * pass lint without complaint
X * are portable
X * are unique or novel in their obfuscation style
X * use a number of different types of obfuscation
X * make us laugh and/or throw up :-)
X
X Some types of programs can't excel in some areas. We try to account
X for this by giving awards to programs in a number of areas. Of course,
X your program doesn't have to excel in all areas, but doing well in
X several helps.
X
X Be creative!
X
X The Judging will be done by Landon Noll and Larry Bassel. If you have
X any QUESTIONS or COMMENTS, please feel free to send them to:
X
X ...!{sun,pacbell,uunet,pyramid,amdahl}!hoptoad!judges
X judges at toad.com
X
X however contest entries should be sent to:
X
X ...!{sun,pacbell,uunet,pyramid,amdahl}!hoptoad!obfuscate
X obfuscate at toad.com
X
X
Xchongo <Landon Curt Noll> /\cc/\ hoptoad!chongo
XLarry Bassel {amdahl,ucbvax,cbosgd}|sun!lab
X
Xp.s. The 1989 contest is being dedicated to the |\_.^
X brain that was removed from Bill the Cat. (@ o)
X *Ackpt!* {:}
X U
//E*O*F 1989/rules//
echo x - 1989/tromp.bsd.c
sed -e 's/^X//' > "1989/tromp.bsd.c" << '//E*O*F 1989/tromp.bsd.c//'
Xlong h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K
X=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,
X12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,
X1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,
X12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i]
X){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf(
X"\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+
Xn[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char*
X*V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<
X25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,
X0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+
X12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){
Xfor(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c
X=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G
X(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(
X8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=
X0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen(
X"stty -cbreak echo stop \023;cat - HI|sort -rn|head -20>/tmp/$$;mv /tmp/$$ HI\
X;cat HI","w");fprintf(d,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}
//E*O*F 1989/tromp.bsd.c//
echo x - 1989/tromp.hint
sed -e 's/^X//' > "1989/tromp.hint" << '//E*O*F 1989/tromp.hint//'
XBest game: <tromp at piring.cwi.nl> John Tromp
X
X John Tromp
X Centre for Mathematics and Computer Science (CWI)
X Oetgensstraat 7
X 1701CK Heerhugowaard
X Netherlands
X
XJudges notes:
X
X This is a character terminal version of the TETRIS program.
X It runs on a VT100 compatible terminal or emulator. It is
X best used at 4800 baud or more.
X
X Usage:
X
X tromp [drops_per_sec [cmd_string]]
X tromp.s5 [1 [cmd_string]]
X
X By default, "drops_per_sec", the number of times an object
X will drop in a second, is 2. The default "cmd_string" is
X "jkl pq". The first 6 characters of "cmd_string" relate
X to the following 6 game commands:
X
X j - left
X k - rotate
X l - right
X <space> - drop
X p - pause
X q - quit
X
X Specifying "cmd_string" allows one to re-define the commands.
X The pause command pauses the game, clears the screen and
X prints the current score. To un-pause, type the pause
X character again, which by default is "p".
X
X This original program requires a BSD-style interval timer and
X and new BSD signal interface. If you are using System V.3
X or earlier, for example, you will need to make "tromp.s5"
X instead of "tromp". You can change the default make rule
X by changing "tromp" to "tromp.s5" in the "WINNERS=..." line
X of the Makefile.
X
X The "tromp.s5" version is not as functional as "tromp".
X The "drops_per_sec" is ignored and defaults to 1. The level
X is always reported as 0.
X
X As was stated last year, we are likely to be more strict about
X portability in the future. [ We mean it this time :-) ]
X
XSelected notes from the author:
X
X This program plays the familiar game of `TETRIS' with the
X following features:
X
X * outputs vt100-like escape-sequences for cursor
X positioning and normal/reverse video in curses
X like fashion (minimal output for screen updates)
X
X * continuously increasing speed (except in pause)
X
X * start speed selectable by giving n as first argument,
X where n is the number of drops per second (default=2).
X
X * controls also selectable by giving as the second argument
X a string of 6 characters. By default they are "jkl pq".
X
X * screen is blanked during the pause and the score is shown
X
X * maintains a high-score table
X
X Giving a full path name for the table will result in a
X system-wide hiscore allowing a competition between users.
X
XThe author provided us with the following notes and new version of
Xthe program:
X
X Here is a somewhat improved version of my tetris entry. All the
X changes are in the popen() at the end. Formerly a move was done
X to the HI score file which is not permitted for other users. Now
X other users can change the HI score file. The extra option -m is
X passed to sort, so that it knows that its input files are already
X sorted. The -o output option of sort is used instead of a
X temporary file.
X
X You may also want to consider giving just the raw option to stty
X at the start and -raw at the end. This further reduces the size of
X the program, but has the possible disadvantage that the program
X can only by stopped by 'q' or by the `kill -9' command.
X
Xlong h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K
X=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,
X12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,
X1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,
X12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i]
X){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf(
X"\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+
Xn[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char*
X*V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<
X25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,
X0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+
X12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){
Xfor(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c
X=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G
X(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(
X8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=
X0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen(
X"stty -cbreak echo stop \023;sort -mnr -o HI - HI;cat HI","w");fprintf(d,
X"%4d from level %1d by %s\n",w,l,getlogin());pclose(d);}
//E*O*F 1989/tromp.hint//
echo x - 1989/tromp.s5.c
sed -e 's/^X//' > "1989/tromp.s5.c" << '//E*O*F 1989/tromp.s5.c//'
Xlong h[4];E[80],S;t(){signal(14,t);if(S)longjmp(E,1);}c,d,l,v[]={(int)t,0,2},
Xw,s,I,K=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9
X,-1,1,12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,
X10,-12,1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-
X11,-12,12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i
X])-Q[i]){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);
Xprintf("\033[%dm "+(K-k?0:5),k);K=k;}alarm(1);Q[263]=c=((S=1)&&!setjmp(E))?
Xgetchar():-1;alarm(0);}G(b){for(i=4;i--;)if(q[i?b+n[i]:b])return 0;return 1;}g
X(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char**V,*a;{for(a=C>2?V[2]:
X"jkl pq";i;i--)*n++=i<25||i%12<2?7:0;srand(getpid());system("stty raw -echo");
Xsignal(14,t);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<
X0){if(G(x+12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(
Xj%12==10){for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G
X(x=17)||(c=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if
X(c==a[2])G(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){
Xprintf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=0);
Xwhile(getchar()-a[4]);puts("\033[H\033[J\033[7m");}}system("stty cooked echo")
X;d=popen("cat - HI|sort -rn|sed -n 1,20p>/tmp/$$;mv /tmp/$$ HI;cat HI","w");
Xfprintf(d,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}
//E*O*F 1989/tromp.s5.c//
echo x - 1989/vanb.c
sed -e 's/^X//' > "1989/vanb.c" << '//E*O*F 1989/vanb.c//'
Xmain(Q,O)char**O;{if(--Q){main(Q,O);O[Q][0]^=0X80;for(O[0][0]=0;O[++O[0][0]]!=0;)if(O[O[0][0]][0]>0)puts(O[O[0][0]]);puts("----------");main(Q,O);}}
//E*O*F 1989/vanb.c//
echo x - 1989/vanb.hint
sed -e 's/^X//' > "1989/vanb.hint" << '//E*O*F 1989/vanb.hint//'
XBest one liner: <...!{decvax|akgua}!ucf-cs!vanb> David Van Brackle
X
X David Van Brackle
X Department of Computer Science
X University of Central Florida
X Orlando, Florida
X 32816
X USA
X
XJudges notes:
X
X This program computes all proper subsets of the set of
X arguments passed to it. Each subset is printed with one
X element on each line, followed by a line of ten dashes.
X
X Try:
X
X vanb the rug gary lent
X vanb unix is better than os/2
X
XSelected notes from the author:
X
X The program has the following charming and possibly
X non-portable features:
X
X * It has no local or global variables,
X only the command-line parameters.
X
X * It calls main recursively.
X
X * It alters the command-line parameters.
X
X * It uses the fact that if the high bit is set in a character
X variable, the value is negative.
//E*O*F 1989/vanb.hint//
echo x - 1989/westley.c
sed -e 's/^X//' > "1989/westley.c" << '//E*O*F 1989/westley.c//'
X
X/**//*/};)/**/main(/*//**/tang ,gnat/**//*/,ABBA~,0-0(avnz;)0-0,tang,raeN
X,ABBA(niam&&)))2-]--tang-[kri - =raeN(&&0<)/*clerk*/,noon,raeN){(!tang&&
Xnoon!=-1&&(gnat&2)&&((raeN&&( getchar(noon+0)))||(1-raeN&&(trgpune(noon
X)))))||tang&&znva(/*//**/tang ,tang,tang/**|**//*/((||)))0(enupgrt=raeN
X(&&tang!(||)))0(rahcteg=raeN( &&1==tang((&&1-^)gnat=raeN(;;;)tang,gnat
X,ABBA,0(avnz;)gnat:46+]552&)191+gnat([kri?0>]652%)191+gnat([kri=gnat
X(&&)1-^gnat(&&)1& ABBA(!;)raeN,tang,gnat,ABBA(avnz&&0>ABBA{)raeN
X,/**/);}znva(/*//**/tang,gnat,ABBA/**//*/(niam;}1-,78-,611-,321
X-,321-,001-,64-,43-,801-,001-,301-,321-,511-,53-,54,44,34,24
X,14,04,93,83,73,63,53,43,33,85,75,65,55,45,35,25,15,05,94,84
X,74,64,0,0,0,0,0,0,/**/){ABBA='N'==65;(ABBA&&(gnat=trgpune
X(0)))||(!ABBA&&(gnat=getchar(0-0)));(--tang&1)&&(gnat='n'<=
Xgnat&&gnat<='z'||'a'<=gnat&&gnat<='m'||'N'<=gnat&&gnat<='Z'
X||'A'<=gnat&&gnat<='M'?(((gnat&/*//**/31/**//*/,21,11,01,9,8
X,7,6,5,4,3,2,1,62,52,42,/**/)+12)%26)+(gnat&/*//**/32/**//*/,
X22,12,02,91,81,71,61,51,41{=]652[kri};)/*pry*/)+65:gnat);main
X(/*//**\**/tang^tang/**//*/,/* */,~/*//*-*/tang,gnat,ABBA-
X0/**//*/(niam&&ABBA||))))tang( rahcteg&&1-1=<enrA(||))tang(
Xenupgrt&&1==enrA((&&)2&gnat(&& )1-^tang(&&ABBA!(;)85- =tang
X(&&)'a\'=gnat(&&)1-==gnat(&&)4 ==ABBA(&&tang!;))))0(enupgrt=
X gnat(&&)tang!((||)))0(rahcteg =gnat(&&tang((&&ABBA;;)1-'A'=!
X'Z'=tang(&&ABBA{)enrA/***/);gnat ^-1&&znva(tang+1,gnat,1+gnat);
X main(ABBA&2/*//*\\**/,tang,gnat ,ABBA/**//*/(avnz/**/);}/*//**/
//E*O*F 1989/westley.c//
echo x - 1989/westley.hint
sed -e 's/^X//' > "1989/westley.hint" << '//E*O*F 1989/westley.hint//'
XMost algorithms in one program: <westley at starfire> Merlyn LeRoy (Brian Westley)
X
X Merlyn LeRoy (Brian Westley)
X Starfire Consulting
X 1026 Blair Ave.
X St. Paul, MN
X 55104
X USA
X
XJudges notes:
X
X There is a secret way to get ONE of the versions to print out
X "Hello, world!\n". Can you find how to do it?
X
X Try the following commands:
X
X westley < westley.c > ver0.c
X westley 1 < westley.c > ver1.c
X westley 1 2 < westley.c > ver2.c
X westley 1 2 3 < westley.c > ver3.c
X
X Try compiling and running the 4 resulting programs.
X
XSelected notes from the author:
X
X This is a filter. If it is run with no arguments, it copies
X stdin to stdout. With one argument, it ROT13's stdin to
X stdout. With two arguments, it reverses stdin to stdout. With
X three arguments, it does both. It requires the ASCII character
X set, with all characters being in 0..255, and EOF must be -1.
X Also requires two's complement (I think).
X
X The source code will run if ROT13'ed and/or reversed, using a
X different algorithm for each version (hereafter referred to as
X ver0 (original), ver1 (ROT13), ver2 (reversed), and ver3
X (ROT13 and reversed)).
X
X When compiling these versions, one needs to define 'trgpune'
X in the compile line. Example:
X
X cc -Dtrgpune=putchar ver3.c -o ver3
X
X "trgpune" is the ROT13 of getchar(), so getchar() and putchar()
X are exchanged in the ROT13 counterpart. It is easy to see that
X this is unavoidable. I must have a #define for a library
X function; otherwise I would have an unidentifed extern for the
X ROT13 version. If I then define this function, it won't link
X in the library version for the ORIGINAL code, since my
X definition will supercede the library function. Hence, the
X compiler option gives me putchar(), and allows me to use
X getchar(). I pass a dummy argument to getchar() to eliminate
X "variable number of args" from lint (unless it checks against
X the library). Otherwise, all versions lint reasonably (main
X returns random value & constant in conditional context [when I
X check for ROT13 version] is all it complains about).
X
X ver0 and ver1 use a range check and a calculation to do ROT13,
X while ver2 and ver3 use table lookup. All versions contain
X main() and it's ROT13 fn, znva(). ver0/ver1 [ver2/ver3] are
X (of course) syntactically identical, since the syntax is in the
X non-alphabetic characters. However, since one program starts
X at main() while it's ROT13 counterpart starts at znva(), znva()
X calls main (znva() is also used for output).
X
X All versions use recursion to work. If the program is NOT
X reversing it's output, it prints out the (possibly ROT13'd)
X character before recursing, otherwise it prints it out
X afterward (or doesn't recurse at all when EOF is reached).
X Since most of this code is identical, it is put into znva() and
X called with a first parameter of 0 as a flag (as "main()", it's
X first argument (argc) must be at least one).
X
X I can't use any flow control. If I used if(), I would have a
X function vs() to define in the ROT13 version. But a function
X called vs() turns into a function called if() in the original,
X so it can't be done. Therefore, I do:
X
X expr1 && expr2 && (expr3=etc);
X
X which is the same as:
X
X if (expr1 && expr2) expr3=etc;
X
X A/UX on the Macintosh doesn't get this right; it evaluates ALL
X expressions if they aren't in an assignment or conditional
X statement. This might warrant a warning, since other compilers
X may do this. I found MANY compilers botched:
X
X expr1 && (expr2,expr3);
X
X expr2 was OFTEN evaluated even if expr1 was false. I removed
X such statements to make it more portable.
X
X The variable names are worth noting:
X
X 'irk' and 'vex' are ROT13 pairs and are synonyms.
X 'Near' and 'Arne' are ROT13 pairs and are anagrams.
X 'NOON' and 'ABBA' are ROT13 pairs and are palindromes.
X 'tang' and 'gnat' are both ROT13 and palindrome pairs!
X
X Normally (!), a reversible C program is done thus:
X
X /**/ forward code /*/ edoc drawkcab /**/
X
X If your compiler nests comments, it will get this wrong.
X However, I have made some bits of the code palindromic,
X (or different, but reversible) so it is more like:
X
X /**/forward/*//**/ palindromic /**//*/drawkcab/**/
X
X The code can therefore be interlaced. There are eight
X such palindromic bits. You can find them within the
X /*//**/ /**//*/ pairs.
X
X The body of the code of ver0 and ver1 is a large lumpy 'K' (for
X Kernighan); the code of ver2 and ver3 is a flat-topped and
X lumpier 'R' (for Ritchie). Judicious use of spaces and tabs
X helped here. It barely fits on an 80x24 screen. Squint. Note
X that the code must start with a blank line, or the reversed version
X will lack a terminating newline.
//E*O*F 1989/westley.hint//
echo Possible errors detected by \'wc\' [hopefully none]:
temp=/tmp/shar$$
trap "rm -f $temp; exit" 0 1 2 3 15
cat > $temp <<\!!!
83 283 1841 Makefile
26 224 1317 README
19 77 729 fubar.c
54 293 1808 fubar.hint
18 75 716 fubar.orig.c
19 55 258 fubar.orig.sh
19 54 264 fubar.sh
1 2 25 jar.1.c
34 154 973 jar.1.hint
1 2 24 jar.1.orig.c
8 18 113 jar.1.orig.sh
8 18 88 jar.1.sh
44 120 1465 jar.2.c
65 379 2328 jar.2.hint
21 57 678 ovdluhe.c
39 224 1426 ovdluhe.hint
35 74 1149 paul.c
103 828 4708 paul.hint
33 69 1023 robison.c
45 217 1418 robison.hint
36 110 1454 rowmer.c
23 104 673 rowmer.hint
205 1284 7848 rules
19 44 1494 tromp.bsd.c
109 548 4553 tromp.hint
19 41 1466 tromp.s5.c
1 1 149 vanb.c
34 125 846 vanb.hint
24 38 1517 westley.c
120 764 4671 westley.hint
1265 6282 47022 total
!!!
wc 1989/Makefile 1989/README 1989/fubar.c 1989/fubar.hint 1989/fubar.orig.c \
1989/fubar.orig.sh 1989/fubar.sh 1989/jar.1.c 1989/jar.1.hint \
1989/jar.1.orig.c 1989/jar.1.orig.sh 1989/jar.1.sh 1989/jar.2.c \
1989/jar.2.hint 1989/ovdluhe.c 1989/ovdluhe.hint 1989/paul.c 1989/paul.hint \
1989/robison.c 1989/robison.hint 1989/rowmer.c 1989/rowmer.hint 1989/rules \
1989/tromp.bsd.c 1989/tromp.hint 1989/tromp.s5.c 1989/vanb.c 1989/vanb.hint \
1989/westley.c 1989/westley.hint | sed 's=[^ ]*/==' | diff -b $temp -
exit 0
--
For a good prime, call: 391581 * 2^216193 -1
More information about the Comp.unix.wizards
mailing list