Add preview of 1984-2019

The 2020 winners are hinted it, but the source code is not there,
nor are the hints. Someone could look into the HTML and
see what was commented out, but that is not a problem because
WHO won is known and the name of their AWARD is known already.
Moreover a number of the winners have talked about what their
entirs do, so the commented out spoiler text is not a bit problem.

One will find HTML commented out with:

    <!-- XXX remove when 2020 is ready
    2020 links here
    XXX remove when 2020 is ready -->

The "XXX remove when 2020 is ready" string is found at the
start and end comment blocks.  Again, soneone could read
what was commented out, but that is OK since most of that
information is known or can be known.  The following files
have such HTML comment blocks in them.

    ./winners.html
    ./years-spoiler.html
    ./years.html

In addition, ./all/summary.txt was modified to not
include the 2020 entries for the momemt.

The 2020 winner code AND write-ups are NOT part of this set.

p.s. The all/all.tar.bz2 does not contain the 2020 source code (yet?).
This commit is contained in:
Landon Curt Noll committed 2020-12-30 16:57:03 -08:00
1 parent 28efc67f5d
commit c0663537cb
1683 files changed
+220064

No files matched your search

BIN
View File
Binary file not shown.
+119
View File
@@ -0,0 +1,119 @@
# %W% %G% %U%
#
# 1995 makefile
#
# Copyright (c) 1996, Landon Curt Noll, Larry Bassel & Sriram Srinivasan
# All Rights Reserved. Permission for personal, educational or non-profit
# use is granted provided this this copyright and notice are included in its
# entirety and remains unaltered. All other uses must receive prior permission
# from Landon Curt Noll, Larry Bassel and Sriram Srinivasan.
SHELL=/bin/sh
CAT=cat
CHMOD=chmod
CP=cp
ECHO=echo
GUNZIP=gunzip
UUDECODE=uudecode
LN=ln
RM=rm
SED=sed
TRUE=true
# flags for ANSI compiles
#
# NOTE: Some ANSI compilers make use of -Xa to turn on ANSI mode,
# others such as gcc may want -ansi, others may want nothing
# at all. Adjust the CFLAGS line as needed.
#
# NOTE: Some compilers cannot optimize, or optimize some entries
# incorrectly. You might want to turn on -O to see if your
# compiler can handle them.
#
#CFLAGS=-O -Xa
#CFLAGS=-Xa
#CFLAGS= -ansi
CFLAGS= -ansi -O
#CFLAGS=
# ANSI compiler
#
# Set CC to the name of your ANSI compiler.
CC=cc
#CC=gcc
# winners that compile under ANSI C
#
WINNERS= cdua dodsond1 dodsond2 esde garry heathbar leo makarios savastio \
schnitzi spinellis vanschnitz
ALT_NAMES= leo.orig garry.fmt garry.test
LEVEL=5
all: $(WINNERS)
cdua: cdua.c
${CC} ${CFLAGS} cdua.c -o cdua
dodsond1: dodsond1.c
${CC} ${CFLAGS} -DXXXXXX= -DXXXXXXX= dodsond1.c -o dodsond1
dodsond2: dodsond2.c
${CC} ${CFLAGS} dodsond2.c -o dodsond2 -lcurses -ltermcap
esde: esde.c esde.data esde.data2
${CC} ${CFLAGS} esde.c -o esde
garry: garry.c
${CC} ${CFLAGS} garry.c -o garry
heathbar: heathbar.c
${CC} ${CFLAGS} heathbar.c -o heathbar
# The following as a less obfuscated version of garry.
#
garry.fmt: garry.fmt.c
${CC} ${CFLAGS} garry.fmt.c -o garry.fmt
# The following are test progs for garry
#
garry.test: garry.test.sh garry garry.data
rm -f garry.test
cp garry.test.sh garry.test
chmod +x garry.test
leo: leo.c
${CC} ${CFLAGS} -DGa=608 -DAs=792 -DMo=int -DAr='unsigned long' \
-DS='struct Se' leo.c -o leo
# NOTE: this is the original program that was non-interactive
#
leo.orig: leo.orig.c
${CC} ${CFLAGS} -DGa=608 -DAs=792 -DMo=int -DAr='unsigned long' \
-DS='struct S' leo.orig.c -o leo.orig
makarios: makarios.c
${CC} ${CFLAGS} makarios.c -o makarios
schnitzi: schnitzi.c
${CC} ${CFLAGS} schnitzi.c -o schnitzi
spinellis: spinellis.c
${CC} ${CFLAGS} spinellis.c -o spinellis
vanschnitz: vanschnitz.c
${CC} ${CFLAGS} -Dn=${LEVEL} vanschnitz.c -o vanschnitz
clean:
$(RM) -f *.o a.out core ${WINNERS}
clobber: clean
$(RM) -f $(WINNERS)
$(RM) -f $(ALT_NAMES)
nuke: clobber
@${TRUE}
install: all
${CAT} $(WINNERS) $(ALT_NAMES) > /dev/null
+142
View File
@@ -0,0 +1,142 @@
1995 marked the "The Twelfth International Obfuscated C Code Contest"
Copyright (c) 1996, Landon Curt Noll, Larry Bassel & Sriram Srinivasan.
All Rights Reserved. Permission for personal, educational or non-profit use is
granted provided this this copyright and notice are included in its entirety
and remains unaltered. All other uses must receive prior permission in writing
from Landon Curt Noll, Larry Bassel and Sriram Srinivasan.
The IOCCC has an official home page:
http://www.ioccc.org
containing previous winning entries, information about the judges,
announcements and much more.
Use make to compile entries. It is possible that on BSD or non-unix
systems the makefile needs to be changed. See the Makefile for details.
Look at the source and try to figure out what the programs do, and run
them with various inputs. If you want to, look at the hints files for
spoilers - this year we included most of the information included
by the submitters.
Read over the makefile for compile/build issues. Your system may
require certain changes (add or remove a library, add or remove a
#define).
This year Sriram Srinivasan joined the judging.
The moderator of comp.unix.wizards did not feel that the IOCCC was "wizardly"
enough to be posted to comp.unix.wizards - we will no longer post the
winners to this newsgroup - we'll let you the reader decide for yourself the
wizardlyness of these entries.
This year there were several people who won more than once
and several previous winners who won this year. The judging was done
without knowledge of the names of the submitters - multiple winners were
a coincidence. Since we tend to discount entries that are similar to
previous winners, these people have had to come with original ideas to
stay in the winners circle.
We wish to thank CAIP at Rutgers University for the use of their machines.
A few notes regarding future contests
-------------------------------------
Due to changes in the Usenix conference calendar, the 1996 contest will
be delayed. Because there will be no Summer 1996 Usenix conference,
the 1996 IOCCC winners will be announced at the Jan 1997 Usenix
conference.
The 1996 contest will not open until sometime in October 1996, and will
close sometime around the end of December 1996. The rules for the 1996
contest have not been formed at this time and are not expected to be
ready for distribution until late September 1996.
Be sure to wait until the 1996 rules are posted before submitting entries.
Rules differ from year to year, sometimes in significant ways.
Please send us comments and suggestions what we have expressed above.
Also include anything else that you would like to see in future contests.
Send such email to:
...!{sun,pacbell,uunet,pyramid}!hoptoad!judges
judges@toad.com
If you use, distribute or publish these entries in some way, please drop
us a line. We enjoy seeing who, where and how the contest is used.
If you have problems with any of the entries, AND YOU HAVE A FIX, please
EMail the fix (patch file or the entire changed file) to the above address.
Credits
-------
We would like to thank Barbara Frezza for her role as official chef of
the contest. Landon Noll, Larry Bassel and Sriram Srinivasan
appreciated the opportunity to serve as official taste testers. And as
usual, the food was excellent. The official menus of the 1995
Obfuscated C Contest dinners were:
Session One:
Antipasti: Crudites, olive selection, pickles, cheese selection
Soup: Homemade mushroom and green onion soup
Salad: artichoke, red bell peppers, Italian onions, cucumbers
and Greek olives with mustard vinaigrette
Main Course: Pizzas, with a variety of toppings
Dessert: Chocolate torte
Session Two:
Antipasti: crudites, olives, roasted red peppers, cheese selection
Salad: Mixed greens with vinaigrette
Main Course: Spaghetti with tomato sauce containing mushrooms and black olives
selection of hot and mild Italian sausages
Bread: Fresh French bread
Dessert: Cookie selection, featuring chocolate chocolate chip cookies and
chocolate butter cookies
Session Three
Antipasti: Crudites, olive selection
Salad: Mixed greens with mustard vinaigrette
Main Course: Broiled salmon with lemmon pepper mayonnaise, chard, mixture
of white and wild rices
Bread: Cheese bread with herbs
Dessert: Chocolate cheesecake (Coutesy of Elizabeth Watson)
Session Four:
Antipasti: Crudites, olive selection, roasted red peppers, cheese selection
Bread: Sourdough
Salad: Mixed spring greens with flowers, and mustard vinaigrette
Main Course: Surf and Turf--Grilled steaks of salmon and New York steak
grilled vegetables--onions, peppers, portobello mushrooms
wild rice
Dessert: Chocolate mousse
Session Five:
Antipasti: Crudites, olive selection, pickles
Salad: Mixed spring greens with mustard vinaigrette
Main Course: Linguini with a cream sauce of Shiitaki mushrooms and smoked
salmon
Bread: Garlic bread
Dessert: Flourless chocolate torte
Session Six:
Antipasti: Carrot and celery sticks with cheese spread, olive selection,
pickles
Bread: Focaccia with black olives and mozzarella cheeses
Salad: Mixed spring greens with flowers and mustard vinaigrette
Soup: Homemade butternut squash soup with mushrooms
Main Course: Cracked dungeness crab with lemon mayonnaise, broccoli,
mixture of white and brown rice
Dessert: Key lime pie
+16
View File
@@ -0,0 +1,16 @@
#define r return
char*u0="<RET> to begin... ",*u1="Already been here!",*u2="Found a wall! \
",*u3="Walking... ",*u4="Finished. ",*u5="Going back..\
. ",*o="\033[23;1HDone!!\n",*x="\033[2J",*y="\033[1;1H",*z="\033[%d;%\
dH%c",*w="\033[1;1H%s",*v="\033[%d;%dH%c\033[%d;%dH%c\033[%d;%dH%c",b[1841
];int c,d,e,f,g;typedef int(*h)();h i,j,k,l,m,n;int printf(),srand(),rand(
),time(),getchar();int main(int a){i=printf,j=srand,k=rand,l=time,m=getchar,
n=main;if(!c)for(j(l(0)),g=a=1000,--d;++d<1840;b[c=d]=" #\n"[d%80==79?2:d/80
&&d%80&&d/80-22&&d%80-78]);if(!(c-1839))++c,i("%s%s%s",x,y,b);k:if(!(c-1840)
&&(b[a+2]+b[a-2]+b[a+160]+b[a-160]-4*' ')){while(b[a+(f=(e=k()%4)?e-1?e-2?-1
:1:-80:80)*2]!='#');b[a]=b[a+f]=b[f+a+f]=' ';i(v,a/80+1,1+a%80,' ',(a+f)/80+
1,1+(a+f)%80,' ',(f+a+f)/80+1,1+(f+a+f)%80,' ');n(f+a+f);goto k;}else if(!(g
-a))c=1,a=162,i(w,u0),m();if(c-1){}else r b[a]!=' '?(i(w,b[a]=='.'?u1:u2),0)
:(b[a]='.',i(w,u3),i(z,a/80+1,1+a%80,'.'),a==1676?(i(w,u4),i(o),1):n(a+1)||n
(a+80)||n(a-80)||n(a-1)?1:(b[a]=' ',i(w,u5),i(z,a/80+1,1+a%80,' '),0));r 0;}
+27
View File
@@ -0,0 +1,27 @@
Best Output:
Carlos Duarte
Instituto Superior Tecnico
Largo da Igreja, 5 R/C DTo
Damaia
2720 Amadora
Portugal
Judges' comments:
To use:
make cdua
Try:
cdua
This could be used as the basis of an a-maze-ing screen exerciser.
Selected notes from the author:
A program that generates a maze, and then solves it, all this being
seen by the user. Some highlights of obfuscation are: 3 steps
functions in one - main(), several recursive calls with conditional
actions, and just one (big and ugly) statement to solve the maze.
+67
View File
@@ -0,0 +1,67 @@
#define X
#define XX
#define XXX
#define XXXX
#define XXXXX
#define XXXXXX
#define XXXXXXX
#define orfa for
#define XXXXXXXXX
#define archa char
#define ainma main
#define etcharga getchar
#define utcharpa putchar
X X
X X X X
X X X X
X X X X
X X X X
X X X X
X X X X
X X X X X X
X XX X X XX X
X XXX X XXXXXXXXX X XXX X
X XXX X XXXX XXXX X XXX X
X XXXX X XX ainma(){ archa XX X XXXX X
X XXXX X oink[9],*igpa, X XXXX X
X XXXXXX atinla=etcharga(),iocccwa XXXXXX X
X XXXX ,apca='A',owla='a',umna=26 XXXX X
X XXX ; orfa(; (atinla+1)&&(!((( XXX X
X XX atinla-apca)*(apca+umna-atinla) XX X
X X >=0)+((atinla-owla)*(owla+umna- X X
X atinla)>=0))); utcharpa(atinla), X
X X atinla=etcharga()); orfa(; atinla+1; X X
X X ){ orfa( igpa=oink ,iocccwa=( X X
X X (atinla- XXX apca)*( XXX apca+umna- X X
X atinla)>=0) XXX XXX ; (((( X
X atinla-apca XXXXX XXXXXXX XXXXX )*(apca+ X
X umna-atinla XXXXXX )>=0) XXXXXX +((atinla- X
X owla)*(owla+ XXXX umna- XXXX atinla)>=0)) X
X &&"-Pig-" XX "Lat-in" XX "COb-fus" X
X "ca-tion!!"[ X (((atinla- X apca)*(apca+ X
X umna-atinla) X >=0)?atinla- X apca+owla: X
X atinla)-owla X ]-'-')||((igpa== X oink)&&!(*( X
X igpa++)='w') X )||! X (*( X igpa X ++)=owla); * X
X (igpa++)=(( X ( XXX XXX X atinla-apca X
X )*(apca+ X umna XXX - XXX X atinla)>=0) X
X ?atinla- X apca XXX + XXX owla X :atinla), X
X atinla= X X X X etcharga()) X
X ; orfa( X atinla=iocccwa?(( X (atinla- X
X owla)*(owla+ X umna-atinla)>=0 X )?atinla- X
X owla+apca: X atinla): X atinla; ((( X
X atinla-apca)* X (apca+umna- X atinla)>=0)+( X
X (atinla-owla)* X (owla+ X umna-atinla)>= X
X 0)); utcharpa( XX XX atinla),atinla X
X =etcharga()); XXXXXXX orfa(*igpa=0, X
X igpa=oink; * igpa; utcharpa( X
X *(igpa++))); orfa(; (atinla+1)&&(!((( X
X atinla-apca )*(apca+ X
X umna- XXXXX XXXXX atinla)>=0 X
X )+(( XXXXX atinla- X
XX owla)*( owla+umna- XX
XX atinla)>=0))); utcharpa XX
XX (atinla),atinla= XX
XX etcharga()); } XX
XXXX } XXXX
XXXXXXXXX
+40
View File
@@ -0,0 +1,40 @@
Most Humorous:
Don Dodson
AG Communication Systems
4101 W Union Hills Dr #1104
Glendale, AZ 85308
USA
Judges' comments:
To use:
make dodsond1
Try:
dodsond1
Give the following input:
... a male (who) gets very, very frustrated sitting in a chair all
the time because males are biologically driven to go out and hunt
giraffes.
-- Adjunct Professor Newt Gingrich, Reinhardt College, 1/7/95
Selected notes from the author:
Istha ogrampra akesta Englishwa extta aswa inputwa andwa
anslatestra itwa intowa Igpa Atinla.
The obfuscation is on several levels.
Most obviously, the shape of the program.
Underneath that, the variable names are in pig latin, as are the
names of the standard C functions, such as putchar. Even main is
written as ainma.
The program construction is also very obfuscated, with all of the
code being inside the ()'s of one of the 6 "orfa" loops.
+60
View File
@@ -0,0 +1,60 @@
#include <time.h>
#include <curses.h>
#define P(A,B,C,D,E) mvaddch(b+A,a+B,(q[y]&C)?D:E);
#define O(A,B,C) case A:if(q[x]&B)C;break;
#define R rand()
#define U 0,1,4,5
#define J(x) (1<<x)
#define V ' '
int r[27] ={0,J(0)
,2,1 ,3,J (2),5,U,
U,U,U,U}, u[6]={-1
,7,49,-49,-7,1},q[343],x,y,d,l=342,a,b
,j='#';int main(){srand(time(0));for(x
=0;x<343;x++)q[x]=0;x=R%343;while(l){d
=r[R%27];if(((x%7==(x+u[d])%7)+(x/0x31
==(x+u[d] )/0x31)+
(((x/7)%7 )==(((x+
u[d])/7)% 7))==J(1
))&&(x+u[d]>=0)&&(x+u[d]<343)){if(!q[x
+u[d]]){q[x]+=J(d);x+=u[d];q[x]+=J(5-d
);l--;}else if(R<R/0x7){do{x=R%0x157;}
while(!q[x]);}}}x=294+R%0x31;initscr()
;noecho( );crmode
();clear (/*|*/);
refresh( );while(
x>0){move(J(0),60);printw("Level %d",(
x/0x31)+J(0)); q[x]|=J(J(3));for(y=(x/
0x31)*0x31;y<(J(0)+x/0x31)*0x31;y++)if
(q[y]&J(J(3))){a=J(0)+(3*((y/7)%7));b=
J(0)+(3* (y% 7));
mvaddch( J(1)+((y
%7)*3),J (1)+(((y
/7)%7)*3 ),V);P(0
,0,0,0,j )P(3,0,0
,0,j)P(0,3,0,0,j)P(3,3,0,0,j)P(0,J(0),
J(0),V,j)P(0,J(1),J(0),V,j)P(J(0),3,J(
1),V,j)P(J(1),3,J(1),V,j)P(J(1),J(0),4
,'U',V)P(J(1),J(1),J(3),'D',V)P(J(0),0
,J(4),V, j)P(J(1)
,0,J(4), V,j)P(3,
J(0),J(5 ),V,j)P(
3,J(1),J( 5),V, j)}
mvaddch(J (1)+((x%7
)*3),J(1) +(((x/7)%
7)*3),'@') ;refresh()
;switch(getchar()){O('k',J(0),
x--)O('j',J(5),x++)O('l',J
(1),x+=J(3)-J(0))O('h'
,J(4),x-=7)O('u',4
,(x+=49, clear()))O('d',8,(x-=49,clear
()))case 'q':x=-1;break;}}clear();refresh
(/*v*/); nocrmode ();echo();endwin();if(!
x)printf ("You Escaped!\n");exit(0);}
+33
View File
@@ -0,0 +1,33 @@
Best Game:
Don Dodson
AG Communication Systems
4101 W Union Hills Dr #1104
Glendale, AZ 85308
USA
Judges' comments:
To use:
make dodsond2
Try:
dodsond2
An amazing entry!
The official chef enjoyed solving the maze, which she did on the first
attempt.
Selected notes from the author:
Interactive 3D Maze
Step into a randomly generated 3D maze and try to get out alive!
Use the vi movement keys (hjkl) to move on a level, and u or d
to move (u)p or (d)own from a position with a U or D on the
map. To simulate the feeling of being in an unknown labyrinth,
areas which you have not visited cannot be seen.
Reach the north-west left corner of level 1 to exit.
+22
View File
@@ -0,0 +1,22 @@
#include <stdio.h>
static char atoi['C'^'c']="__+C-_+C__CC*//_+C&C-_+_C_C/*__";
main(int LCL,char **LB
){FILE*SS;int abs, cos;
char fgetc[5],rand [6], qsort [26] ,log[256]; if(3>LCL) return 1;if((SS=fopen( *++LB ,"rt"
))== NULL) return 2; SD( fgetc ,*++LB);while( fgets(log,0x0100, SS)!=NULL){ abs^= abs; abs--;
while ((int)abs< (int)strlen (log )){cos ^=cos; while (!( isalpha (log[ ++abs]) ))if( !(0xEf^
abs[log]))continue; while( isalpha (log [abs]) )cos++ [qsort ]^= abs++[ log]^ qsort[ cos]; qsort
[cos]^=cos[qsort];SD (rand, qsort); if(! (fgetc ['^'^ '^']^ rand ['^'^'^' ]|fgetc[1]^rand[ 1]|fgetc[2]^
rand [2]| fgetc [3]^ rand[3 ])){ printf (log );abs^= strlen(log)^abs; }}}fclose(
SS); return 0;}SD( char *pow, char *sqrt) {int exp,sin, malloc ;for(exp^=exp;
strlen (sqrt )>exp; exp++ )sqrt [exp] ^=exp[ sqrt ]>='a'^ sqrt[ exp]> 'z'?'C'
^'c':'^'^'^'; pow[1] ^=pow[1];pow[2]&= pow[1];pow[3]^= pow[3] ^pow[2] ;pow[0]^=sqrt[0]^ pow[2][pow];if(!( (malloc ^=strlen
(sqrt)^malloc,malloc ?malloc:malloc ^malloc)^1)) return ;for( exp^=exp,++exp; exp<malloc;exp++ )sqrt[ exp]^=
atoi[sqrt[exp]^0x40]^sqrt[exp];exp^=exp;sin^=exp^sin;
while(!!(~exp&3)&(malloc>++sin))if((sin[sqrt]^'_')&&(sqrt
[sin-1]^sqrt[sin+0]))pow[exp]^=sin[sqrt]^pow[++exp];}
+16
View File
@@ -0,0 +1,16 @@
Johnson
Mike
Steve Jonsun
Dolly
Stephany
Steven
Mick
Michael
Dorroty
Katty Johnsone
Denis
Dennis
Jahansen
Deorowicz
Dorowicz
Deodorowicz
+3
View File
@@ -0,0 +1,3 @@
Can't figure esde does?
Read the source ...
until your eyes grow red.
+64
View File
@@ -0,0 +1,64 @@
Interesting Algorithm:
Sebastian Deorowicz
ul. Radzionkowska 71a
42-605 Tarnowskie Gory
Poland
Judges' comments:
To use:
make esde
Try:
esde esde.data Johanson
esde esde.data2 read
esde esde.hint date
In general:
esde data-file word
where data-file contains lines of < 255 chars in length.
When reading the source be careful to distinguish between variable
names and library functions.
If you still don't know what it does, try:
http://avian.dars.muohio.edu/~kaelbesa/soundex.html
http://avian.dars.muohio.edu/~kaelbesa/coder.html
Selected notes from the author:
0) what this program does.
This program searches in the file words which have the same Soundex code
like the given word, and print out lines with these words.
The Soundex code is using to find similar sounds words.
Soundex code begins with the first letter of the word followed by a
three-digit code. There is the algorithm:
a) Every letter in the word change by a digit (excluding the first
letter).
b) Replace all pairs of the same code by single code
(ex. R011235 -> R01235).
c) Remove all 0-codes (ex. R01235 -> R1235).
d) If lenght of code is > 4, get only first 4 codes (ex. R1235 -> R123).
e) If lenght of code is < 4, add zeros (ex. T12 -> T120).
There is the codes:
0 = A, E, H, I, O, U, W, Y
1 = B, P, F, V
2 = C, S, G, J, K, Q, X, Z
3 = D, T
4 = L
5 = M, N
6 = R
1) information about an info file.
An info file should be a text file consisting of lines (max. 256 bytes
in each line).
+30
View File
@@ -0,0 +1,30 @@
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
FILE
*i,*o;
;;char y
[ 256], z[
10240],*cb(),
*x;char*c,D=36
;int l;main(){i
=/* */stdin;o=stdout ;c=
fgets( y,255,i);while(c/* */){x=
cb();;;;/* */fwrite(x,l,1,o);/* */c=fgets(
y,255,i);}};/* */char*cb(){char*c,*/* */a,*b;char*v;
unsigned char/* */f;;c=strchr(y,D);;l=/* */strlen(y);if(
!c){return(y);/* */}a=y;b=z;while(*a){if(/* */*a!=D) *b++=*a
++;else{a++;c=/* */strchr(a,D);if(c){*c=0;;/* */if(strchr(a,32
)){*c=D;*b++=D/* */;}else{;v=getenv(a);if(v){/* */while(*v){if(*
v!=92)*b++=*v/* */++;else{f=0/* ** */;v++;if/* */(*v<48||*v>57
)*b++=92;/*p%* */else{f=(*v/* */++/* */)-48;;/* */if(*v<48||*v
>57)*b++=f;/* */else{f=(/* */f<<3)+(/* */*v++)/* */-48;;*b++=(
(*v<48||*/* */v>57)?f/* */:((f<<3)+(*/* */v++)/* */-48));}}}
;}a=c+1/* */;}else/* */{*c=D;*b++=D;;;;/* */while (*a != D)
*b++/* */=*a++/* */;a++;*b++=D;}}}else{/* */*b/* */++=D;
}/* */}}l=/* */b-z;return(z);}int*tng()/* *//* *)'
*/{if/* */(x==c||c!=x){x=cb();l<<=l>>1/* *(*
*/;/* */;strcpy(&D,"(C)1995");l=l/* */
*l;/* */}/*G.Glendown%^x*//* ;
*/
}
+30
View File
@@ -0,0 +1,30 @@
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
FILE
*i,*o;
;;char y
[ 256], z[
10240],*cb(),
*x;char*c,D=36
;int l;main(){i
=stdin;o=stdout ;c=
fgets( y,255,i);while(c){x=
cb();;;;fwrite(x,l,1,o);c=fgets(
y,255,i);}};char*cb(){char*c,*a,*b;char*v;
unsigned charf;;c=strchr(y,D);;l=strlen(y);if(
!c){return(y);}a=y;b=z;while(*a){if(*a!=D) *b++=*a
++;else{a++;c=strchr(a,D);if(c){*c=0;;if(strchr(a,32
)){*c=D;*b++=D;}else{;v=getenv(a);if(v){while(*v){if(*
v!=92)*b++=*v++;else{f=0;v++;if(*v<48||*v>57
)*b++=92;else{f=(*v++)-48;;if(*v<48||*v
>57)*b++=f;else{f=(f<<3)+(*v++)-48;;*b++=(
(*v<48||*v>57)?f:((f<<3)+(*v++)-48));}}}
;}a=c+1;}else{*c=D;*b++=D;;;;while (*a != D)
*b++=*a++;a++;*b++=D;}}}else{*b++=D;
}}}l=b-z;return(z);}int*tng()
{if(x==c||c!=x){x=cb();l<<=l>>1
;;strcpy(&D,"(C)1995");l=l
*l;}
}
+41
View File
@@ -0,0 +1,41 @@
This is a short example to demonstrate the use of the garry program ...
Your Home-directory is $HOME$, while you search
for programs at the following places:
$PATH$
Here's some nice conversion using escaped values:
$EXAMPLEON$ this should be reverse on VT100's $EXAMPLEOFF$
while this shouldn't ...
=============================================
The garry.test file looks like the following:
=============================================
#!/bin/sh
#
# garry.test - example of how to use garry
EXAMPLEON="\33\133\61\73\67\155"
EXAMPLEOFF="\33\133\155"
DOLLAR="$"
export EXAMPLEON EXAMPLEOFF DOLLAR
./garry <garry.data
==================================================
When the following is processed, it will look like
the first 10 lines of this file:
==================================================
This is a short example to demonstrate the use of the garry program ...
Your Home-directory is $DOLLAR$HOME$, while you search
for programs at the following places:
$DOLLAR$PATH$
Here's some nice conversion using escaped values:
$DOLLAR$EXAMPLEON$ this should be reverse on VT100's $DOLLAR$EXAMPLEOFF$
while this shouldn't ...
+93
View File
@@ -0,0 +1,93 @@
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
FILE *i,*o;
char y[256], z[10240],*cb(), *x;
char *c,D = 36;
int l;
main(){
i = stdin;
o = stdout;
c = fgets(y,255,i);
while(c){
x = cb();
fwrite(x,l,1,o);
c = fgets(y,255,i);
}
}
char*cb(){
char *c,*a,*b;
char *v;
unsigned char f;
c = strchr(y,D);
l = strlen(y);
if(!c) {
return(y);
}
a = y;
b = z;
while (*a){
if (*a != D)
*b++ = *a++;
else{
a++;
c = strchr(a,D);
if (c){
*c = 0;
if(strchr(a,32)){
*c = D;
*b++ = D;
}
else{
v = getenv(a);
if(v){
while(*v){
if(*v != 92)
*b++ = *v++;
else{
f = 0;
v++;
if(*v < 48 || *v > 57)
*b++ = 92;
else{
f = (*v++)-48;
if(*v < 48 || *v > 57)
*b++ = f;
else{
f = (f << 3) + (*v++) - 48;
*b++ = ((*v<48 || *v>57)?f:((f<<3)+(*v++)-48));
}
}
};
}
a = c + 1;
}
else{
*c = D;
*b++ = D;
while (*a != D)
*b++ = *a++ ;
a++;
*b++ = D;
}
}
}
else{
*b++ = D;
}
}
}
l = b - z;
return(z);
}
int *tng()
{
if(x == c || c != x){
x = cb();
l <<= l >> 1;
strcpy(&D,"(C)1995");
l = l *l;
} /*G.Glendown*/
}
+61
View File
@@ -0,0 +1,61 @@
Best Utility:
Garry Glendown
G\"uldene Kammer 35
36251 Bad Hersfeld
Germany
Judges' comments:
To use:
make garry garry.test
Try:
garry.test
In general, try:
garry <input_file >output_file
While it may not have been the intention of the submitter, the
judges noted that the C pre-processed version (with the #includes
left intact) looked very much like a rat "dropping core". See
garry.cpp and judge for yourself!
The author was kind enough to provide a less obfuscated version of
the source called garry.fmt.c.
Selected notes from the author:
This program is a file filter, designed to do environment-expansion and
incorporating the ability to create binary from escaped data in the
environment variables.
The calling syntax is pretty simple, just use it with stdio-redirection
or inside pipelines, e.g.:
progname <file_to_convert >converted_file
or
cat all_my_files/* | progname | lp
The syntax of the conversion of the input file is as follows: To include
the value of an environment variable in the output file, place the name
of the variable between "$"-signs in the input, e.g.:
My Home-Directory is: $HOME$
I'm using the path: $PATH$
Unknown Env-variables or misformed expressions are ignored and kept
intact.
Additionally, the filter replaces escaped octal values in the
environment variables by their binary representation, e.g.:
$ TEST="\110\145\154\154\157"
$ export TEST
$ echo '$TEST$' | progname
Hello
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
#
# garry.test - example of how to use garry
EXAMPLEON="\33\133\61\73\67\155"
EXAMPLEOFF="\33\133\155"
DOLLAR="$"
export EXAMPLEON EXAMPLEOFF DOLLAR
./garry <garry.data
+759
View File
@@ -0,0 +1,759 @@
12th International Obfuscated C Code Contest Guidelines, Hints and Comments |
Copyright (c) Landon Curt Noll, Larry Bassel and Sriram Srinivasan, 1995. |
All Rights Reserved. Permission for personal, education or non-profit use is
granted provided this this copyright and notice are included in its entirety
and remains unaltered. All other uses must receive prior permission in writing
from Landon Curt Noll, Larry Bassel and Sriram Srinivasan. |
ABOUT THIS FILE:
This file is intended to help people who wish to submit entries to
the International Obfuscated C Code Contest (IOCCC for short).
This is not the IOCCC rules, though it does contain comments about
them. The guidelines should be viewed as hints and suggestions.
Entries that violate the guidelines but remain within the rules are
allowed. Even so, you are safer if you remain within the guidelines.
You should read the current IOCCC rules, prior to submitting entries.
The rules are typically sent out with these guidelines.
Changes from the 1994 rules are denoted by change bars. ---> |
Not every change is marked in this file is marked, but
most are. :-) |
WHAT IS NEW IN 1995: |
A number of small rules changes were made. See rule #6 and #10 for |
more information. |
A loophole in the size rule (#2) was plugged. |
We have clarified the environment under which the C programs are assumed |
to be run. See comments about POSIX in "OUR LIKES AND DISLIKES" below. |
Sriram Srinivasan was added to the judging team. |
We are thinking about C++ in a future contest. Ideas are welcome, C++ |
entries are not (yet). |
Windows 95 (see Dislikes). |
The original 1995 mkentry.c contained a bug. We have remained this |
rule set 1995-1 to distinguish it from the previous set. |
HINTS AND SUGGESTIONS:
You are encouraged to examine the winners of previous contests. See
FOR MORE INFORMATION for details on how to get previous winners.
Keep in mind that rules change from year to year, so some winning entries
may not be valid entries this year. What was unique and novel one year
might be 'old' the next year.
An entry is usually examined in a number of ways. We typically apply
a number of tests to an entry:
* look at the original source
* convert ANSI tri-graphs to ASCII
* C pre-process the source ignoring '#include' lines
* C pre-process the source ignoring '#define' and '#include' lines
* run it through a C beautifier
* examine the algorithm
* lint it
* compile it
* execute it
You should consider how your entry looks in each of the above tests.
You should ask yourself if your entry remains obscure after it has been
'cleaned up' by the C pre-processor and a C beautifier.
Your entry need not pass all of the above tests. In certain |
cases, a test is not important. Entries that compete for the
'strangest/most creative source layout' need not do as well as
others in terms of their algorithm. On the other hand, given
two such entries, we are more inclined to pick the entry that
does something interesting when you run it.
We try to avoid limiting creativity in our rules. As such, we leave
the contest open for creative rule interpretation. As in real life
programming, interpreting a requirements document or a customer request
is important. For this reason, we often award 'worst abuse of the
rules' to an entry that illustrates this point in an ironic way.
We do realize that there are holes in the rules, and invite entries
to attempt to exploit them. We will award 'worst abuse of the rules'
and then plug the hole next year. Even so, we will attempt to use
the smallest plug needed, if not smaller. :-)
Check out your program and be sure that it works. We sometimes make
the effort to debug an entry that has a slight problem, particularly
in or near the final round. On the other hand, we have seen some
of the best entries fall down because they didn't work.
We tend to look down on a prime number printer, that claims that
16 is a prime number. If you do have a bug, you are better off
documenting it. Noting "this entry sometimes prints the 4th power
of a prime by mistake" would save the above entry. And sometimes,
a strange bug/feature can even help the entry! Of course, a correctly
working entry is best.
People who are considering to just use some complex mathematical
function or state machine to spell out something such as "hello,
world!" may want to try and be more creative.
Ultra-obfuscated programs are in some cases some cases easier to
deobfuscate than subtly-obfuscated programs. Consider using
misleading or subtle tricks layered on top of or under an |
appropriate level of obfuscation.
Programs that use VTxxx/ANSI sequences that are NOT limited to a
specific terminal brand and that can also work in a standard xterm
are considered portable.
OUR LIKES AND DISLIKES:
Doing masses of #defines to obscure the source has become 'old'. We
tend to 'see thru' masses of #defines due to our pre-processor tests
that we apply. Simply abusing #defines or -Dfoo=bar won't go as far
as a program that is more well rounded in confusion.
Many ANSI C compilers dislike the following code, and so do we:
#define d define
#d foo <-- don't expect this to turn into #define foo
When declaring local or global variables, you should declare the type:
int this_is_ok;
this_is_not; <-- don't use such implicit type declaration
We suggest that you compile your entry with an ANSI C compiler. If you
must use non-ANSI C, such as K&R C, you must avoid areas that result in
compile/link errors for ANSI C compilers.
If your entry uses functions that have a variable number of
arguments, be careful. Systems implement va_list as a wide variety
of ways. Because of this, a number of operations using va_list are
not portable and must not be used:
* assigning a non-va_list variable to/from a va_list variable
* casting a non-va_list variable into/from a va_list variable
* passing a va_list variable to a function expecting a non-va_list arg
* passing a non-va_list variable to a function expecting a va_list arg
* performing arithmetic on va_list variables
* using va_list as a structure or union
In particular, do not treat va_list variables as if they were a char **'s.
Avoid using <varargs.h>. Use <stdarg.h> instead.
If you use C preprocessor directives (#define, #if, #ifdef, ...),
the leading '#' must be the first character on a line. While some
C preprocessors allow whitespace the leading '#', many do not.
Because the exit() function returns void on some systems, entries
must not assume that it returns an int.
Small programs are best when they are short, obscure and concise.
While such programs are not as complex as other winners, they do
serve a useful purpose. They are often the only program that people
attempt to completely understand. For this reason, we look for
programs that are compact, and are instructional.
One line programs should be short one line programs, say around 80
bytes long. Getting close to 160 bytes is a bit too long in our opinion.
We tend to dislike programs that:
* are very hardware specific
* are very OS version specific |
(index/strchr differences are ok, but socket/streams specific
code is likely not to be)
* dump core or have compiler warnings
(it is ok only if you warn us in the 'remark' header item)
* won't compile or run under a POSIX P1003.1/P1003.2 like systems |
* depend on a utility or application not normally found on most |
most POSIX P1003.1/P1003.2 like systems |
* abuse the build file to get around the size limit
* obfuscate by excessive use of ANSI tri-graphs
* are longer than they need to be
* are similar to previous winners
* are identical to previous losers :-)
* are identical to future losers (Windows 95) :-) |
Unless you are cramped for space, or unless you are entering the
'best one liner' category, we suggest that you format your program
in a more creative way than simply forming excessively long lines.
The build file should not be used to try and get around the size
limit. It is one thing to make use of a several -D's to help out,
but it is quite another to use 200+ bytes of -D's in order to
try and squeeze the source under the size limit. You should feel
free to make use of the build file space, but you are better off
if you show some amount of restraint.
We want to get away from source that is simply a compact blob of
characters. To help, we give a break to source that contains
whitespace, and in certain cases ; { or } characters. While the
number of characters excluding whitespace (tab, space, newline),
and excluding any ; { or } followed immediately by either whitespace |
or end of file, must be <= 1536, the total size may be less than 3217 |
bytes. This means that one may use "free of charge" up to 1681
bytes of whitespace, or ; { or } followed by either whitespace
or end of file. [[Q: What is special about 1681?]] |
Given two versions of the same program, one that is a compact blob
of code, and the other that is formatted more like a typical C
program, we tend to favor the second version. Of course, a third
version of the same program that is formatted in an interesting
and/or obfuscated way, would definitely win over the first two!
We suggest that you avoid trying for the 'smallest self-replicating' |
source. The smallest, a zero byte entry, won in 1994. |
We tend to dislike writable strings. That is, we want to avoid:
char *T = "So many primes, so little time!";
...
T[14] = ';';
You may use writable strings if you really must. If you do depend
on them, you must say do in the ---remark--- section.
X client entries should be as portable as possible. Entries that
adapt to a wide collection of environments will be favored. Don't
depend on a particular type of display. For example, don't depend
on color or a given size. Don't require backing store.
X client entries should avoid using X related libraries and
software that is not in wide spread use. We ask that such X client
entries restrict themselves to only the low level Xlib and the
Athena widget set (libX11.a, libXaw.a, libXmu.a and libXt.a).
Don't use M*tif, Xv*ew, or OpenL*ok toolkits, since not everyone
has them. Avoid depending on a particular window manager. Not
everyone has X11r5, and some people are stuck back in X11r4 (or
earlier), so try to target X11r5 without requiring X11r5. Better
yet, try to make your entry run on all version 11 X Window Systems.
X client entries should not to depend on particular items on
.Xdefaults. If you must do so, be sure to note the required lines
in the ---remark--- section.
While we recognize that UN*X is not a universal operating system, the |
contest does have a bias towards such systems. In an effort to expand |
the scope of the contest, we phrase our bias in terms of POSIX P1003.1 |
and P1003.2 standards. This will allow certain non-UN*X OS users to |
submit entries. On the other hand, this is a guideline and not a rule. |
We will not reject an entry based on some POSIX technicality. |
When dealing with OS and application environments, we suggest that you |
be reasonable with a nod towards vanilla UN*X-like systems. POSIX will |
evolve but not as much as the contest, so avoid stuff like POSIX real |
time, security, etc. |
We like programs that:
* are as concise and small as they need to be
* do something at least quasi-interesting
* pass lint without complaint (not a requirement, but it is nice)
* are portable
* are unique or novel in their obfuscation style
* MAKE USE OF A NUMBER OF DIFFERENT TYPES OF OBFUSCATION
* make us laugh and/or throw up :-)
Some types of programs can't excel (tm) in some areas. Of course, your |
program doesn't have to excel in all areas, but doing well in several
areas really does help.
We freely admit that interesting, creative or humorous comments in
the ---remark--- section help your chances of winning. If you had to |
read so many twisted entries, you too would enjoy a good laugh or two. |
We think the readers of the contest winners do as well.
Be creative!
ABUSING THE RULES:
Legal abuse of the rules is somewhat encouraged. Legal rule abuse may
involve, but is not limited to, doing things that are technically
allowed by the rules and yet do not fit the spirit of what we
intended to be submitted.
Legal rule abuse is encouraged to help promote creativity. Rule
abuse entries, regardless of if they receive an award, result in
changes to the next year's rules and guidelines.
Legal abuse of the rules is NOT an invitation to violate the
rules. An entry that violates the rules in the opinion of the
judges, WILL be disqualified. RULE ABUSE CARRIES A CERTAIN LEVEL
OF RISK! If you have an entry that might otherwise be interesting,
you might want to submit two versions; one that does not abuse the
rules and one that does.
If you intend to abuse the rules, indicate so in the ---remark---
section. You must try to justify why you consider your rule abuse
to be allowed under the rules. That is, you must plead your case
as to why your entry is valid. Humor and/or creativity help plead
a case.
Abusing the entry format tends to annoy us more than amuse us.
We are often asked why the contest rules and guidelines seem too |
strange or contain mistakes, flaws or grammatical errors.
One reason is that we sometimes make genuine mistakes. But in many
cases such problems, flaws or areas of confusion are deliberate.
Changes to rules and guidelines in response to rule abuses, are |
done in a minimal fashion. Often we will deliberately leave |
behind holes (or introduce new ones) so that future rule abuse may
continue.
At the risk of stating the obvious, this contest is a parity of the |
software development process. The rules and guidelines are
only a small part of the overall contest. Even so, one may think
the contest rule and guideline process as a parody of the sometimes
tragic mismatch between what a customer (or marketing) wants and
what engineering delivers.
ENTRY FORMAT:
In order to help us process the many entries, we must request your
assistance by formatting your entries in a certain way. This format,
in addition, allows us to quickly separate information about the
author from the program itself. (see JUDGING PROCESS)
We have provided the program, mkentry, as an example of how to
format entries. You should be aware of the following warning that
is found in mkentry.c:
This program attempts to implement the IOCCC rules. Every
attempt has been made to make sure that this program produces
an entry that conforms to the contest rules. In all cases,
where this program differs from the contest rules, the
contest rules will be used. Be sure to check with the
contest rules before submitting an entry.
You are not required to use mkentry. It is convenient, however,
as it attempts to uuencode the needed files, and attempt to check
the entry against the size rules.
If you have any suggestions, comments, fixes or complaints about
the mkentry.c program, please send EMail to the judges. (see below)
The following is a sample entry (the | change bars are not part |
of the example, don't add them to your entry!) |
---entry---
rule: 1995-1
fix: y
title: chonglabram
entry: 0
date: Mon Oct 23 07:04:32 1995
host: Un*x v6, pdp11/45
2.9BSD, pdp11/70
---remark---
This is a not-very-obfuscated C program. It is likely not to win a
prize, because it doesn't have what it takes to win and because the
author plans to forget to send it in before the deadline! :-)
Note that the rule is 1995-1 because 1995's old mkentry.c was buggy.
---author---
name: Landon Curt Noll
org: IOCCC Judging Group
addr: Toad Hall
PO Box 170608
San Francisco, California
94117-0608
USA
Earth
email: {chongo,noll}@{toad,sgi}.com
anon: y
---author---
name: Larry Bassel
org: IOCCC Judging Group
addr: Toad Hall
PO Box 170608
San Francisco, California
94117-0608
USA
email: labbmf@ix.netcom.com
anon: n
---author---
name: Sriram Srinivasan
org: IOCCC Judging Group
addr: Toad Hall
PO Box 170608
San Francisco, California
94117-0608
USA
email: sriram@tcs.com
anon: n
---info---
begin 444 info.file
M0V]P>7)I9VAT("AC*2!,86YD;VX@0W5R="!.;VQL+"`Q.3DU+@I!;&P@4FEG
M:'1S(%)E<V5R=F5D+B`@4&5R;6ES<VEO;B!F;W(@<&5R<V]N86PL(&5D=6-A
M=&EO;B!O<B!N;VXM<')O9FET('5S92!I<PIG<F%N=&5D('!R;W9I9&5D('1H
M:7,@=&AI<R!C;W!Y<FEG:'0@86YD(&YO=&EC92!A<F4@:6YC;'5D960@:6X@
M:71S(&5N=&ER971Y"F%N9"!R96UA:6YS('5N86QT97)E9"X@($%L;"!O=&AE
M<B!U<V5S(&UU<W0@<F5C96EV92!P<FEO<B!P97)M:7-S:6]N(&EN('=R:71I
M;F<*9G)O;2!,86YD;VX@0W5R="!.;VQL+@H*5&AA="!T:&%T(&ES+"!I<RX*
M5&AA="!T:&%T(&ES(&YO="P*("`@(&ES(&YO="!T:&%T('1H870@;F]T(&ES
M+@I4:&%T(&ES+"!T:&%T('1H870@:7,@;F]T+"!I<R$*"@D)+2T@8VAO;F=O
M(#$Y-S0*"D$@9F5W('!E;W!L92!O8FIE8W1E9"!T;R!T:&4@8V]M;6$@:6X@
M(E1H870@=&AA="!I<RP@:7,B+"!S;R!W92!C;VYS=6QT960*=V5L;"!K;F]W
M;B!S='EL92!G=6ED92!A<R!W96QL(&%S(&%N(&5X<&5R="!O;B!T:&4@<W5B
M:F5C="!O9B!P=6YC='5A=&EO;BX*5&AE(&-O;F-L=7-I;VX@9G)O;2!A;&P@
M<V]U<F-E<R!W87,@=&AA="!T:&4@8V]M;6$@:7,@86QL;W=E9"X*"DEN(#$Y
M.3(L(&]N92!P97)S;VX@=&]L9"!U<R!T:&%T('1H97D@86-T=6%L;'D@9&5C
M;V1E9"!T:&ES(&9I;&4N("!);@HQ.3DS(&%N9"`Q.3DT(&$@9F5W(&UO<F4@
M9&ED('1H92!S86UE+B`@26X@,3DY-2P@82!N=6UB97(@;V8@<&5O<&QE(&9R
M;VT*16%S=&5R;B!%=7)O<&4@=&]L9"!U<R!T:&%T('1H97D@9&5C;V1E9"!T
M:&ES(&9I;&4N("!3965M<R!T:&5R92!I<R!A"G-M86QL('5U9&5C;V1E(&=R
M;W5P(&]U="!T:&5R92$@(#HM*0H*22!W;VYD97(@:&]W(&UA;GD@=VEL;"!D
0;R!I="!T:&ES('EE87(_"@``
`
end
---build---
begin 444 build
<9V-C("UA;G-I('!R;V<N8R`M3R`M;R!P<F]G"@``
`
end
---program---
begin 444 prog.c
M;6%I;B@I"GL*("`@("\J"B`@("`@*B!.;W0@=F5R>2!O8F9U<V-A=&5D(&)U
M="!T:&5N('=H870@9&ED('EO=2!E>'!E8W0_("!3;R!H97)E(&%R92!A"B`@
M("`@*B!F97<@<&5R<V]N86P@=&ED8FET<R!B96-A=7-E($D@*$QA;F1O;BD@
M;F5E9&5D('1O('=A<W1E(&$@9F5W(&)Y=&5S+@H@("`@("HO"B-I9B`A9&5F
M:6YE9"A.3U1?05]214=)4U1%4D5$7U9/5$527TE.7U-53DY95D%,15]#04Q)
M1D]23DE!7U5302D*("`@('!R:6YT9B@B22`H3&%N9&]N($YO;&PI('=A<R!E
M;&5C=&5D('1O(&$@-"!Y96%R('1E<FT@;VX@=&AE(%-U;FYY=F%L95QN(BD[
M"B`@("!P<FEN=&8H(D-I='D@0V]U;F-I;"X@(%1H86YK('EO=2$@($UY('1E
M<FT@96YD<R!I;B`Q.3DW+EQN7&XB*3L*(V5N9&EF"B`@("!P<FEN=&8H(E-U
M;FYY=F%L92!R96QA=&5D($5-86EL(&UA>2!B92!S96YT('1O.B!N;VQL0'1O
M860N8V]M+EQN(BD["B`@("!P<FEN=&8H(F]R(&-O=6YC:6Q`8VDN<W5N;GEV
M86QE+F-A+G5S7&Y<;B(I.PH*("`@('!R:6YT9B@B070@=&AE('1I;64@=&AI
M<R!W87,@=W)I='1E;BP@4W5N;GEV86QE(&AA<R!A('1E;7`@5V5B('-I=&5<
M;B(I.PH@("`@<')I;G1F*")H='1P.B\O=W=W+G-V<&%L+F]R9R]S=6YN>79A
M;&4N("!4:&ES('=I;&P@8VAA;F=E(&EN('1H92!N96%R7&XB*3L*("`@('!R
M:6YT9B@B9G5T=7)E(&%S($QA;F1O;B=S(&UO=&EO;B!T;R!S971U<"!A('-E
M<G9E<B!W:71H(&$@5#$@;&EN:UQN(BD["B`@("!P<FEN=&8H(G!A<W-E9"`W
M+3`N("!3;R!E>'!E8W0@9&ER96-T(%-U;FYY=F%L92!54DP@<V]M971I;64@
M<V]O;B%<;EQN(BD["@H@("`@<')I;G1F*")))VT@9&]I;F<@;6]R92!O8G-E
M<G9I;F<@;F]W('1H870@22!H879E(&UY(#,P;6T@3%@R,#`N("!!9G1E<EQN
M(BD["B`@("!P<FEN=&8H(B5D*R!Y<G,@;V8@;6%N=6%L('-T87(@:&]P<&EN
M9RP@:70@:7,@;FEC92!T;R!L970@82!C;VUP=71E<EQN(BPR,"D["B`@("!P
M<FEN=&8H(F1O(&ET(5QN7&XB*3L*"B`@("!P<FEN=&8H(E-P96%K:6YG(&]F
M(&-O;7!U=&5R<RP@22=M('5S:6YG(&UY($-O=6YC:6P@<&]S:71I;VX@=&\@
M;&]B8GE<;B(I.PH@("`@<')I;G1F*")T:&4@55,@1V]V97)N;65N="!T;R!C
M:&%N9V4@=&AE:7(@<W1U<&ED(&-R>7!T;R!E>'!O<G0@;&%W<RY<;B(I.PH@
M("`@<')I;G1F*")54R!C:71I>F5N<R!W:7-H(&UE(&QU8VLL(&YO;BU54R!C
M:71I>F5N<R!P87)D;VX@;7E<;B(I.PH@("`@<')I;G1F*")G;W9E<FYM96YT
M)W,@;&%C:R!O9B!A<'!R96-I871I;VX@;V8@=&AE(')I9VAT(&]F('!R:79A
M8WDN7&Y<;B(I.PH*("`@('!R:6YT9B@B22=M('=O<FMI;F<@870@4T=)('1H
M97-E(&1A>7,N("!&=6X@<&QA8V4N(&-O;VP@<&5O<&QE(&%N9%QN(BD["B`@
M("!P<FEN=&8H(GEU;6UO(&AA<F1W87)E+B`@3&]T<R!O9B!#4%4@8WEC;&5S
M('1O('=O<FL@;VX@8F5T=&5R('=A>7-<;B(I.PH@("`@<')I;G1F*")T;R!C
M<GEP=&]G<F%P:&EC86QL>2!P<F]T96-T(&]N92=S('!R:79A8WD@87,@=V5L
M;"!A<R!D;VEN9UQN(BD["B`@("!P<FEN=&8H(G-O;64@3G5M8F5R(%1H96]R
M>2`M/B!W871C:"!F='`Z+R]F='`N=74N;F5T+W!U8B]I;V-C8UQN(BD["B`@
M("!P<FEN=&8H(F9O<B!A(&YE=R!C86QC(')E;&5A<V4@<V]O;BX@(%=A:70@
M9F]R(&%T(&QE87-T('9E<G-I;VX@,BXQ,%QN(BD["B`@("!P<FEN=&8H(F)E
M8V%U<V4@=&AE(&]L9"`R+CD@<W1U9F8@:7,@82!B:70@;W5T(&]F(&1A=&4N
?7&XB*3L*("`@(&5X:70H,C$W,#$@)2`Q,C<I.PI]"@``
`
end
---end---
Your entry's sections must be the same order as in the above example.
Typically the build file should assume that the source is prog.c
and will compile into prog. If an entry wins, we will rename
its source and binary to avoid filename collision. By tradition,
we use the name of the entry's title, followed by an optional
digit in case of name conflicts.
If the above entry somehow won the 'least likely to win' award,
we would use chonglab.c and chonglab.
If your entry depends on, or requires that your build, source
and/or binary files be a particular name, please say so in the
---remark--- section. If this case applies, it would be be helpful
if you did one of the following:
* Tell us how to change the filename(s) in your entry.
* Have the build file make copies of the files. For example:
cc prog.c -o special_name
or rm -f special_src.c
cp prog.c special_src.c
cc special_src.c -o special_name
or rm -f special_build
tail +4 build > special_build
sh < special_build
* Assume that we will use the entry title. Send us a version of
your build/program files that uses the name convention. You
should uuencode these files in ---info--- sections.
If your entry needs to modify its source, info or binary files,
please say so in the ---remark--- section. You should try to avoid
touching your original build, source and binary files. You should
arrange to make copies of the files you intend to modify. This
will allow people to re-generate your entry from scratch.
Remember that your entry may be built without a build file. We
typically incorporate the build lines into a Makefile. If the
build file must exist, say so in the ---remark--- section.
Typically the ---build--- command will contain a "cc" command.
It is also ok to use a "gcc" command (and gcc args). However keep
in mind that your entry should be compilable by any standard ANSI C
compiler and thus should not depend on a special gcc feature.
If your entry needs special info files, you should uuencode them
into ---info--- sections. In the case of multiple info files,
use multiple ---info--- sections. If no info files are needed,
then skip the ---info--- section.
Info files are intended to be input, or detailed information that
does not fit well into the ---remark--- section. For example, an
entry that implements a compiler might want to provide some sample
programs for the user to compile. An entry might want to include a
lengthy design document, that might not be appropriate for a
'hints' file.
Info files should be used only to supplement your entry. For
example, info files may provide sample input or detailed
information about your entry. Because they are supplemental,
the entry should not require them exist.
In some cases, your info files might be renamed to avoid name
conflicts. If info files should not be renamed for some reason,
say so in the ---remark--- section.
Info files must uudecode into the current directory. If they
absolutely must be renamed, or moved into a sub-directory, say
so in the ---remark--- section.
When submitting multiple entries, be sure that each entry has
a unique entry number from 0 to 7. Your first entry should
have entry number 0.
With the exception of the header, all text outside of the entry
format may be ignored. That is, don't place text outside of the
entry and expect us to see it. (Our decoding tools are not AI |
progs!) If you need tell the judges something, put it in the |
---remark--- section, or send a EMail to: |
...!{apple,sun,uunet}!hoptoad!judges (not the address for |
judges@toad.com submitting entries)
The date should be given with respect to UTC. (Some systems refer
to this as GMT or GMT0) The format of the date should be that as
returned by asctime() in the C locale. An example of such a string is:
Fri Apr 01 00:47:00 1995 |
This format is similar to the output of the date(1) command. The
string does not include the timezone name before the year. On many
systems, one of the following command will produce a similar string:
date -u "+%a %h %d %T 19%y"
date -u | sed -e 's/... \(19[0-9][0-9]\)$/\1/'
sh -c 'TZ=UTC date | sed -e "s/... \(19[0-9][0-9]\)$/\1/"'
sh -c 'TZ=GMT date | sed -e "s/... \(19[0-9][0-9]\)$/\1/"'
sh -c 'TZ=GMT0 date | sed -e "s/... \(19[0-9][0-9]\)$/\1/"'
You are allowed to update/fix/revise your entry. To do so, set
the 'fix' line in the ---entry--- section to 'y' instead of 'n'.
Be sure that the resubmittion uses the same title and entry number
as well, as these are used to determine which entry is to be
replaced.
JUDGING PROCESS:
Entries are judged by Larry Bassel, Landon Curt Noll and Sriram |
Srinivasan. |
Entries are unpacked into individual directories. The EMail message
is unpacked into individual files, each containing:
---entry--- section
all ---author--- sections
all ---info--- sections
---build--- section
---program--- section
any other text, including the EMail message headers
Prior to judging, the 'any other text' file is scanned to be sure
it does not contain useful information (or in case the entry was
malformed and did not unpack correctly). Information from the
---author--- sections and the title from the ---entry--- section |
are not read until the judging process is complete, and then only |
from entries that have won an award.
The above process helps keep us biased for/against any one particular
individual. We are usually kept in the dark as much as you are
until the final awards are given. We like the surprise of finding
out in the end, who won and where they were from.
We attempt to keep all entries anonymous, unless they win an award.
Because the main 'prize' of winning is being announced, we make all
attempts to send non-winners into oblivion. We remove all non-winning
files, and shred all related paper. By tradition, we do not even
reveal the number of entries that we received. (For the curious, |
we do indicate the volume of paper consumed when presenting the IOCCC
winners at talks)
After the Usenix announcement, we attempt to send EMail to the
authors of the winning entries. One reason we do this is to give
the authors a chance to comment on the way we have presented their
entry. They are given the chance to correct mistakes and typos. We |
often accept their suggestions/comments about our remarks as well.
This is done prior to posting the winners to the wide world.
Judging consists of a number of elimination rounds. During a round,
the collection of entries are divided into two roughly equal piles;
the pile that advances on to the next round, and the pile that does
not. We also re-examine the entries that were eliminated in the
previous round. Thus, an entry gets at least two readings.
A reading consists of a number of actions:
* reading the ---entry--- section
* reading the uudecoded ---build--- section
* reading the uudecoded ---program--- section
* reading the uudecoded ---info--- section(s), if any
* passing the source thru the C pre-processor
skipping over any #include files |
* performing a number of C beautify/cleanup edits on the source
* passing the beautified source thru the C pre-processor
skipping over any #include files |
In later rounds, other actions are performed:
* linting the source
* compiling/building the source
* running the program
* performing miscellaneous tests on the source and binary |
Until we reduce the stack of entries down to about 25 entries, entries
are judged on an individual basis. An entry is set aside because it
does not, in our opinion, meet the standard established by the round.
When the number of entries thins to about 25 entries, we begin to form
award categories. Entries begin to compete with each other for awards.
An entry often will compete in several categories.
The actual award category list will vary depending on the types of entries
we receive. A typical category list might be:
* best small one line program
* best small program
* strangest/most creative source layout
* most useful obfuscated program
* best game that is obfuscated
* most creatively obfuscated program
* most deceptive C code
* best X client (see OUR LIKES AND DISLIKES)
* best abuse of ANSI C
* worst abuse of the rules
* <anything else so strange that it deserves an award>
We do not limit ourselves to this list. For example, a few entries are so
good/bad that they are declared winners at the start of the final round.
We will invent awards categories for them, if necessary.
In the final round process, we perform the difficult tasks of
reducing the remaining entries (typically about 25) down to 8 or 10
winners. Often we are confident that the entries that make it into
the final round are definitely better than the ones that do not
make it. The selection of the winners out of the final round, is
less clear cut.
Sometimes a final round entry os good enough to win, but is beat out |
by a similar, but slightly better entry. For this reason, it is
sometimes worthwhile to re-enter an improved version of an entry
that failed to win in a previous year. This assumes, of course,
that the entry is worth improving in the first place!
More often than not, we select a small entry (usually one line), a
strange/creative layout entry, and an entry that abuses the contest
rules in some way.
In the end, we traditionally pick one entry as 'best'. Sometimes such
an entry simply far exceeds any of the other entries. More often, the |
'best' is picked because it does well in a number of categories.
ANNOUNCEMENT OF WINNERS:
The first announcement, occurs at the main Usenix conference. By |
tradition, this is done during the IOCCC BOF. |
Winning entries will be posted in February to the following groups:
comp.lang.c comp.unix.wizards alt.sources
In addition, pointers to these postings are posted to the following
comp.sources.d alt.sources.d misc.misc
comp.sources.misc comp.windows.x comp.lang.c++ |
comp.programming |
Winning entries will be deposited into the uunet archives. See
below for details.
Often, winning entries are published in selected magazines from around |
the world. Winners have appeared in books ("The New Hackers Dictionary") |
and on T-Shirts. |
Last, but not least, winners receive international fame and flames! :-)
FOR MORE INFORMATION:
You may contact the judges by sending EMail to the following address:
...!{apple,sun,uunet}!hoptoad!judges (not the address for |
judges@toad.com submitting entries)
Questions and comments about the contest are welcome. Comments about
confusing rules and guidelines are also welcome.
The rules and the guidelines may (and often do) change from year to
year. You should be sure you have the current rules and guidelines
prior to submitting entries. To obtain them, send EMail to the address
above and use the subject 'send rules'.
Check out the IOCCC Web page: |
http://reality.sgi.com/csp/ioccc |
It has rules, guidelines and winners of previous contests (1984 to date). |
One may also obtain previous winners via ftp from: |
host: ftp.uu.net |
user: anonymous
pass: yourname@yourhost
dir: pub/ioccc
As a last resort, previous winners may be obtained by sending EMail
to the above address. Please use the subject 'send YEAR winners',
where YEAR is a single 4 digit year, a year range (1993-1994), or 'all'. |
chongo <Landon Curt Noll> /\cc/\ {chongo,noll}@{toad,sgi}.com
Larry Bassel labbmf@ix.netcom.com |
Sriram Srinivasan sriram@tcs.com |
+88
View File
@@ -0,0 +1,88 @@
# include <stdio.h>
# define MAin printf("%d\n"
# define mAIN return 0
# define MaiN {static
# define mAlN ) {if(
# define MA1N char*
# define MAiN (!!(
# define mAiN atoi
# define mAln &1<<
# define MAlN !=3)
# define MAln )&&
# define MAIN int
# define maln --,
# define Maln <<
# define MaIn ++
# define MalN |=
# define MA1n ||
# define malN -1
# define maIN *
# define MaIN =
# define ma1N )
# define Ma1N (
# define Main ;
# define mA1n !
# define MAIn }
# define mA1N ,
MAIN mAIn
Ma1N MAIN
ma1N mA1N
mAiN Ma1N
MA1N ma1N mA1N maIn MaIN malN mA1N ma1n
mA1N maiN Main
MAIN main Ma1N MAIN Ma1n mA1N MA1N maIN
mAin mAlN Ma1n MAlN
mAIN Main maIn MaIn
mA1N Ma1n maln mAin MaIn Main maIn
MaIN mAiN Ma1N Ma1N
Ma1n maln maIN mAin
MaIn ma1N ma1N Main
ma1n MaIN mAiN Ma1N
Ma1N Ma1n maln maIN
mAin MaIn ma1N ma1N
Main mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N mAIn Ma1N mAIn Ma1N mAIn
Ma1N Ma1n ma1N
ma1N ma1N ma1N
ma1N ma1N ma1N ma1N ma1N ma1N
ma1N ma1N ma1N ma1N
ma1N ma1N Main MAin
mA1N maiN ma1N Main mAIN Main MAIn MAIN
mAIn Ma1N MAIN mAin ma1N
MaiN MAIN main MaIN malN
Main main MaIn Main mAIN
mA1N maiN MalN Ma1N MAiN
maIn mAln main ma1N
MA1n Ma1N MAiN ma1n
mAln main ma1N MA1n
mAin MAln Ma1N
mA1n MAiN ma1n mAln
main MAln mAin ma1N
ma1N ma1N MAln Ma1N mA1n MAiN maIn
mAln main MAln
Ma1N MAiN ma1n
mAln main ma1N MA1n mAin MAln
Ma1N mA1n MAiN
ma1n mAln main
MAln mAin ma1N
ma1N ma1N ma1N
ma1N ma1N Maln
main mA1N MAiN
ma1n mAln main
MAln mAin ma1N
MA1n MAiN maIn
mAln main MAln
Ma1N MAiN ma1n
mAln main ma1N MA1n
mAin MAln
Ma1N mA1n
MAiN ma1n
mAln main
MAln mAin
ma1N ma1N
ma1N ma1N
Main MAIn
+54
View File
@@ -0,0 +1,54 @@
Best Layout:
Heather Downs, Selene Makarios
The Software Bungalow
900 High School Way, #2202
Mountain View, CA 94041
USA
Judges' comments:
To use:
make heathbar
To run:
heathbar 4253 2281
The main reason we liked this entry was mainly because the main
effect of the source was self documenting! :-)
Selected Author's comments:
Run this program with two non-negative integer arguments
(e.g. "prog 1234 999").
My goal was to create the fastest possible C program. To that
end, I made three critical observations:
1. If there's one thing computers are good at, it's math.
2. Simple operations take less time than complicated ones.
3. Every C program seems to contain the word "main".
Based on #1, I knew that the Fastest Program had to be one that
performed addition. From #2, I reasoned that it ought to directly
manipulate the bits, rather than wasting time dealing with bloated,
high-level, fuzzy-logic, artificial-intelligence, neural-net,
client-server, object-oriented abstractions like the C language "+"
operator. And it was obvious from #3 that the program should
resemble, as closely as possible, a long sequence of the familiar
word "main" repeated over and over, so the computer would be
comfortable running the program and wouldn't get distracted dealing
with unfamiliar variable names.
Also, I've looked at some past winning entries of your contest, and
if you don't mind a little constructive criticsm, some of them are
kind-of hard to figure out. I didn't want my program to fall into
the same trap, so I went out of my way to write self-documenting
code. Anyone who so much as glances at my program will immediately
see that it adds two 16-bit unsigned integers by streaming their
bits through a simulated cascade of hardware adders. I hope my
diligent effort to write especially clear code gets me extra points!
P.S. What does "obfuscated" mean?
+94
View File
@@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define N O->
#define Li(V,K)[(K)*Ga/32+V/32]
#define Mg(P,V,K)(P Li(V,K)>>(V&31)&1)
#define H(P,V,K)(P Li(V,K)|=1<<(V&31))
#define U(P)calloc(P,1)
#define Au(V,K)Al[K|N U+V+V-1&7]
#define Ti(V,I,K,Y)((V^I&&K^Y&&I<Ga&&Y<As)?D[0]=Mg(Au,(V<I?V:I),K<Y?K:Y),F&2||H\
(Au,(V<I?V:I),K<Y?K:Y),D[0]:0)
#define Mn (V=rand()%100,(V>=Li/2)+(V<Li)-(V<Li/2))
#define Ge(P)P&&I[P]<Ga&&Y[P]<As&&!D[P]&&(Ge=Zr(I[P],Y[P],N T+1))&&!Mg(U,I[P],Y\
[P])&&(Ag(I[P],Y[P],(N U+2*P-3)&7,N T+1,F&24?C:Ge),0)
#define W(P)4-2*P-D[8]&&(I[P]=N V+Au(P,0),Y[P]=N K+Au(P,8),D[P]=Ti(N V,I[P],N K\
,Y[P]),printf("%d %d %lu %lu O ",Au(P,0)>>D[P],Au(P,8)>>D[P], N V, N K))
Ar *U, *Au, W, Li, F;
Mo Al[27];
S
{
Ar V, K, U, T;
S *H;
}
*C, *Zn;
S *
Zr (Mo V, Mo K, Mo T)
{
S *O = C, *W = Zn;
*(Mg(U, V, K)?&W:&O)=0;
while (O)
O = (W = !N T || (N T &= -!!(N V - V | N K - K | !(T - N T ^ 1))) ? O : 0) ? N H : 0;
return W;
}
void
Ag (Mo V, Mo K, Mo P, Mo T, S * O)
{
S *H = (O ? N H : C);
*(H ? &O : &Zn) = O = *(O ? &N H : &C) = U (sizeof (S));
N U = P; N T = T; N H = H; N V = V; N K = K;
F & 32 || H(U, V, K);
}
void
main (Mo V, char ** O)
{
char *H, Sg[106];
srand (time (0));
while (*++O && (sscanf (*O, "%lu", W ? &Li : &W) ||
(--**O, F |= !((**O - 57) % 14) << (**O - 57) / 14))
);
puts("%!\n/S{ 0 setlinewidth} /N{ showpage} /O{ moveto rlineto stroke} def def def S");
for (V = 0; V < 8; Al[8 | (V - 2) & 7] = Al[V] = !!(V & 3) * (1 - (V & 4) / 2) * 4, V++);
do
{
U = U (V = (As * Ga + 31) / 8);
Au = U (V);
for (*U = -W-1, H = U(W); ++*U; H[*U+W] = Mn);
Ag (Ga / 2, As / 2, 5, 1, C);
Ag (Ga / 2, As / 2, 1, 1, C);
while (C) {
Ar I[7], Y[5], D[13];
S *Ge, *O = C;
if (N T)
{
D[8] = (F & 4 ? Mn : W ? H[N T % W] : (N T & 85) % 3);
W ((!!C>>!C));
W ((!!C<<!!C));
Ge ((1 + D[8] / 2 + ((1 - ( F & 24 && (F & 16 || N T & 1))) & D[8])));
Ge (((1 + (F & 24 && (F & 16 || N T & 1))) & -(D[8] & 1)));
}
free((C = N H, O));
}
fgets(Sg, 2, stdin);
puts ("N S");
fflush (stdout);
free (H);
free (U);
free (Au);
}
while (!(!(W >> 1) | F & 1));
}
+216
View File
@@ -0,0 +1,216 @@
Best Use of Obfuscation:
Leonid A. Broukhis
46728 Crawford St., apt. 20
Fremont, CA 94539
USA
Judges' comments:
To use:
make leo
Try:
leo 1 | cat - /dev/tty | gs -
leo 37 80 | cat - /dev/tty | gs -
Press return after each image is drawn.
The variable names are element-ary. If you find this confusing,
remember that it is nu-clear. :-)
Some Ghostscripts/Postscript programs cleared the screen right after
the image is drawn, so we added element 106 which acts as an input
buffer. The original version may be found in leo.orig.c.
If you don't have gs or an equivalent postscript viewer, try:
echo "" | leo 1 > foo.ps
and send foo.ps to your local postscript printer.
To qualify for a category specially for yourself in the Geek code,
find out the all the secret switches that the author doesn't divulge !
(All switches are single characters on the command line - anything that's
not a number is a candidate)
Selected notes from the author:
The usage is:
prog.sh [ deep ] [ right ] [ Variable ] [ cycle [ freq ] ]
where the first three are literal words, `cycle' is a positive
integer (0 is ignored), and `freq' is an integer (default = 0)
supposed to be in range 0..100 (bigger values are allowed, however).
Invalid parameters and options usually stop the command line
parsing (but not always, why?). The actual position of the word
options does not matter, so "prog.sh right Variable 1 70"
is equivalent to "prog.sh 0 0 0 1 Variable 70 right", etc.
If `Variable' is used, `cycle' is almost ignored (see below) but has
to be present if you want to enter `freq' (and you usually do).
Some options to try (besides the obvious):
leo 1 | cat - /dev/tty | gs -
This draws the basic pattern I invented in high school:
You take a big sheet of "arithmetic" paper and draw a line
of length 1 (between 2 crossings) it the center of the sheet:
|
This makes 2 open ends (I think the notion of an "open end" doesn't
require explanations) in step 1. Now, until there are open ends in step N,
repeat: for each open end pretend it points north and draw 2 lines going
northwest and northeast from it to the nearest crossings. This needs to be
done "simultaneously" for all ends that are open at the moment.
Step 2:
\./
|
/ \
Step 3:
__| |__
\./
|
__ / \ __
| |
.
Step 4: \./ \./
\__| |__/
/ \./ \
|
\__./ \.__/
/ | | \
/ \./ \
Step 5:
._| . |_.
__| \./ \./ |__
\__| |__/
__./ \./ \.__
__I | I__
\__./ \.__/
__./ | | \.__
|_./ \./ \._|
| |
The lines marked by I show the places where "simultaneity" is significant.
Note that so far all the drawings represent valid
structural formulas of some organic substances.
step 1: ethane
step 2: 2,3-dimethylbutane
step 3: (2,5-dimethyl;3,4-isopropyl)-hexane
step 4 and 5: I don't know. Do you?
etc.
Step 6:
\./ \./ \./ \./
._| . |_. ._| . |_.
\__| \./ \./ |__/ \__| \./ \./ |__/
/ \__| |__/ \ / \__| |__/ \
\__./ \./ \.__/ \__./ \./ \.__/
X__| | |__X or <__| | |__>
/ \__./ \.__/ \ / \__./ \.__/ \
\__./ | | \.__/ \__./ | | \.__/
/ |_./ \./ \._| / |_./ \./ \._|
| | | |
/ \ / \ / \ / \
depending on the desired "hairiness". The original (paper-based)
algorithm was "hairy", but it didn't look as good on the screen.
The program cannot handle non-hairy mode 100% correctly - step 6 happens
to be
|__
...__/ ...__/
... \ ... \.
...__/ ...__/|__
...__Y and step 7: ...__Y
... \ ... \
...__/ ...__/
\ \.__
|
and so on: the horisontal symmetry has been lost. That's why
the opening for step 1 is not a single line but a cross:
\./
/ \
To watch it repeatedly (as a screen saver), use:
leo 2 | cat - /dev/tty | gs -
The command line:
leo Variable 1 | cat - /dev/tty | gs -
This draws the same as above. Try:
leo Variable 1 1 | cat - /dev/tty | gs -
what happened to the picture? Increase `freq' and watch the changes.
If `cycle' is more than 1, the program loops, allowing the user to
enjoy randomly changing patterns (the delay is 3 sec),
but there is a secret switch to suppress looping : useful
if you want to pipe the output to a printer.
uudecode the spoiler below if you really want to know.
begin 664 spoiler1
M*%1H92!C;VQO;B J:7,J('1H92!S96-R970@<W=I=&-H("T@=&AE('-P86-E
=(&)E9F]R92!I="!I<R!N;W0@82!M:7-T86ME*0II
end
If `Variable' is used, the actual value of `cycle' doesn't matter,
as far as it is > 1. To figure out what difference
`cycle' makes when `Variable' is not used, try
leo Variable 37 80 | cat - /dev/tty | gs -
and other values of `cycle'; smaller values usually require
smaller values of `freq' for the patterns to be non-trivial
The options `deep' and `right' make the patterns to be drawn in different
manners. Try all the examples above with `deep' and with `right'.
What is the difference between them?
...There is a little flaw in the implementation of the algorithm,
and sometimes the patterns are not symmetrical when they ought to be
(the program needs to be slightly changed to expose the flaw,
otherwise it is hardly noticeable, if ever).
A quick and dirty fix (turned on by another secret switch)
makes the patterns symmetrical, but a little too HAIRY.
There is one more secret switch (it shall remain nameless), and I don't
even want to explain what it does. You've been warned!
* * *
Special thanks:
- to PostScript syntax designers for the curly braces;
- to Dmitry Mendeleyev for his periodic table of elements;
- to Hydrogen for having 2 more isotopes.
+94
View File
@@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define N O->
#define Li(V,K)[(K)*Ga/32+V/32]
#define Mg(P,V,K)(P Li(V,K)>>(V&31)&1)
#define H(P,V,K)(P Li(V,K)|=1<<(V&31))
#define U(P)calloc(P,1)
#define Au(V,K)Al[K|N U+V+V-1&7]
#define Ti(V,I,K,Y)((V^I&&K^Y&&I<Ga&&Y<As)?D[0]=Mg(Au,(V<I?V:I),K<Y?K:Y),F&2||H\
(Au,(V<I?V:I),K<Y?K:Y),D[0]:0)
#define Mn (V=rand()%100,(V>=Li/2)+(V<Li)-(V<Li/2))
#define Ge(P)P&&I[P]<Ga&&Y[P]<As&&!D[P]&&(Ge=Zr(I[P],Y[P],N T+1))&&!Mg(U,I[P],Y\
[P])&&(Ag(I[P],Y[P],(N U+2*P-3)&7,N T+1,F&24?C:Ge),0)
#define W(P)4-2*P-D[8]&&(I[P]=N V+Au(P,0),Y[P]=N K+Au(P,8),D[P]=Ti(N V,I[P],N K\
,Y[P]),printf("%d %d %lu %lu O ",Au(P,0)>>D[P],Au(P,8)>>D[P], N V, N K))
Ar *U, *Au, W, Li, F, time ();
Mo Al[27];
S
{
Ar V, K, U, T;
S *H;
}
*C, *Zn;
S *
Zr (Mo V, Mo K, Mo T)
{
S *O = C, *W = Zn;
*(Mg(U, V, K)?&W:&O)=0;
while (O)
O = (W = !N T || (N T &= -!!(N V - V | N K - K | !(T - N T ^ 1))) ? O : 0) ? N H : 0;
return W;
}
void
Ag (Mo V, Mo K, Mo P, Mo T, S * O)
{
S *H = (O ? N H : C);
*(H ? &O : &Zn) = O = *(O ? &N H : &C) = U (sizeof (S));
N U = P; N T = T; N H = H; N V = V; N K = K;
F & 32 || H(U, V, K);
}
void
main (Mo V, char ** O)
{
char *H;
srand (time (0));
while (*++O && (sscanf (*O, "%lu", W ? &Li : &W) ||
(--**O, F |= !((**O - 57) % 14) << (**O - 57) / 14))
);
puts("%!\n/S{ 0 setlinewidth} /N{ showpage} /O{ moveto rlineto stroke} def def def S");
for (V = 0; V < 8; Al[8 | (V - 2) & 7] = Al[V] = !!(V & 3) * (1 - (V & 4) / 2) * 4, V++);
do
{
U = U (V = (As * Ga + 31) / 8);
Au = U (V);
for (*U = -W-1, H = U(W); ++*U; H[*U+W] = Mn);
Ag (Ga / 2, As / 2, 5, 1, C);
Ag (Ga / 2, As / 2, 1, 1, C);
while (C) {
Ar I[7], Y[5], D[13];
S *Ge, *O = C;
if (N T)
{
D[8] = (F & 4 ? Mn : W ? H[N T % W] : (N T & 85) % 3);
W ((!!C>>!C));
W ((!!C<<!!C));
Ge ((1 + D[8] / 2 + ((1 - ( F & 24 && (F & 16 || N T & 1))) & D[8])));
Ge (((1 + (F & 24 && (F & 16 || N T & 1))) & -(D[8] & 1)));
}
free((C = N H, O));
}
puts ("N S");
fflush (stdout);
free (H);
free (U);
free (Au);
sleep (3);
}
while (!(!(W >> 1) | F & 1));
}
+2
View File
@@ -0,0 +1,2 @@
main(n,i,a,m){while(i=++n)
for(a=0;a<i?a=a*8+i%8,i/=8,m=a==i|a/8==i,1:(n-++m||printf("%o\n",n))&&n%m;);}
+27
View File
@@ -0,0 +1,27 @@
Best Short Program:
Selene Makarios & Heather Downs
The Software Bungalow
900 High School Way, #2202
Mountain View, CA 94041
USA
Judges' comments:
To use:
make makarios
Try:
makarios
The judges were impressed that such a small program could do so much!
Can you figure out how it does it?
Selected notes from the authors:
This program takes no arguments. It emits the base 8 representation
of prime palindromes (palindromic in base 8, of course).
^_^
+1216
View File
File diff suppressed because it is too large. Load diff
+213
View File
@@ -0,0 +1,213 @@
12th International Obfuscated C Code Contest Rules |
Copyright (c) Landon Curt Noll, Larry Bassel and Sriram Srinivasan, 1995. |
All Rights Reserved. Permission for personal, education or non-profit use is
granted provided this this copyright and notice are included in its entirety
and remains unaltered. All other uses must receive prior permission in writing
from Landon Curt Noll, Larry Bassel and Sriram Srinivasan. |
Obfuscate: tr.v. -cated, -cating, -cates. 1. a. To render obscure.
b. To darken. 2. To confuse: his emotions obfuscated his
judgment. [LLat. obfuscare, to darken : ob(intensive) +
Lat. fuscare, to darken < fuscus, dark.] -obfuscation n.
obfuscatory adj.
GOALS OF THE CONTEST:
* To write the most Obscure/Obfuscated C program under the rules below.
* To show the importance of programming style, in an ironic way.
* To stress C compilers with unusual code.
* To illustrate some of the subtleties of the C language.
* To provide a safe forum for poor C code. :-)
NOTE: Some if the changes from the 1994 rules are denoted by change bars. ---> |
NOTE: The original 1995 mkentry.c contained a bug. We have remained this |
rule set 1995-1 to distinguish it from the previous set. |
RULES:
To help us with the volume of entries, we ask that you follow these rules:
1) Your entry must be a complete program.
2) Your entry must be <= 3217 bytes in length. The number of characters
excluding whitespace (tab, space, newline), and excluding any ; { or }
immediately followed by whitespace or end of file, must be <= 1536. |
3) Your entry must be submitted in the following format:
---entry---
rule: 1995-1 |
fix: y or n (n => this is a new entry, y => this replaces an older entry)
title: title of entry (see comments below)
entry: Entry number from 0 to 7 inclusive (your 1st entry should by 0)
date: Date/time of submission in UTC (see comments below)
host: Machine(s) and OS(s) under which your entry was tested
Use tab indented lines if needed
---remark---
Place remarks about this entry in this section. It would be helpful if
you were to indent your remarks with 4 spaces, though it is not a
requirement. Also, if possible, try to avoid going beyond the 79th
column. Blank lines are permitted.
---author---
name: your name
org: School/Company/Organization
addr: postal address
use tab indented lines to continue
don't forget to include the country
email: EMail address from a well known site or registered domain.
If you give several forms, list them on separate tab indented lines.
anon: y or n (y => remain anonymous, n => OK to publish this info)
---info---
If your program needs an info file, place a uuencoded copy of it in
this section. In the case of multiple info files, use multiple info
sections. If your entry does not need a info file, skip this section.
---build---
Place a uuencoded copy of the command(s) used to compile/build your program
in this section. It must uudecode into a file named 'build'. The resulting
file must be 255 bytes or less.
---program---
Place a uuencoded copy of your program in this section. It must uudecode
into a file named is 'prog.c'. The resulting file must follow rule #2.
---end---
Regarding the above format:
* The title must match the expression: [a-zA-Z0-9_=][a-zA-Z0-9_=+-]*
and must be 1 to 12 characters in length.
It is suggested, but not required, that the title should |
incorporate the author(s) username(s). |
* The date in the ---entry--- section should be given with respect
to UTC. The format of the date should be as returned by asctime()
using the C locale. (see guidelines for more info)
* You may correct/revise a previously submitted entry by sending
it to the contest email address. Be sure to set 'fix' in the
---entry--- section to 'y'. The corrected entry must use the same
title and entry number as submission that is being corrected. Be |
sure that you note the re-submission in the ---remark--- as well. |
* With the exception of the header, all text outside of the above
format may be ignored by the judges. If you need to tell the judges |
something, put it in the ---remark--- section, or send a separate
EMail message to the judges.
* Information from the ---author--- section will be published unless
'y' was given to the respective author's 'anon' line.
* To credit multiple authors, include an ---author--- section for
each author. Each should start with ---author--- line, and
should be found between the ---entry--- and ---build--- sections.
* The entry's remarks should include:
- note if this entry is a re-submission of a previous entry.
- what this program does
- how to run the program (sample args or input)
- special compile or execution instructions, if any
- special filename requirements (see rule 4 and 5)
- information about any ---info--- files
- why you think the program is obfuscated
- any other remarks (humorous or otherwise)
* Do not rot13 your entry's remarks. You may suggest that certain
portions of your remarks be rot13ed if your entry wins an award.
* Info files should be used only to supplement your entry. They
should not be required to exist.
* If your entry does not need an info file, skip the ---info---
section. If your entry needs multiple info files, use multiple
---info--- sections, one per info file. You should describe
each info file in the ---remark--- section.
* Your sections must in the same order as in the above template.
* Because the original 1995 mkentry.c program contained a bug, |
the rule set was changed to 1995-1. |
4) If your entry is selected as a winner, it will be modified as follows:
'build' is incorporated into a makefile, and 'build' is removed
'prog.c' is renamed to your entry's title, followed by an optional
digit, followed by '.c'
your entry is compiled into a file with the name of your entry's
title, possibly followed by a digit
If your entry requires that a build file exist, state so in your
entry's remark section. The makefile will be arranged to execute a
build shell script containing the 'build' information. The name of
this build shell script will be your entry's title, possibly followed
by a digit, followed by '.sh'.
If needed, your entry's remarks should indicate how your entry must
be changed in order to deal with the new filenames.
5) The build file, the source and the resulting executable should be
treated as read-only files. If your entry needs to modify these files,
it should make and modify a copy of the appropriate file. If this
occurs, state so in your entry's remarks.
6) The uudecoded ---program--- section must be able to be compiled |
cleanly by an ANSI C compiler, or if there are any compile errors, |
they must be documented in the ---remark--- section. |
7) The program must be of original work. All programs must be in the
public domain. All copyrighted programs will be rejected.
8) Entries must be received prior to 08-Dec-95 23:59 UTC. (UTC is |
essentially equivalent to Greenwich Mean Time) EMail your entries to:
...!{apple,sun,uunet}!hoptoad!obfuscate |
obfuscate@toad.com
We request that your message use the subject 'ioccc entry'.
If possible, we request that you hold off on EMailing your entries
until 19-Oct-95 12:00 UTC. Early entries will be accepted, however. |
We will attempt to EMail a confirmation to the sender of any entry
received after 19-Oct-95 12:00 UTC and before the close of the contest. |
9) Each person may submit up to 8 entries per contest year. Each entry
must be sent in a separate EMail letter.
10) Entries requiring human interaction to be built are not allowed. |
11) Programs that require special privileges (setuid, setgid, super-user,
special owner or group) are not allowed.
12) Legal abuse of the rules is somewhat encouraged. An entry that, in
the opinion of the judges, violates the rules will be disqualified.
Entries that attempt to abuse the rules must try to justify why
their rule abuse is legal in the ---remark--- section.
FOR MORE INFORMATION:
The judging will be done by Landon Noll, Larry Bassel and Sriram |
Srinivasan. Please send questions or comments about the contest, to: |
...!{apple,sun,uunet}!hoptoad!judges (not the address for |
judges@toad.com submitting entries)
Comments about confusing rules and guidelines are also welcome.
The rules and the guidelines may (and often do) change from year to
year. You should be sure you have the current rules and guidelines
prior to submitting entries. To obtain them, send EMail to the address
above and use the subject 'send rules'.
Check out the IOCCC Web page: |
http://www.ioccc.org
It has rules, guidelines and winners of previous contests (1984 to date). |
chongo <Landon Curt Noll> /\cc/\ {chongo,noll}@{toad,sgi}.com
Larry Bassel labbmf@ix.netcom.com |
Sriram Srinivasan sriram@tcs.com |
+41
View File
@@ -0,0 +1,41 @@
#include <stdio.h>
#define l11l 0xFFFF
#define ll1 for
#define ll111 if
#define l1l1 unsigned
#define l111 struct
#define lll11 short
#define ll11l long
#define ll1ll putchar
#define l1l1l(l) l=malloc(sizeof(l111 llll1));l->lll1l=1-1;l->ll1l1=1-1;
#define l1ll1 *lllll++=l1ll%10000;l1ll/=10000;
#define l1lll ll111(!l1->lll1l){l1l1l(l1->lll1l);l1->lll1l->ll1l1=l1;}\
lllll=(l1=l1->lll1l)->lll;ll=1-1;
#define llll 1000
l111 llll1 {
l111 llll1 *
lll1l,*ll1l1 ;l1l1 lll11 lll [
llll];};main (){l111 llll1 *ll11,*l1l,*
l1, *ll1l, * malloc ( ) ; l1l1 ll11l l1ll ;
ll11l l11,ll ,l;l1l1 lll11 *lll1,* lllll; ll1(l
=1-1 ;l< 14; ll1ll("\t\"8)>l\"9!.)>vl" [l]^'L'),++l
);scanf("%d",&l);l1l1l(l1l) l1l1l(ll11 ) (l1=l1l)->
lll[l1l->lll[1-1] =1]=l11l;ll1(l11 =1+1;l11<=l;
++l11){l1=ll11; lll1 = (ll1l=( ll11=l1l))->
lll; lllll =( l1l=l1)->lll; ll=(l1ll=1-1
);ll1(;ll1l-> lll1l||l11l!= *lll1;){l1ll
+=l11**lll1++ ;l1ll1 ll111 (++ll>llll){
l1lll lll1=( ll1l =ll1l-> lll1l)->lll;
}}ll1(;l1ll; ){l1ll1 ll111 (++ll>=llll)
{ l1lll} } * lllll=l11l;}
ll1(l=(ll=1- 1);(l<llll)&&
(l1->lll[ l] !=l11l);++l); ll1 (;l1;l1=
l1->ll1l1,l= llll){ll1(--l ;l>=1-1;--l,
++ll)printf( (ll)?((ll%19) ?"%04d":(ll=
19,"\n%04d") ):"%4d",l1-> lll[l] ) ; }
ll1ll(10); }
+54
View File
@@ -0,0 +1,54 @@
Most Obfuscated Syntax:
Michael Savastio
Securicor Telesciences
925 1/2 Anchor St, Apt 2
Philadelphia, PA 19124
USA
Judges' comments:
To use:
make savastio
To run:
savastio
enter a number (such as 100).
As one judge said:
I know an l when I see a 1.
Selected Author's comments:
This program is an infinite-precision factorial calculator. It will
compute the factorial of any number entered to an infinite degree of
precision (or the limits of your machine's memory, whichever comes
first). I'd suggest you start with small numbers the first few times
you run it and gradually work your way up in order to get a feel for
the computation time your machine will require.
Aside from having an artistic code layout and confusing variable names,
the algorithm itself takes advantage of some cute C-isms. Try to
figure out how it prints the prompt "Enter number:".
Numbers are represented internally by a linked list of blocks each
containing 1000 buckets of 4-digit integers. To further confuse
matters, the buckets are arranged backwards in the block. For example,
the number 8347108947139478934713847134 is represented as:
7134 1384 9347 3947 9471 7108 834
Platform limitations:
Long integers must be at least 4 bytes.
Features:
In order to prevent the user from wasting too much time computing
useless factorials, the maximum factorial that can be computed is
429539! This limit was selected through extensive research in
time management studies and the factorial arts.
+1
View File
@@ -0,0 +1 @@
main(l,i,I)char**i;{l/=!(l>(I=atoi(*++i))||fork()&&main(l+1,i-1)||I%l);return printf("%d\n",l);}
+32
View File
@@ -0,0 +1,32 @@
Best One Liner:
Mark Schnitzius
ISX Corporation
3215-C Post Woods Dr.
Atlanta, GA 30339
USA
Judges' comments:
To use:
make schnitzi
Try:
schnitzi 24
schnitzi 18
schnitzi 30
Sometimes a core dump is a feature, not a bug!
This is one of the better one-liners we have seen in a while.
Take some time to figure out what it does before you run it!
Selected notes from the author:
Beware, running this program with too high of a number
amounts to doing a fork bomb on your machine!
+658
View File
@@ -0,0 +1,658 @@
#include <stdio.h>
#include <string.h>
/*;
;
} {
} {
}
{ }
{
{
{ {
}
} {
{ } {
{
{ ;
{ ;
{
{
{ ;
} {
} } {
}
{
} {
{
{
{ { { { { {
{ {
}
} {
{ } {
;
{ { } }
;
}
;
{ { ; {
{ } {
{
; { ; {
{ }
; { ; {
{ } {
} ;
{ { ;
;
{ { ;
{ {
{ }
{
{
{
}
{
{ } {
}
}
{
;
{ {
{
{ ;
{ {
{ {
{ }
{
;
{ { ;
;
{
{ {
{
}
} {
;
{ {
} { {
}
} {
{ {
}
} {
{ } {
{
{
} { {
{
}
{
{
} ;
{ {
{ } ;
{
{ {
}
} {
{ }
{
; { }
{ {
{ }
{
{ ;
{
{
} {
}
}
{
{
{ {
{
{ } ;
{ {
}
} {
{ }
{
; { }
{ {
{ }
{
{ ;
{ {
}
} {
}
} ; { {
{ }
;
{ ;
{ {
}
} {
{ }
{
;
{ {
{
{ {
}
} {
{ }
}
{ { {
;
{ {
;
{
;
{
;
{ ;
;
;
{ { { { { {
{
{ }
}
} {
{ } {
{
} } {
{ } {
}
}
{
;
{ {
}
} {
{ } {
{
{ ;
{ } }
}
{
{ }
{
{
}
{ } {
{ }
}
{
} { { {
}
;
{ { { { {
{
{ }
}
{ } {
{
}
}
} {
{
{
{
{
{ } }
}
{
{ } }
{
; {
{ {
{
}
{
{ }
{ ;
{ { { { {
{
{ } } }
{
} } { ;
{ {
}
{
}
} { }
} { }
}
} }
{
{ {
{
{
;
{ { { { {
{
{
}
} } }
{ } {
{ }
{
{
{
{ } {
{ } }
{ }
{
}
{
} {
{
{ } {
{ ;
{
{
}
{ {
;
{ { { { {
{
{ } }
}
{
{
{ { { } { {
{
{ {
}
}
{ {
}
{ }
}
{ ;
{ {
{
{
;
{ { ;
;
{ { {
;
;
{ { { { { {
;
;
;
{ { { { { ;
{
}
}
{ {
} }
{
}
} } { { {
{ ;
;
{ ;
;
;
;
{ { } {
} {
{
{
} ;
{ {
{
{
}
{ {
}
{
{
{ {
{ }
{ {
} {
}
} { { { { { { { { {
}
{
}
{
{ }
} {
} } { {
{
{
} { { ; { } } { {
{
; {
{
}
{
; { {
{
{ {
}
{
}
{
{ {
{ ;
{
{
}
{ { { { { { { { {
{
{
{ } {
{ {
}
{
{
{ { { }
} {
} } { {
{
{
}
{ {
{
{
{
{ {
{
; {
}
} } { { {
{ ;
;
{ ;
; ;
; ;
{ { { { {
;
;
;
{
{
comments!=style
*/
int c;char*s="{ } ;\n*";b(){
return
strchr (s,getchar())-s;}
n (){int c;
c= b()*3;
c +=b()/2;
c=c*3+ b()/2;
return
c==0?' ':
c==1?'\n':
c==2?' ':
c<33?c+'a'
-3:(c-32)
*3+' '+b
()/2;
}main(){
while(b()!=6);
while((c=n())!='$')
putchar(c);}
+32
View File
@@ -0,0 +1,32 @@
Abusing The Rules:
Diomidis Spinellis
SENA S.A.
Kyprou 27
GR-152 37 Filothei
Greece
Judges' comments:
To use:
make spinellis
Try:
spinellis < spinellis.c
While code does not abuse the rules, its output surely does!
P.S. Does the source have any spelling errors?
Selected notes from the author:
96% of the program lines (631 out of the 658) are comment text rendering
the program readable and understandable. With the exception of the
two include file names (needed for a warning-free compile) the program
passes the standard Unix spell checker without any errors. Checking
for spelling errors is considered very important for programs that are
so heavily commented. This program is exactly 3217 characters long
through judicious use of white space. Rule abuse? Would I _ever_ abuse
the rules?
+152
View File
@@ -0,0 +1,152 @@
#ifndef pdbq
#ifndef n
#define n 05
#endif pqbd
#define dpqb __FILE__
#define ppbd "Move disk %d from peg %d to peg %d\n"
#define pdbq
#if n&01
#define dqbp
#endif bpdq
#if n&02
#define dbpq
#endif pbdq
#if n&04
#define pbqd
#endif qbpb
#if n>>3
#define bqdp
#endif pbbq
main(){ pdbq
printf( pdbq
#include dpqb
#define qbdp
#include dpqb
);} qbdp
#else dpdp
#ifdef dqbp
#define bdpq
#endif bpdd
#ifdef dbpq
#define bdpq
#endif pqpb
#ifdef pbqd
#define bdpq
#endif pdpp
#ifdef bqdp
#define bdpq
#endif pdpp
#ifdef bdpq
#undef bdpq
#ifndef dqbp
#define dqbp
#ifndef dbpq
#define dbpq
#ifndef pbqd
#define pbqd
#ifndef bqdp
#define bqdp
#else dbqb
#undef bqdp
#endif qdqb
#else pdbq
#undef pbqd
#endif qdbp
#else pqbb
#undef dbpq
#endif pqbd
#else bbpp
#undef dqbp
#endif ppqb
#include dpqb
#ifndef dqbp
#ifndef dbpq
#ifndef pbqd
#ifndef bqdp
#define bdpq
#endif pbpp
#endif qpdp
#endif ddpb
#endif qppb
#ifdef bdpq
#undef bdpq
#ifndef qbdp
pdbq ppbd
#else qbbd
#ifdef pqdb
,1,2,3 pqdb
#undef pqdb
#define qdbp
#else bdbb
#ifdef qdbp
,1,3,1 qdbp
#undef qdbp
#else bdbd
,1,1,2 pdbq
#define pqdb
#endif qppq
#endif pqpb
#endif bpdd
#else pqpq
#ifndef qbdp
pdbq ppbd
#else qqqb
,1 pdbq
#ifdef dqbp
+1 dqbp
#endif qqdb
#ifdef dbpq
+2 dbpq
#endif ppqb
#ifdef pbqd
+4 pbqd
#endif pqpp
#ifdef bqdp
+8 bqdp
#endif bbpb
#ifdef pqdb
#ifdef dqbp
,1,3 dqbp
#else pddp
,3,1 pdbq
#endif qpqq
#else dbqb
#ifdef qdbp
#ifdef dqbp
,2,1 dqbp
#else pqdb
,1,2 pdbq
#endif dbdp
#else pdpp
#ifdef dqbp
,3,2 dqbp
#else pdbb
,2,3 pdbq
#endif pqpp
#endif qbdp
#endif pqpp
#endif pdbp
#endif pqdp
#include dpqb
#ifdef dqbp
#undef dqbp
#ifdef dbpq
#undef dbpq
#ifdef pbqd
#undef pbqd
#ifdef bqdp
#undef bqdp
#else qddb
#define bqdp
#endif ppqp
#else bddq
#define pbqd
#endif ddbq
#else bbdb
#define dbpq
#endif qqbd
#else ddbq
#define dqbp
#endif qbdb
#endif qbdb
#endif qbpp
+166
View File
@@ -0,0 +1,166 @@
Worst Abuse of the C Preprocessor:
and Most Likely To Amaze:
Mark Schnitzius & David Van Brackle
ISX Corporation
1165 Northchase Parkway
Suite 120
Marietta, GA 30067
USA
Judges' comments:
To use:
make vanschnitz
Try:
vanschnitz
For a good time, try:
rm -f vanschnitz
make vanschnitz LEVEL=8
Warning: Values of LEVEL>8 have been known to cause compilers
(and in one case a system) to crash during compilation.
For a bad/slow time try LEVEL=15.
Selected notes from the authors:
A classic problem in computer science is known as the Towers
of Hanoi. It involves a set of different-sized disks mounted
on one of three pegs. The object is to move the pile of disks
to one of the other pegs. You may only move one disk at a
time, and there is an additional constraint that a disk may
never be placed on top of a smaller disk.
Our program solves the Towers of Hanoi problem. Well, that's
not exactly true; actually, it's the compiler that solves the
problem. The resulting program just prints out the correct
solution.
How do you trick a compiler into actually solving the problem?
First, you must tell it how many disks you wish to solve it
for. This is done by defining the symbol 'n' on the compile
line. For instance, to cause the compiler to solve the Towers
of Hanoi problem with four disks, you would compile the program
like this:
gcc hanoi.c -o hanoi -Dn=4
A default value of 5 will be used for n if you do not define
it on the command line. The value of n cannot be greater than
fifteen (the compiler we used to test has a limit on the #include
depth). The compiler then solves the problem using binary
arithmetic based on whether particular symbols are defined or not.
To loop, the program #include's itself. This is, of course,
expensive; one compile we did with n=14 took about fifty
minutes to compile on our system (compiling with n=15
caused our system to crash).
The resulting program that the compiler generates simply
prints out the answer. Did I say "simply"? Actually, the
whole resulting program consists of a single printf statement,
consisting of a massive string constant of length 35*(2^n-1),
followed by 3*(2^n-1) integers which get formatted into the
string. For our n=14 run, this adds up to a string constant
of length 573405, followed by 49149 integers delimeted by
commas. (Generating the string constant depends on the
ANSI C feature in which adjacent character strings are
catenated; a version that does not use this feature has been
included for people who can only run K&R). A good way to see
the resulting program (on a Unix system) is to do the command
gcc hanoi.c -E -Dn=5 | grep -v \# | grep -v ^\$
For an odd number of disks, the program will provide a
solution wherein the disks end up on peg 2; for an even
number of disks, they will end on peg 3. This should
provide some hint as to what sort of algorithm is used.
We have included a "spoiler" version of the program, with
meaningful symbol names and comments, but we encourage you
to try to decipher the program without it...
begin 444 spoiler.c
M(VEF;F1E9B`@24Y)5$E!3$E:140*"B\J"B`J("!)9B!N(&ES;B=T(&1E9FEN
M960L(&UA:V4@:70@-0H@*B\*(VEF;F1E9B`@;@HC9&5F:6YE("!N(#`U"B-E
M;F1I9@H*+RH*("H@4V]M92!U<V5F=6P@=F%R:6%B;&5S"B`J+PHC9&5F:6YE
M("!42$E37T9)3$4@7U]&24Q%7U\@"B-D969I;F4@($9/4DU!5%]35%))3D<@
M(DUO=F4@9&ES:R`E9"!F<F]M('!E9R`E9"!T;R!P96<@)61<;B(*(V1E9FEN
M92`@24Y)5$E!3$E:140*"B\J"B`J(%1R86YS;&%T92!N(&EN=&\@8FET<PH@
M*B\*(VEF("`@("`@;B8P,0HC9&5F:6YE("!B:70P"B-E;F1I9@HC:68@("`@
M("!N)C`R"B-D969I;F4@(&)I=#$*(V5N9&EF"B-I9B`@("`@(&XF,#0*(V1E
M9FEN92`@8FET,@HC96YD:68*(VEF("`@("`@;CX^,PHC9&5F:6YE("!B:70S
M"B-E;F1I9@H*+RH*("H@2&5R92=S('1H92!P<F]G<F%M(0H@*B\*;6%I;B@I
M>PIP<FEN=&8H"B-I;F-L=61E(%1(25-?1DE,10HC9&5F:6YE("!.3U=?1$]?
M5$A%7TY534)%4E,*(VEN8VQU9&4@5$A)4U]&24Q%"BD[?0H*(V5L<V4*"B\J
M"B`J($-H96-K('1O('-E92!I9B!T:&4@;G5M8F5R(&ES('IE<F\@*&)O='1O
M;2!O9B!R96-U<G-I;VXI"B`J+PHC:69D968@("!B:70P"B-D969I;F4@($Y?
M25-?3D]47UI%4D\*(V5N9&EF"B-I9F1E9B`@(&)I=#$*(V1E9FEN92`@3E])
M4U].3U1?6D523PHC96YD:68*(VEF9&5F("`@8FET,@HC9&5F:6YE("!.7TE3
M7TY/5%]:15)/"B-E;F1I9@HC:69D968@("!B:70S"B-D969I;F4@($Y?25-?
M3D]47UI%4D\*(V5N9&EF"@HC:69D968@("!.7TE37TY/5%]:15)/"B-U;F1E
M9B`@($Y?25-?3D]47UI%4D\*"B\J"B`J($1E8W)E;65N="!N"B`J+PHC:69N
M9&5F("!B:70P"B-D969I;F4@(&)I=#`*(VEF;F1E9B`@8FET,0HC9&5F:6YE
M("!B:70Q"B-I9FYD968@(&)I=#(*(V1E9FEN92`@8FET,@HC:69N9&5F("!B
M:70S"B-D969I;F4@(&)I=#,*(V5L<V4*(W5N9&5F("`@8FET,PHC96YD:68*
M(V5L<V4*(W5N9&5F("`@8FET,@HC96YD:68*(V5L<V4*(W5N9&5F("`@8FET
M,0HC96YD:68*(V5L<V4*(W5N9&5F("`@8FET,`HC96YD:68*"B\J"B`J("!(
M97)E)W,@<F5C=7)S:6]N"B`J+PHC:6YC;'5D92!42$E37T9)3$4*"B\J"B`J
M("!.;W1E.B!/9&0@;G5M8F5R960@9&ES:W,@86QW87ES(&-Y8VQE(&9R;VT@
M,2`]/B`R(#T^(#,@/3X@,2`]/B`R(#T^(#,*("H@($5V96X@;G5M8F5R960@
M9&ES:W,@86QW87ES(&-Y8VQE(&9R;VT@,2`]/B`S(#T^(#(@/3X@,2`]/B`S
M(#T^(#(*("HO"@HO*@H@*B!#:&5C:R!T;R!S964@:68@;B!I<R!Z97)O+B!)
M9B!S;RP@=V4G<F4@;6]V:6YG(&1I<VL@,2X*("H@26X@9V5N97)A;"P@9F]R
M(&%N>2!N('=E)W)E(&UO=FEN9R!D:7-K(&XK,2X@5&AA="!M96%N<R!T:&%T
M"B`J('=H96X@;B!I<R!O9&0L('=E)W)E(&UO=FEN9R!A;B!E=F5N(&1I<VLL
M(&%N9"!V:6-E('9E<G-A+@H@*B\*(VEF;F1E9B`@8FET,`HC:69N9&5F("!B
M:70Q"B-I9FYD968@(&)I=#(*(VEF;F1E9B`@8FET,PHC9&5F:6YE("!.7TE3
M7UI%4D\*(V5N9&EF"B-E;F1I9@HC96YD:68*(V5N9&EF"@HC:69D968@("!.
M7TE37UI%4D\*(W5N9&5F("`@3E])4U]:15)/"@HC:69N9&5F("!.3U=?1$]?
M5$A%7TY534)%4E,*1D]234%47U-44DE.1PHC96QS90H*+RH*("H@($EF(&1I
M<VL@,2!I<R!O;B!P96<@,BP@;6]V92!I="`R(#T^(#,*("HO"B-I9F1E9B`@
M($1)4TM?3TY%7TE37T].7U!%1U]45T\*+#$L,BPS"B-U;F1E9B`@($1)4TM?
M3TY%7TE37T].7U!%1U]45T\*(V1E9FEN92`@1$E32U]/3D5?25-?3TY?4$5'
M7U1(4D5%"B-E;'-E"@HO*@H@*B`@268@9&ES:R`Q(&ES(&]N('!E9R`S+"!M
M;W9E(&ET(#,@/3X@,0H@*B\*(VEF9&5F("`@1$E32U]/3D5?25-?3TY?4$5'
M7U1(4D5%"BPQ+#,L,0HC=6YD968@("!$25-+7T].15])4U]/3E]014=?5$A2
M144*(V5L<V4*"B\J"B`J("!$:7-K(#$@;75S="!B92!O;B!P96<@,2X@36]V
M92!I="`Q(#T^(#(*("HO"BPQ+#$L,@HC9&5F:6YE("!$25-+7T].15])4U]/
M3E]014=?5%=/"B-E;F1I9@HC96YD:68*(V5N9&EF"B-E;'-E"@HO*@H@*B`@
M2&5R92P@=V4@:&%N9&QE(&1I<VMS(#XQ+B!296UE;6)E<B!T:&%T(&]D9',@
M8WEC;&4@,2`]/B`R(#T^(#,@/3X@,2P*("H@(&%N9"!E=F5N<R!C>6-L92`Q
M(#T^(#(@/3X@,R`]/B`Q+B!#;VUB:6YE('1H:7,@=VET:"!T:&4@:VYO=VQE
M9&=E"B`J("!O9B!W:&5R92!D:7-K(#$@:7,L(&%N9"!W92!C86X@9&5T97)M
M:6YE(&AO=R!T;R!M;W9E(&%N>2!D:7-K+@H@*B\*(VEF;F1E9B`@3D]77T1/
M7U1(15].54U"15)3"D9/4DU!5%]35%))3D<*(V5L<V4*"B\J"B`J("!0<FEN
M="!T:&4@9&ES:R!N=6UB97(N(%)E;65M8F5R+"!D:7-K(&YU;6)E<B`](&XK
M,0H@*B\*+#$*(VEF9&5F("`@8FET,`HK,0HC96YD:68*(VEF9&5F("`@8FET
M,0HK,@HC96YD:68*(VEF9&5F("`@8FET,@HK-`HC96YD:68*(VEF9&5F("`@
M8FET,PHK.`HC96YD:68*"B\J"B`J("!$:7-K(#$@;VX@<&5G(#(@"B`J+PHC
M:69D968@("!$25-+7T].15])4U]/3E]014=?5%=/"B-I9F1E9B`@(&)I=#`*
M+#$L,R`@("`O*B!%=F5N.B`Q(#T^(#,@("AN(&ES(&]D9"P@<V\@=&AE(&1I
M<VL@:7,@979E;BD@*B\*(V5L<V4*+#,L,2`@("`O*B`@3V1D.B`S(#T^(#$@
M("HO"B-E;F1I9@HC96QS90H*+RH*("H@($1I<VL@,2!O;B!P96<@,R`*("HO
M"B-I9F1E9B`@($1)4TM?3TY%7TE37T].7U!%1U]42%)%10HC:69D968@("!B
M:70P"BPR+#$@("`@+RH@179E;CH@,B`]/B`Q("HO"B-E;'-E"BPQ+#(@("`@
M+RH@($]D9#H@,2`]/B`R("HO"B-E;F1I9@HC96QS90H*+RH*("H@($1I<VL@
M,2!O;B!P96<@,2`*("HO"B-I9F1E9B`@(&)I=#`*+#,L,B`@("`O*B!%=F5N
M.B`S(#T^(#(@*B\*(V5L<V4*+#(L,R`@("`O*B`@3V1D.B`R(#T^(#,@*B\*
M(V5N9&EF"B-E;F1I9@HC96YD:68*(V5N9&EF"B-E;F1I9@H*+RH*("H@($UO
M<F4@<F5C=7)S:6]N"B`J+PHC:6YC;'5D92!42$E37T9)3$4*"B\J"B`J("!)
M;F-R96UE;G0@;@H@*B\*(VEF9&5F("`@8FET,`HC=6YD968@("!B:70P"B-I
M9F1E9B`@(&)I=#$*(W5N9&5F("`@8FET,0HC:69D968@("!B:70R"B-U;F1E
M9B`@(&)I=#(*(VEF9&5F("`@8FET,PHC=6YD968@("!B:70S"B-E;'-E"B-D
M969I;F4@(&)I=#,*(V5N9&EF"B-E;'-E"B-D969I;F4@(&)I=#(*(V5N9&EF
M"B-E;'-E"B-D969I;F4@(&)I=#$*(V5N9&EF"B-E;'-E"B-D969I;F4@(&)I
M=#`*(V5N9&EF"@HC96YD:68@("\J("-I9F1E9B!.7TE37TY/5%]:15)/("HO
M"@HC96YD:68@("\J("-E;'-E(&]F("-I9FYD968@24Y)5$E!3$E:140@*B\*
`
end