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.
+157
View File
@@ -0,0 +1,157 @@
# %W% %G% %U%
#
# 1996 makefile
#
# Copyright (c) 1997, Landon Curt Noll & 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 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= august dalbec eldby gandalf huffman jonth rcm schweikh1 \
schweikh2 schweikh3 westley
ALT_NAMES= august.orig
LEVEL=5
all: $(WINNERS)
# NOTE: Some compilers will compile this code into infinite loop
# progs. We have found gcc to work on a number of platforms.
# If the following example does not execute in a very
# short time, try a better compiler:
#
# cat august.c test.oc | ./august > test.oo
#
august: august.c fac.oc parse.oc test.oc
${CC} ${CFLAGS} -DZ=60000 -D'T=m[s]' -D'P=m[s++]' \
-D'L=m[p++]' -D'g=getchar()' -DE=else -DW=while -D'B=m[p++]' \
-DI=if -DR='s=s+l/2;T=r;I(l%2)s++' -D'X=m[s-' \
-D'D=Q(13,-)Q(14,*)Q(15,/)Q(16,%)Q(6,==)Q(7,!=)Q(8,<)C(1,r=P;m[T]=r;T=r)C(9,r=P;m[T]=r;s++)' \
august.c -o august
${CHMOD} +r fac.oc parse.oc test.oc
# This forms a byte code execution engine written in OC
#
august.oc: august.c
${RM} -f august.oc
${CC} ${CFLAGS} -E -DZ=40000 -D'T=m[s]' -D'P=m[s++]' \
-D'L=m[p++]' -D'g=getchar()' -DE=else -DW=while -D'B=m[p++]' \
-DI=if -DR='s=s+l/2;T=r;I(l%2)s++' -D'X=m[s-' \
-D'D=Q(13,-)Q(14,*)Q(15,/)Q(16,%)Q(6,==)Q(7,!=)Q(8,<)C(1,r=P;m[T]=r;T=r)C(9,r=P;m[T]=r;s++)' \
august.c > august.oc
${CHMOD} +r august.oc
# NOTE: this is the original source that won
#
august.orig: august.orig.c fac.oc parse.oc test.oc
${CC} ${CFLAGS} -DZ=60000 -DZ=60000 -D'T=m[s]' -D'P=m[s++]' \
-D'L=m[p++]' -D'g=getchar()' -DE=else -DW=while -D'B=m[p++]' \
-DI=if -DR='s=s+l/2;T=r;I(l%2)s++' -D'X=m[s-' \
-D'D=Q(13,-)Q(14,*)Q(15,/)Q(16,%)Q(6,==)Q(7,!=)Q(8,<)C(1,r=P;m[T]=r;T=r)C(9,r=P;m[T]=r;s++)' \
august.orig.c -o august.orig
${RM} -f august.oc
${CC} ${CFLAGS} -E -DZ=40000 -D'T=m[s]' -D'P=m[s++]' \
-D'L=m[p++]' -D'g=getchar()' -DE=else -DW=while -D'B=m[p++]' \
-DI=if -DR='s=s+l/2;T=r;I(l%2)s++' -D'X=m[s-' \
-D'D=Q(13,-)Q(14,*)Q(15,/)Q(16,%)Q(6,==)Q(7,!=)Q(8,<)C(1,r=P;m[T]=r;T=r)C(9,r=P;m[T]=r;s++)' \
august.orig.c > august.oc
${CHMOD} +r fac.oc parse.oc test.oc august.oc
dalbec: dalbec.c
${CC} ${CFLAGS} dalbec.c -o dalbec
eldby: eldby.c
${CC} ${CFLAGS} eldby.c -o eldby
gandalf: gandalf.c
${CC} ${CFLAGS} gandalf.c -o gandalf
${RM} -f hatcat cathat
${CP} gandalf hatcat
${CP} gandalf cathat
huffman: huffman.c
${CC} ${CFLAGS} huffman.c -o huffman
# Add -I${X}/include and -L${X}/lib if this doesn't build
# (X is the root of the X Window distribution)
# Solaris users add -lsocket
#
jonth: jonth.c
${CC} ${CFLAGS} jonth.c -o jonth -lX11 -lm
rcm: rcm.c
${CC} ${CFLAGS} -DJ='if(' -Ds='else J O==' -DU='B(' \
-DX='for(' -DH='unsigned' -Dn='struct x' -DA='0,0,0,0,' \
-DT='<stdio.h>' -DY='<stdlib.h>' -DR='malloc(sizeof(n))' \
-DM='%=K' -DK=32768 -DD='getchar()' -DN=putchar rcm.c -o rcm
schweikh1: schweikh1.c errno.h
${CC} ${CFLAGS} -I. schweikh1.c -o schweikh1
schweikh2: schweikh2.c hunni.c hunni.pl
${CC} ${CFLAGS} -D_POSIX_SOURCE schweikh2.c -o schweikh2
# NOTE: On some systems such as SunOS, one may need to compile with:
#
# ${CC} ${CFLAGS} \
# -I. -D_POSIX_SOURCE '-Ddifftime(a,b)=(double)(b-a)' \
# schweikh3.c -o schweikh3
#
schweikh3: schweikh3.c iso646.h
${CC} ${CFLAGS} -I. -D_POSIX_SOURCE schweikh3.c -o schweikh3
westley: westley.c clock1 clock2 clock3
${CC} ${CFLAGS} westley.c -o westley
${CHMOD} +x clock1 clock2 clock3
clean:
${RM} -f *.o a.out core ${WINNERS}
clobber: clean
${RM} -f $(WINNERS)
${RM} -f $(ALT_NAMES)
${RM} -f fac.oo parse.oo test.oo hatcat cathat august.oc
nuke: clobber
@${TRUE}
install: all
${CAT} $(WINNERS) $(ALT_NAMES) > /dev/null
+97
View File
@@ -0,0 +1,97 @@
1996 marked the "The Thirteenth International Obfuscated C Code Contest"
Copyright (c) 1997, Landon Curt Noll & 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 and Sriram Srinivasan.
Standard IOCCC stuff
--------------------
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).
Where are Larry Bassel and Barbara Frezza?
------------------------------------------
It is not true that Larry Bassel avoided the 13th IOCCC on grounds of
superstition! Larry (as well as Landon) is fond of prime numbers.
Larry is so fond of prime numbers that he decided to become a graduate
student in number theory at UC San Diego. For this reason Larry
decided to sit out this year and plans to be back next year.
Barbara Frezza also went to San Diego to enter into law school
at the same time. Her cooking in the role of official chef was
sorely missed. We look forward to her return to the contest
next year as well.
Both Larry and Barbara have taken important new steps in their
lives as we wish them the best. When it is all over, Larry will
be able to produce obfuscated mathematical proofs, and Barbara
will be able de-obfuscate the many legal obfuscations. :-)
Remarks on some of the entries
------------------------------
This year, Jens Schweikhardt won 3 times ... a new IOCCC record.
Meanwhile, Brian Westley came up with his 8th winning entry, twice the
number of the next highest count. But with people like Schweikhardt
around, this lead could fall fast.
As we state in the guidelines, the names of the winners are as much
news to us as they are to you because we keep authorship separate from
rest of the entry. Some people have it, we guess!
There were a few very good entries that might have won if it were not
for the fact that they didn't work. If you didn't win, but think you
had a chance: test your program, fix it and submit it next year!
A few notes regarding future contests
-------------------------------------
There is no 1997 contest.
The next contest will not open until sometime in March 1998, and will
close sometime around the end of May 1998. The rules for the 1998
contest have not been formed at this time and are not expected to be
ready for distribution until late February 1998.
So what happened to 1997? Well the next USENIX Technical Conference
will be held Jun 15-19, 1998 (in New Orleans, USA). The 18 month
span between conferences will cause the IOCCC to skip over 1997.
Be sure to wait until the 1998 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:
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.
+321
View File
@@ -0,0 +1,321 @@
/*T } ¶ ;
ˆ
;

;
}
{ 
{ ;  ;
; 1 {
è { !
} {
; é ;
;
{

{ ]- } ; ; |
í ; Q
;
´ë ; ; ; "û }
} Ü; ; -ýl
}
} t dÀ ;
; +
t2 { ì ;
} 1; C
i
; = } ; ;

;
ì ; {
{ ê
} { � { ï } }
; . {
␍ { é } } ; 
{ ;
; /nÈ; 5
} ; Ú␍{ ; 
; { 1 ; } ; ¨ý } {
;  { ; . { ;  } ;  ;
; T ;
{
; ; Ä; ;  {
;
 { { ; ;
ì; ‘ ; ; ï; n!t }
; ì!; G; t;  ø; ¤ }  ;
;
} ; "; è# }
; 
{
; �$ {
;
; &
; d˜
{
¶;  {
; Sé'
{ d; ; è); �c
{
;  ;
; &ï*; ␍ ;
— {
;
$; ¢; ,; ; $ˆd } —; ˆ; ë/Î; Î
; a; Í ; {
} ; j; #è1;
 }
; Ä ; { ê5a; û␍ Ät { ï4a }
}
; £ ;
Û2; -
; 8
} ; }
; è8; ;  Ú6Q ; aÌ { ;  { ˆ
ì }
†; v:
{
?
}
{ ?
{ ; 4r
;
; v=b; Û
;
;
} ; 
; ; ; Þ { ú>
} }
{  ;
{ Õ`
}
;
;
!;
; 1; ; >; Ì } 1; X
; } p ;
;
; ; ; 
; ; 2 } ; vm
2; ;1íJ
;
; ; Ï }
; ÉJc; ›; d }
} ÞG; i }
; ; §F
{ vl¶þV; z
n
¶éOc; s
; ; ÑÞ;
 uh¶ëR } hRs; A cl,;
; ; Z;  {
x
lw¶êUch�{  }
} ; àîVc }
; Ž; >ÈD
; G ; ; †
;
îX; ’ˆ
;
; 2 }  { é[; 
{  }
; Þj; å; ë_; ␍y
; D; T; ; ?j; .n; ; ã {
; Ú]; !; Ë; 0a
} J ;
; ^; .
{ { { îc; ␍X ; ; ´;
J {
; ;
 } — { êf; 
; {
; ; : } { 
{
; (h} ␍ }
{  }
} ; ; { 
; ûD; Tì Cr; ␍; I; WèsÎWQ
; ;
×; W { û }
; ( ; ; }
} ;  {
; ÿn{ k; © ; ‚; ?; %Ùk;  ;
{ ïv;
3{ (; h {
; ; z
; ; ]{ ; ˜ïx; S; { * } ˜; z} ; î; 
{ ; ~
;
U; ö
; { ‡
; í~;
Ob } ; ò; UU; U{ -{ %Ú|1èƒ;
; Q
;
µ{ w{ š;  ;
 { í‡; ‚; ü�
…
} Ù†; ?; u
{
ƒ
} } ; » ; ´ ; ;  }
; è
{
; ;  }
; p ; ; ; Q; Ü�{ ; ; K; $ì“
p; 1}
4; $;
2Q ; }  {
; $î— } ; #;
T; 1
; ; +; ± } 
; ;
. ; { 
{ ; š{
  ;
{
; ;  }
; { [ { ; £{ ; �; 0{ 
{ ôr ; éŸ
;
} =; w
?; ;
ä; B®lwx
; h�h
} ; pj
; ; ; ö { û§; 'n
; ; { ) {
; ú¤;
;
Q
; f; 'r
{
? { ë¬; %lÂf}
; ~©{ qÛ¨; 
{
 { ÿ­; ÂÛ¬{ œÚžl,u
; & ;
{ í; G } 
; k
;  }
; 
{
; hR; ; Wß´; 
} ;
; ; —e; Z; ž{ N; =
} ; <
{ ]- Bšretur; ¡if
else
whil; do; nt
char
{ ; { pu{  }
{ ; =
} B
} {
; ø¿`ˆ; dÀ; ´ } �
} } ; ø`; waÌ { •ma; >
{ ; oJ
} ÈD
{  ; ; ; · ;

; Á ; ; ;  ; ; 
{ 
; ; €Õ; @ë ; Á; L {
; ØÈ ;
*/int m[Z];
#define U(x)s--;T=x
#define C(l,s)I(o==l){s;}E
#define Q(l,o)C(l,r=P;T=T o r)
#define O(l,o)C(l,T=o T)
#define H(l,s)C(l,U(s))
int
main(){int*q,s,f,r,o,l,p,c,b;
char*d;
d=" \t\n;{}\0AÊP€³²‰Š@ɵ�gEÏͱ°Œ0�Ž‹q";
b=256;
q=m;
g;
o=g;
c=g;
c=c+g*b;
p=c;
I(o){W(p){o=g;
C(59,r=2)C('{',r=5)C('}',r=8)r=0;
I(r){r=r+g%4;
l=1-g-r;
W(r--){*q=q[l];
q++;
p--;
}}E{I((o==32)+(o==9)+(o==10)){r=g;
o=o%4+(r+(r==123))%8*3;
I(8<o)o=o+g%4*9;
o=d[o]+b;
}*q++=o%b;
p--;
}}W(g!=12);
g;
}E{W(p--)*q++=g;
}s=Z;
p=0;
W(1){o=L;
O(17,!)O(18,-)Q(12,+)D C(10,r=T;
s=f;
p=X 1];
f=X 2];
l=X 3];
R)C(22,s++)C(27,return T)C(21,r=T;
U(r))C(23,T=m[T])C(19,T=m[T]++)C(25,T=m[T]--){l=o%16;
o=o/16;
I(l==7){l=B;
l=l+B*b;
}E I(7<l)l=l+B*8-1;
H(2,f+l)H(4,f-l-4)H(3,m[f+l])H(5,m[f-l-4])H(6,c+l)H(7,m[c+l])H(12,l)H(8,l)C(9,U(p);
p=p+l)C(11,r=X -l/2];
I(r<3){I(r)r=putchar(T);
E
r=g;
R;
}E{X 1]=p;
X 2]=f;
X 3]=l;
f=s;
s=s-19;
p=r;
})C(13,p=l)C(15,I(P)p=l)C(14,I(!P)p=l);
}}}
+231
View File
@@ -0,0 +1,231 @@
Best of Show:
Lennart Augustsson
CR&T
Stora Badhusgatan 18-20
S-411 21 Goteborg
Sweden
Judges' comments:
To use:
make august
cat august.c test.oc | ./august > test.oo
./august < test.oo
NOTE: Some compilers will compile this code into infinite loops!
If the above cat line does not execute in a very short amount
of time, then you may need to fix your compiler or use gcc.
Try:
cat august.c fac.oc | ./august > fac.oo
./august < fac.oo
Or try:
cat august.c fac.oc | ./august | ./august
And try:
cat august.c parse.oc | ./august > parse.oo
cat parse.oo fac.oc | ./august | ./august
This entry can feed on itself. If you C preprocess the source,
you compile the interpreter:
make august.oc
We can now compile the interpreter as follows:
cat august.c august.oc | ./august > august.oo
and use the compiled interpreter to execute some previously
compiled code:
cat august.oo test.oo | ./august
And we can have the compiled interpreter interpret itself which
inturn compiles the test program:
cat august.oo august.oo fac.oo | ./august
And if you have lots of spare time, you can recurse one level deeper:
cat august.oo august.oo august.oo fac.oo | ./august
We (the judges) recommend that you spend some time studying this
entry as it surely will make the 'best of the IOCCC' list. It was
very well received by those who attended the IOCCC BOF.
Selected notes from the author:
This program is a bytecode interpreter. This fact is not
particularly obfuscated; any experienced C programmer can see that
in about a minute.
The interpreter reads the bytecode from the standard input. What
remains of the standard input after this is left as standard input for
the interpreted program.
Having an interpreter but no code isn't any fun. But within a comment
in the beginning of the interpreter is a sequence of bytes that is
code that the interpreter understands. It is in fact the code for a
compiler that compiles from OC (Obfuscated C, a subset of C) into the
byte code that the interpreter understands.
The language the compiler understands is a subset of C (the grammar
is in grammar.small) with the functions getchar() and putchar()
available. The subset has the types `int', `char', and pointers to
those (it has function pointers too, but not with the proper
syntax). Arrays can only be global. There is a rather limited set
of operators, and control constructs.
The compiler has absolutely no error checking, so things
can go wrong. But this is what seasoned C progammers are used to.
Assume that the interpreter has been compiled (source in prog.c and
binary in prog) and that we have this in a file named test.oc:
main() { putchar('!'); putchar('\n'); exit(0); }
We can then compile by
cat august.c test.oc | ./august > test.oo
And run the compiled program by
./august < test.oo
Or even simpler:
cat august.c test.oc | ./august | ./august
A larger example is included fac.oc.
The compiler for OC is naturally written in OC (where did you think
the byte code came from?). It is in the file parse.oc.
Hmm... So now we have an interpreter written in OC and a compiler
for OC, can we compile the interpreter? Yes, we can! The OC
compiler does not have a preprocessor (hey, what do you expect from
a program that is this small), so we need to use an external one.
To preprocess august.c use the command from the build file, but add
the -E flag and change 60000 to 40000, i.e.:
cc -E -DZ=40000 .... august.c > prog.oc
If prog.oc contain some junk line starting with a `#' (most likely
it does) then remove it.
OK, we can now compile the interpreter:
cat august.c prog.oc | ./august > prog.oo
And we can run it:
cat prog.oo test.oo | ./august
Here we have the interpreter interpreting another interpreter that runs
the program. Did you think that was too fast? Just throw in another
level of interpretation:
cat prog.oo prog.oo test.oo | ./august
And another...
cat prog.oo prog.oo prog.oo test.oo | ./august
*****
Fitting the byte code for the compiler into the initial comment
was a challenge. I had to strip the compiler/interpreter of
a lot of functionality to bring down their sizes. The initial
version had a full set of binary operators as well as prefix &.
Given a handful more bytes it would be easy to put them back.
Anyway, the bytecode from the compiler is first optimized in
an external optimizer (not supplied here); this brings down the
size of it by about 30%. The remaining code is then LZ-compressed
(roughly) with a sliding window of 255 bytes. The most common
occuring bytes are then encoded using " \n\t;{}" to avoid having
them counted as significant. About 200 bytes of the interpreter
handles the unpacking of the byte code (this is a lot, but it pays
off).
Despite all this work I still had to put a lot of code in the
compilation command. This disturbs me. It is possible to compress
the code further with a better entropy coder (e.g. an arithmetic
coder), but decompression then takes up too much code. Maybe this
would be a way to fit it all into the 1536 bytes, but I'm don't have
time to try it.
*****
Execution starts at main(). Nothing can be used before it is
defined. getchar() and putchar() are predefined functions.
The following is a description of the OC grammar:
OC grammar
==========
Terminals are in quotes, () is used for bracketing.
program: decl*
decl: vardecl
fundecl
vardecl: type NAME ;
type NAME "[" INT "]" ;
fundecl: type NAME "(" args ")" "{" body "}"
args: /*empty*/
( arg "," )* arg
arg: type NAME
body: vardecl* stmt*
stmt: ifstmt
whilestmt
dowhilestmt
"return" expr ";"
expr ";"
"{" stmt* "}"
";"
ifstmt: "if" "(" expr ")" stmt
"if" "(" expr ")" stmt "else" stmt
whilestmt: "while" "(" expr ")" stmt
dowhilestmt: "do" stmt "while" "(" expr ")" ";"
expr: expr binop expr
unop expr
expr "[" expr "]"
"(" expr ")"
expr "(" exprs ")"
NAME
INT
CHAR
STRING
exprs: /*empty*/
(expr ",")* expr
binop: "+" | "-" | "*" | "/" | "%" |
"=" |
"<" | "==" | "!="
unop: "!" | "-" | "*"
type: "int" stars
"char" stars
stars: "*"*
*****
Well, that is enough ranting for now.
+321
View File
@@ -0,0 +1,321 @@
/*T } ¶ ;
ˆ
;

;
}
{ 
{ ;  ;
; 1 {
è { !
} {
; é ;
;
{

{ ]- } ; ; |
í ; Q
;
´ë ; ; ; "û }
} Ü; ; -ýl
}
} t dÀ ;
; +
t2 { ì ;
} 1; C
i
; = } ; ;

;
ì ; {
{ ê
} { � { ï } }
; . {
␍ { é } } ; 
{ ;
; /nÈ; 5
} ; Ú␍{ ; 
; { 1 ; } ; ¨ý } {
;  { ; . { ;  } ;  ;
; T ;
{
; ; Ä; ;  {
;
 { { ; ;
ì; ‘ ; ; ï; n!t }
; ì!; G; t;  ø; ¤ }  ;
;
} ; "; è# }
; 
{
; �$ {
;
; &
; d˜
{
¶;  {
; Sé'
{ d; ; è); �c
{
;  ;
; &ï*; ␍ ;
— {
;
$; ¢; ,; ; $ˆd } —; ˆ; ë/Î; Î
; a; Í ; {
} ; j; #è1;
 }
; Ä ; { ê5a; û␍ Ät { ï4a }
}
; £ ;
Û2; -
; 8
} ; }
; è8; ;  Ú6Q ; aÌ { ;  { ˆ
ì }
†; v:
{
?
}
{ ?
{ ; 4r
;
; v=b; Û
;
;
} ; 
; ; ; Þ { ú>
} }
{  ;
{ Õ`
}
;
;
!;
; 1; ; >; Ì } 1; X
; } p ;
;
; ; ; 
; ; 2 } ; vm
2; ;1íJ
;
; ; Ï }
; ÉJc; ›; d }
} ÞG; i }
; ; §F
{ vl¶þV; z
n
¶éOc; s
; ; ÑÞ;
 uh¶ëR } hRs; A cl,;
; ; Z;  {
x
lw¶êUch�{  }
} ; àîVc }
; Ž; >ÈD
; G ; ; †
;
îX; ’ˆ
;
; 2 }  { é[; 
{  }
; Þj; å; ë_; ␍y
; D; T; ; ?j; .n; ; ã {
; Ú]; !; Ë; 0a
} J ;
; ^; .
{ { { îc; ␍X ; ; ´;
J {
; ;
 } — { êf; 
; {
; ; : } { 
{
; (h} ␍ }
{  }
} ; ; { 
; ûD; Tì Cr; ␍; I; WèsÎWQ
; ;
×; W { û }
; ( ; ; }
} ;  {
; ÿn{ k; © ; ‚; ?; %Ùk;  ;
{ ïv;
3{ (; h {
; ; z
; ; ]{ ; ˜ïx; S; { * } ˜; z} ; î; 
{ ; ~
;
U; ö
; { ‡
; í~;
Ob } ; ò; UU; U{ -{ %Ú|1èƒ;
; Q
;
µ{ w{ š;  ;
 { í‡; ‚; ü�
…
} Ù†; ?; u
{
ƒ
} } ; » ; ´ ; ;  }
; è
{
; ;  }
; p ; ; ; Q; Ü�{ ; ; K; $ì“
p; 1}
4; $;
2Q ; }  {
; $î— } ; #;
T; 1
; ; +; ± } 
; ;
. ; { 
{ ; š{
  ;
{
; ;  }
; { [ { ; £{ ; �; 0{ 
{ ôr ; éŸ
;
} =; w
?; ;
ä; B®lwx
; h�h
} ; pj
; ; ; ö { û§; 'n
; ; { ) {
; ú¤;
;
Q
; f; 'r
{
? { ë¬; %lÂf}
; ~©{ qÛ¨; 
{
 { ÿ­; ÂÛ¬{ œÚžl,u
; & ;
{ í; G } 
; k
;  }
; 
{
; hR; ; Wß´; 
} ;
; ; —e; Z; ž{ N; =
} ; <
{ ]- Bšretur; ¡if
else
whil; do; nt
char
{ ; { pu{  }
{ ; =
} B
} {
; ø¿`ˆ; dÀ; ´ } �
} } ; ø`; waÌ { •ma; >
{ ; oJ
} ÈD
{  ; ; ; · ;

; Á ; ; ;  ; ; 
{ 
; ; €Õ; @ë ; Á; L {
; ØÈ ;
*/int m[Z];
#define U(x)s--;T=x
#define C(l,s)I(o==l){s;}E
#define Q(l,o)C(l,r=P;T=T o r)
#define O(l,o)C(l,T=o T)
#define H(l,s)C(l,U(s))
int
main(){int*q,s,f,r,o,l,p,c,b;
char*d;
d=" \t\n;{}\0AÊP€³²‰Š@ɵ�gEÏͱ°Œ0�Ž‹q";
b=256;
q=m;
g;
o=g;
c=g;
c=c+g*b;
p=c;
I(o){W(p){o=g;
C(59,r=2)C('{',r=5)C('}',r=8)r=0;
I(r){r=r+g%4;
l=1-g-r;
W(r--){*q=q[l];
q++;
p--;
}}E{I((o==32)+(o==9)+(o==10)){r=g;
o=o%4+(r+(r==123))%8*3;
I(8<o)o=o+g%4*9;
o=d[o]+b;
}*q++=o%b;
p--;
}}W(g!=12);
g;
}E{W(p--)*q++=g;
}s=Z;
p=0;
W(1){o=L;
O(17,!)O(18,-)Q(12,+)D C(10,r=T;
s=f;
p=X 1];
f=X 2];
l=X 3];
R)C(22,s++)C(27,return T)C(21,r=T;
U(r))C(23,T=m[T])C(19,T=m[T]++)C(25,T=m[T]--){l=o%16;
o=o/16;
I(l==7){l=B;
l=l+B*b;
}E I(7<l)l=l+B*8-1;
H(2,f+l)H(4,f-l-4)H(3,m[f+l])H(5,m[f-l-4])H(6,c+l)H(7,m[c+l])H(12,l)H(8,l)C(9,U(p);
p=p+l)C(11,r=X-l/2];
I(r<3){I(r)r=putchar(T);
E
r=g;
R;
}E{X 1]=p;
X 2]=f;
X 3]=l;
f=s;
s=s-19;
p=r;
})C(13,p=l)C(15,I(P)p=l)C(14,I(!P)p=l);
}}}
+28
View File
@@ -0,0 +1,28 @@
#!/bin/sh
./westley \
"%%%&&&'''666EEESSSaaannn{{{zzzyyyxxxwwwhhhYYYKKK===000###\$\$\$" \
"34CQ_lkj[M?234CQ_lkj[M?2" \
" .*" \
"
-<<==O==>>-
--====v====--
| |
| |
| |
| 0 |
| |
| |
| |
=============
\\ /
\\ /
| |
| | |
| | |
| | |
| | |
| O |
| |
)-----------(
| |
============="
+18
View File
@@ -0,0 +1,18 @@
#!/bin/sh
./westley \
"%%%\$\$\$###000===KKKYYYhhhwwwxxxyyyzzz{{{nnnaaaSSSEEE666'''&&&" \
"32?M[jkl_QC432?M[jkl_QC4" \
" xX" \
"
)-=*=-(
--===-=-===--
) (
| |
| |
| 0 |
| |
| |
) (
]]==-----==[[
) | (
-----------"
+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
./westley \
"123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_\`abcdefghijkl" \
"/\$%&'()*+,-./\$%&'()*+,-." \
" ||" \
"
..3..6..9..12 Hours
----.----10---.----20---.----30---.----40---.----50---.---- Minutes
"
+19
View File
@@ -0,0 +1,19 @@
#include<stdlib.h>
#include<stdio.h>
main(I,O,O0,OO,l)
int I,O0,OO,l;
char **O;
{
return !!I>=I?!I>=I?!!~I>=~I?!~I>=~I?!OO?!I:OO%2?
OO=main(I,O,O0,OO>>!!OO,l),
OO=main(I-!I-!!I,O,OO,OO,l),
OO=main(I-!I-!!I,O,O0,OO,l),
!(OO-!I||I)?l-1:OO
:(OO=main(I,O,O0,OO>>!!OO,l),
!(OO-l+!I||I)?l-1:main(I-!I-!!I,O,OO,OO,l))
:(O0+OO)%l
:main(I-I/I-I/I,O,O0,OO+OO/OO,
main(0,O,O0,OO,I-I-I)+I+1?1:printf("%d ",I-I-I)+fflush(stdout))
:main(I-I-I-I-I,O,I+I-I+I,I,0)
:main(~!!I-!!I,O,atoi(1[O]),1,atoi(0[O]));
}
+67
View File
@@ -0,0 +1,67 @@
Best Numerical Obfuscation:
John Dalbec
20 Squire's Ct. (home address)
Canfield, OH 44406
USA
http://www.math.yale.edu/pub/users/dalbec/
Judges' comments:
To use:
make dalbec
./dalbec
The output is mis-leading ... why does it also print 2047?
Also try:
./dalbec 3
why does it output 121?
For a hint see:
http://www.utm.edu/research/primes/prove2.html#sprp
and then try to understand the source! :-)
We (the judges) recommend that you take the time needed to understand
how this program works. The source is small enough to make the effort
reasonable, and complex enough to make it interesting.
Selected notes from the author:
This program assumes that your terminal wraps lines automatically.
If this is not the case, you may need to change the space in the
"printf" format string to a newline character.
An extra feature of this program is that it allows you (in most
cases) to estimate the stack space available to programs on your
system. Simply allow the program to run to completion. The stack
space is roughly proportional to the last number printed.
(On SunOS/cc, the proportionality constant is about 48 bytes.)
On completion, the program produces a core file that may be used to
refine this estimate. (Or you could try typing "limit" if you're
running csh.) In rare cases the stack space may exceed 24*MAXINT
bytes, in which case the program will produce an inaccurate estimate.
This program is obfuscated:
(1) by the use of easily-confused variable names
(2) by using the implicit !=0 in conditional expressions
(3) by substituting expressions such as !a for 0 where a!=0
and !a for 1 where a==0
(4) by the fact that main() is a single expression and so beautifies poorly
(5) by the fact that main() is used
(a) to compute powers in modular arithmetic
(b) to recursively call itself in the main loop
+8
View File
@@ -0,0 +1,8 @@
float s=1944,x[5],y[5],z[5],r[5],j,h,a,b,d,e;int i=33,c,l,f=1;int g(){return f=
(f*6478+1)%65346;}m(){x[i]=g()-l;y[i]=(g()-l)/4;r[i]=g()>>4;}main(){char t[1948
]=" `MYmtw%FFlj%Jqig~%`jqig~Etsqnsj3stb",*p=t+3,*k="3tjlq9TX";l=s*20;while(i<s)
p[i++]='\n'+5;for(i=0;i<5;i++)z[i]=(i?z[i-1]:0)+l/3+!m();while(1){for(c=33;c<s;
c++){c+=!((c+1)%81);j=c/s-.5;h=c%81/40.0-1;p[c]=37;for(i=4;i+1;i--)if((b=(a=h*x
[i]+j*y[i]+z[i])*a-(d=1+j*j+h*h)*(-r[i]*r[i]+x[i]*x[i]+y[i]*y[i]+z[i]*z[i]))>0)
{for(e=b;e*e>b*1.01||e*e<b*.99;e-=.5*(e*e-b)/e);p[c]=k[(int)(8*e/d/r[i])];}}for
(i=4;i+1;z[i]-=s/2,i--)z[i]=z[i]<0?l*2+!m():z[i];while(i<s)putchar(t[i++]-5);}}
+24
View File
@@ -0,0 +1,24 @@
Best Output:
Thor AAge Eldby
European Technology Partner
Roedtvetvn 20 (Home address)
0955 OSLO
Norway
Judges' comments:
To use:
make eldby
./eldby
We were impressed by the author's ability to render spheres in 3D
in a very small chunk of code.
Selected notes from the author:
This program shows flying spheres. The program eats CPU on lesser
equipt systems. The program will run until termination. Terminal
must be vt100 or better with 80 columns and 24 rows or more.
+1
View File
@@ -0,0 +1 @@
extern int errno;
+44
View File
@@ -0,0 +1,44 @@
/* A factorial program */
int
putstr(char *s)
{
while(*s)
putchar(*s++);
}
int
fac(int n)
{
if (n == 0)
return 1;
else
return n*fac(n-1);
}
int
putn(int n)
{
if (9 < n)
putn(n / 10);
putchar((n%10) + '0');
}
int
facpr(int n)
{
putstr("factorial ");
putn(n);
putstr(" = ");
putn(fac(n));
putstr("\n");
}
int
main()
{
int i;
i = 0;
while(i < 10)
facpr(i++);
return 0;
}
+59
View File
@@ -0,0 +1,59 @@
#define fine #define de #define/**/ /**/*#define*/
#define de #define
#define do de
do { begin
do you like (green eggs and ham++)?
do you eat them: in a box?
do you eat them with a fox?0
do } end
fine
fine, just fine.
/*@@@@@@@@@@@@=___
/@@@@@@@@@@@@@@@@@@@a
@@@@@@@@@@@@@@@@@@@@@
|@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@
\@=~ ~~@@@/
\ /
\ |
/@@@@@===__ |
@@@@@@@@@@@@==/
/@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@
/ ~~~====@@@@@@
/ ~~~/
| /
/____ |
@@@@@@@@=====__/
@@@@@@@@@@@@@@@@
/@@@@@@@@@@@@@@@
/@@@@@@@@@@@@@@@|
___/ ~~~~@@*/
char groo(p,q)int p;int q;{return
((char) (--q*q+ (p/10)*q+--p))
; }void grem /**/ (){ int x=0
; printf(" ")
;/**/ /**/ for(;x<16
; x++)printf
( "%c",groo(x
, 8)) ;printf
( "\n\n")
; }void cred(a
) int a;{int
x=0;printf
( "%c "
, /*_____===~*/ groo(a,8))
; for(;x<16
; x++)printf
( "%c",(char)
a*16+ x);printf(
"\n");}main(a
,b)int a;
char **b ;{int x=2;
do(x=0;x<4;x++)exit(0);
for(grem();x<1<<3+(int)b[0]
[0]%2;)cred (++x-1);}
+50
View File
@@ -0,0 +1,50 @@
Best Layout:
Dean Swift
Trinome Communications
7, Jeffries Passage
Guildford
Surrey
GU1 4AP
England
http://www.tc3.co.uk/~gandalf/G.HTML
Judges' comments:
To use:
make gandalf
./gandalf
Also try:
For C-shell:
setenv PATH ( . $PATH )
hatcat
cathat
For K-shell, /bin/sh, bash, etc:
PATH=.:$PATH
hatcat
cathat
And next try:
./cathat
`pwd`/cathat # <--- those are back quotes
Care to guess why these execute differently? Only the
compiler knows ... ok maybe other things like the author,
the judges and maybe you too?
For mis-leading C pre-processor output, try:
cc -E gandalf.c
Selected notes from the author:
The program requires an ASCII system.
+778
View File
@@ -0,0 +1,778 @@
13th International Obfuscated C Code Contest Guidelines, Hints and Comments
Copyright (c) Landon Curt Noll, Larry Bassel and Sriram Srinivasan, 1996.
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 1995 rules are denoted by change bars. ---> |
Not every change is marked in this file is marked, but
most are. :-)
WHAT IS NEW IN 1996:
A number of small rules changes were made. See rule #3. |
We clarified what is a legal title by using a stronger regexp. |
We expanded on the value of the --remark--- section in the |
guidelines below. |
We now ask for an author's home page URL in the --entry-- section. |
We declared that use of local funcions are not allowed this year due |
to the lack of portability. |
Windows 95 (see Dislikes). This is not really new but we like to |
say it anyway. |
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. For example, using gcc |
local function declarations, such as: |
void main() { |
void blah() { printf("blah\n"); } |
blah(); |
} |
are not allowed even though their existence seems tailor made for |
this contest! But for now, since they are not in wide spread use |
we cannot accept entries that use them. |
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.
You are better off explaining what your entry does in the |
---remark--- section rather than leaving it obscure for the judges |
as we might miss something and/or be too tired to notice. |
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. We do read |
the ---remark--- section during the judging process, so it is worth |
your while to write a remarkable ---remark--- section. |
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: 1996-1
fix: y
title: chonglabram
entry: 0
date: Mon Oct 28 00:47:00 1996
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 1996-1 because 1996'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
url: http:///www.isthe.com/chongo/index.html
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
url: none
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
url: none |
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.
Please note that the title must match the following regexp: |
^[a-zA-Z0-9_=][a-zA-Z0-9_=+-]*$ |
and must be 1 to 12 chars in length. Titles such as: |
foo.c |
this is my invalid title name |
/dev/null |
are right out! :-) |
It is suggested, but not required, that the title should incorporate |
the author(s) username(s). |
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:
Mon Oct 28 00:47:00 1996
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 resubmission 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://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
+49
View File
@@ -0,0 +1,49 @@
#define x char
#define z else
#define w gets
#define r if
#define u int
#define s main
#define v putchar
#define y while
#define t " A?B?K?L?CIF?MSP?E?H?O?R?DJG?NTQ?????U?V?????X???????Z????W??Y??"
s ( ) { x* c , b[ 5 * 72 ]; u a, e , d [ 9
*9 *9 ] ; y (w ( b) ){ r ( 0 [ b] -7 *
5 ) { c = b ; y ( (* c - 6
* 7 )* * c )c = c+ 1 ; r (( -0 ) [ c ] && w ( b +
8 * 5* 3 ) && w (b +8 *5 * 6) )
{ a = 0; y ( a [ b ]
) { a [ d ] = ! ! ( a[ b] - 4 *8 ) ; a = a +
1; } y (a < 8 * 5 * 3 ) d [ ( a ++ )
] = 0 ; a = 0; y( b [
a + 8 *3 * 5 ] ) { d [ a ] = a [ d] + ! !( b[
a+ 40 * 3 ] -4 * 8) * 2 ; ++ a ; } a =
0 ; y ( a [ b + 6 * 40 ]
) {a [d ] += ! ! ( b[ a + 5 * 6 * 8 ] - 4 *
8 ) * 4; a = a + 1 ;} a= 0; y (a <3 *8
*5 ) { r ( a [ d ] ) { e
= 1 ; y ( e[ a + d] ){ * ( d+ a+ e ) = a[ d
+e - 1] +( d [ a + e ] << ( 3* e) ) ;e
= e + 1 ;} a = a +
e - 1 ; v( !! ( * ( d+
a) % ( 64 ) - 12 * 5
) + ( e
> 4 ) ?t [ e >2 ? 2 :a [ d ] ] :6 * 8 +( t [ d[
a ]/ 8 /8 ] -4 ) %( 10 ) ) ; r( ! (2 [a
+ d] + 3 [d + a ] ) ) v ( 4 * 8 )
; } a = a + 1 ; } v (5 * 2 ) ; } z {c =b ; e
= 0 ; y (* c ) { * c += - (* c > 8 * 12
) * 32 ; a = 8 * 8 ; r (* c
>= 48 &&* c<8 *8 -6) {*c =( * c + 1
) %( 5 * 2 ) + 65 ;y( --a >0 &&*
c- a[ t] ); d[ (e ++ )] =4 ;(
* ( d + (e ++) ))= 07 ;}z y(a -- >1
&&* c- t[a ]); d[ ( e = e + 1) -
1] =a %8 ;y (a /= 8) d[ (e ++
) ] = a% 8 ; ++ c ; * ( e ++ +d ) =0
;} -- e ;r ( e >0 ) {a = 1 ;
y ( a< 8 ) { c = b ;y
( c <e +b ) { v ( * ( c - b + d )& a? 6 *7
:8 * 4 ) ; c ++ ;} a= a + a ; v ( 2*
5) ; } v ( 5* 2 ) ; }} }} }
+48
View File
@@ -0,0 +1,48 @@
Best Obfuscated Character Set Utility:
Ken Huffman
Applied Innovation Inc
5800 Innovation Dr.
Dublin, OH 43016
USA
<http://www.huffmancoding.com>
huffmancoding@gmail.com
Judges' comments:
To use:
make huffman
echo 'Huffman Decoding' | ./huffman
Try:
echo 'seeing or feeling is believing' | ./huffman
echo 'CC OR NOT CC' | ./huffman | ./huffman
If you are still confused and want to read a spoiler, check out
the source and it will be clear as mud!
And for a misleading hint, consider who won! :-)
And if you really can't see what is going on, here is an extra spoiler:
./huffman < huffman.c
This entry was very well received at the IOCCC BOF.
Selected notes from the author:
This filter program is really not obfuscated code. It compiles cleanly
with an ANSI C compiler and comes with user documentation that even a
blind person could read.
The program is a bi-directional filter with the output of the program
suitable for its input. The output of this program, when used as input,
undoes the original program filtering.
This program accepts any alphanumeric text that has lines less than 100
characters. The user is encouraged to use the program's source as input
to the executable.
This program is best appreciated on a tactile monitor.
+18
View File
@@ -0,0 +1,18 @@
#define O B F U S C A T E D
#define I 8;}t(p){r(p?W:o);XClearWindow(V,m);}main(i,f)char**f;{M((T(h=f),
#define K Y(o,XMapRaised(V,e);)x=3;x--;)for(y=3;y--;r(G))XMapRaised(V,R[D]
#define N z(x+i,(z(H-x-i,x),x)))x<i||z(x-i,x)|z(H-x+i,x)Y(W,)l=k;l>20&&l>x
#define XIMOfIC Z;XID(*w)()=XCreateWindow,m,e,o[2],W[2],G[2],R[2][O]);}GC*g
#define E (++D)));}r(XID*z){XSetWindowBackgroundPixmap(V=d[D],m=R[D][x][y],z[
#define L ;XStoreName(V,e=w(V,RootWindow(V,s),0,0,152,152,2,0,1,0,0,0),"II"+D
#define B 3][3];Display*V,*d[2];char**h,k=25,b[2500],H=50,D,s,x,y,i;T(){float
#define S +k),z(k-P=w(V,e,H*x,H*y,H,H,1,0,1,0,2048,&c));}XEvent J;M(){XFlush(
#define Y(z,y) ;for(z[D]=XCreatePixmapFromBitmapData(Q,x=0,H*H);x<H;x++)y for(
#define A x][y]&&!b[x+k*y]++?t(D),t(!(D^=1)):D);M();}z(x,y){b[x/8+y*7]|=1<<x%I
#define P x,y)-z(y,x+k)+z(y,k-x)*z(x+k,y=H-y),z(k-x,y),z(y,k-x),z(y,k+x)K[x][y]
#define Q V,e,b,H,H,BlackPixel(V,s),WhitePixel(V,s),DefaultDepth(V,s)),memset(b
#define C d[!D]);x=3;for(XNextEvent(V,&J);x--;)for(y=3;y--;J.xany.window==R[D][
#define F l;XSetWindowAttributes c;s=XDefaultScreen(V=d[D]=XOpenDisplay(*(h+=!!
#define U *h)))L)Y(G,)i=c.event_mask=4;i--;x+i>H||N;l-=.5)z(x+k,y=sqrt(l*l-x*x)
#include <math.h>
#include <X11/Xlib.h>
+45
View File
@@ -0,0 +1,45 @@
Best X11 Entry:
Jon Thingvold
University of Oslo
Gaustadveien 10B
N 0372 Oslo
Norway
http://www.uio.no/~jonth/
Judges' comments:
To use:
make jonth
./jonth
Also try:
./jonth host1:0 host2:0
NOTE: You may need to change the Makefile depending on where X11
include files are found and what libs are required. For
example Solaris and Slowlaris need -lsocket. :-)
For extra credit, figure out how you can cheat by taking over
a square already occupied by an opponent.
Selected notes from the author:
This is mulituser tictactoe for X Windows. You may give one or two X
displays as arguments to this game.
Known bugs:
Sometimes on Solaris X gets confused and this program core dumps,
solution: give two display arguments (prog host:0 host:0)
If one (or both) windows look like a copy of the window(s) below,
try xrefresh command.
Have a nice(1) day.
+1226
View File
File diff suppressed because it is too large. Load diff
+463
View File
@@ -0,0 +1,463 @@
int curloc;
int lexval;
int token;
int pusharg;
int thechar;
int nglob;
int nlocal;
int nfun;
int strsize;
int narg;
int curgloboffs;
int nsym;
int pushop;
int argids[50 ];
int globids[300 ];
int globoffs[300 ];
int globscalar[300 ];
int funids[300 ];
int funoffs[300 ];
int localids[50 ];
char symbol[5000 ];
char code[5000 ];
char names[5000 ];
int
digit(int c)
{
return (( '/' < c ) * ( c < ':' )) ;
}
int
letter(int c)
{
return (( '`' < c ) * ( c < '{' ))
;
}
int
eqstr(char *p, char *q)
{
while(*p) {
if (*p++ != *q++)
return 0;
}
return !*q;
}
int
lookup(char *name)
{
int i;
char *ns;
ns = names;
i = 0;
while(i < nsym) {
if (eqstr(ns, name)) {
return i;
}
while(*ns++)
;
i++;
}
while(*ns++ = *name++)
;
return nsym++;
}
int
next()
{
int r;
r = thechar;
thechar = getchar();
return r;
}
int
gobble(int t, int rr, int r)
{
if (thechar == t) {
next();
return rr;
}
return r;
}
int
getstring(int delim)
{
int c;
strsize = 0;
while((c = next()) != delim) {
if (c == '\\') {
if ( (c = next()) == 'n') c = '\n';
if (c == 't') c = '\t';
if (c == '0') c = 0;
}
symbol[strsize++] = c;
}
symbol[strsize++] = 0;
}
int
getlex()
{
int c;
char *p;
while( (( 0 < (c = next()) ) * ( c < '!' )) )
;
if ((( c == -1 ) + (
(( c == '(' ) + (
(( c == ')' ) + (
(( c == '[' ) + (
(( c == ']' ) + (
(( c == '{' ) + (
(( c == '}' ) + (
(( c == ',' ) + (
c == ';' )) )) )) )) )) )) )) )) )
return c;
if (c == '/') {
if (thechar == '*') {
while((( next() != '*' ) + ( thechar != '/' )) )
;
next();
return getlex();
} else
return 1115 ;
}
if (c == '*') return 1114 ;
if (c == '%') return 1116 ;
if (c == '-')
return gobble(c,1225 ,1013 );
if (c == '<')
return 808 ;
if (c == '=')
return gobble(c,806 ,101 );
if (c == '+')
return gobble(c,1219 ,1012 );
if (c == '!')
return gobble('=',807 ,1217 );
if (c == '\'') {
getstring(c);
lexval = symbol[0];
return 257 ;
}
if (c == '"') {
getstring(c);
return 258 ;
}
if (digit(c)) {
lexval = c - '0';
while(digit(thechar)) {
lexval = lexval * 10 + next() - '0';
}
return 257 ;
}
p = symbol;
*p++ = c;
while(letter(thechar))
*p++ = next();
*p = 0;
if ( (lexval = lookup(symbol)) < 7 ) {
if (lexval == 6 )
return 517 ;
return lexval + 512 ;
}
return 256 ;
}
int
istoken(int t)
{
if (token == t) {
token = getlex();
return 1;
}
return 0;
}
int
type()
{
istoken( 517 ) ;
while(istoken(1114 ))
;
}
int
name()
{
int r;
r = lexval;
token = getlex();
return r;
}
int
emit(int opc)
{
code[curloc++] = opc;
}
int
emitat(int a, int c)
{
code[a++] = c;
code[a] = c/256;
}
int
emitop(int rator, int rand)
{
int r;
emit(rator+ 7 );
r = curloc;
emit(rand);
emit(rand/256);
return r;
}
int
pushloop(int puop, int max, int *arr)
{
int i;
i = 0;
pushop = puop;
while (i < max) {
if (arr[i] == lexval) {
pusharg = i;
return 1;
}
i++;
}
return 0;
}
int
pushval()
{
int lval;
lval = 1;
if (pushloop(64 , nlocal, localids)) {
} else if (pushloop(32 , narg, argids)) {
pusharg = narg-pusharg-1;
} else if (pushloop(96 , nglob, globids)) {
lval = globscalar[pusharg];
pusharg = globoffs[pusharg];
} else {
lval = 0;
if (pushloop(192 , nfun, funids)) {
pusharg = funoffs[pusharg];
} else if (lexval < 9 ) {
pusharg = lexval- 7 ;
}
}
emitop(pushop, pusharg);
return lval;
}
int
pderef(int l)
{
if (l)
emit(23 );
}
int
expr(int needval, int prec)
{
int na;
int islval;
int jdst;
int op;
int any;
int opprec;
islval = 0;
if (istoken(257 )) {
emitop(128 , lexval);
} else if (istoken(258 )) {
emitop(144 , strsize);
any = 0;
while(any < strsize)
emit(symbol[any++]);
} else if (istoken(256 )) {
islval = pushval();
} else if (istoken('(')) {
islval = expr(0, 0 );
istoken( ')' ) ;
} else if (istoken(1217 )) {
expr(1, 100 );
emit(17 );
} else if (istoken(1013 )) {
expr(1, 100 );
emit(18 );
} else if (istoken(1114 )) {
expr(1, 100 );
islval = 1;
}
any = 1;
while(any) {
op = token % 100 ;
if (istoken('(')) {
pderef(islval);
na = 0;
if (!istoken(')')) {
do {
expr(1, 0 );
na++;
} while(istoken(','));
istoken( ')' ) ;
}
emitop(176 , na*2);
islval = 0;
} else if (istoken('[')) {
pderef(islval);
expr(1, 0 );
emit(12 );
istoken( ']' ) ;
islval = 1;
} else if (istoken(1219 )) {
emit(op);
islval = 0;
} else if (istoken(1225 )) {
emit(op);
islval = 0;
} else
any = 0;
}
opprec = token / 100 ;
while (prec < opprec) {
if ( (op = token % 100 ) != 1 ) {
pderef(islval);
}
{
token = getlex();
expr(1, opprec);
emit(op);
}
islval = 0;
opprec = token / 100 ;
}
if (needval) {
pderef(islval);
islval = 0;
}
return islval;
}
int
pexpr()
{
istoken( '(' ) ;
expr(1, 0 );
istoken( ')' ) ;
}
int
stmt()
{
int jdest;
int tst;
if (istoken('{')) {
while(!istoken('}'))
stmt();
} else if (istoken(513 )) {
pexpr();
jdest = emitop (224 , 0);
stmt();
if (istoken(514 )) {
tst = emitop (208 , 0);
emitat(jdest, curloc);
stmt();
emitat(tst, curloc);
} else {
emitat(jdest, curloc);
}
} else if (istoken(515 )) {
tst = curloc;
pexpr();
jdest = emitop (224 , 0);
stmt();
emitop (208 , tst);
emitat(jdest, curloc);
} else if (istoken(516 )) {
jdest = curloc;
stmt();
istoken( 515 ) ;
pexpr();
emit(17 );
emitop (224 , jdest);
} else if (istoken(512 )) {
expr(1, 0 );
istoken( ';' ) ;
emit(10 );
} else if (istoken(';')) {
} else {
expr(1, 0 );
emit(22 );
istoken( ';' ) ;
}
}
int
parse()
{
int objid;
token = getlex();
while(1) {
if (token < 0)
return 1;
type();
objid = name();
if (istoken('(')) {
funids[nfun] = objid;
funoffs[nfun++] = curloc;
narg = 0;
if (!istoken(')')) {
do {
type();
argids[narg++] = name();
} while(istoken(','));
istoken( ')' ) ;
}
istoken( '{' ) ;
nlocal = 0;
while(token == 517 ) {
type();
do {
localids[nlocal++] = name();
} while (istoken(','));
istoken( ';' ) ;
}
while(!istoken('}'))
stmt();
emit(10 );
} else {
globoffs[nglob] = curgloboffs;
if (istoken('[')) {
istoken( 257 ) ;
curgloboffs = curgloboffs + lexval;
istoken( ']' ) ;
globscalar[nglob] = 0;
} else {
curgloboffs++;
globscalar[nglob] = 1;
}
globids[nglob++] = objid;
istoken( ';' ) ;
}
}
}
int
main(
)
{
int n;
char *p;
char *q;
nsym = 9 ;
p = names;
q = "return\0if\0else\0while\0do\0int\0char\0getchar\0putchar" ;
n = 48 ;
do
*p++ = *q++;
while(n--);
curloc = 7;
thechar = getchar();
parse();
n = curloc;
curloc = 0;
lexval = lookup("main");
pushval();
emitop(176 , 0);
emit(27 );
putchar(0);
putchar(0);
putchar(n);
putchar(n/256);
p = code;
while(n--) {
putchar(*p++);
}
return 0;
}
+119
View File
@@ -0,0 +1,119 @@
#include T
#include Y
H W[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }
,u[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
59, 67, 83, 99, 115, 131, 163, 195, 227, 258 } ,P[] = { A A 1, 1, 1, 1, 2,
2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 } ,Q[] = { 1, 2, 3, 4, 5, 7, 9,
13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049,
3073, 4097, 6145, 8193, 12289, 16385, 24577 } ,L[] = { A 1, 1, 2, 2, 3, 3,
4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 }, y, C, t,
Z[320], b[17], G[17]; H long j; H char S[K]; n { n *o, *O; H l; } F, *V, *h,
*I, **e;
H U H l, H O)
{
H w = 0, o, f, q; J !O) { ; {
U 24, 1); o = U 8, 1); U 24, 1); U 24, 1); {
J o & 4) { ; X q = U 16, 1); q--; U 8, 1)); } ; {
X; o & 8 && U 8, 1); ) { ; ;
}
}
X; o & 16 && U 8, 1); );
o & 2 && U 16, 1);
}
X o = 0; !o; ) { ;
{
o = U 1, 1); q = U 2, 1); J
q || U 8, 7)) { ; { ; { ; } ; ; ;
q & 1 && U 7, 8);
q & 2 && U 3, 9); U 5, 6);
I = V; U 2, 4); I = h; U 9, 4); } ; }
} ; ; { ; } ; { ; } ; { ; } ; { ; }
}
X; (C M) != (t M); N (C++[S])); } ; }
s 6)
{
; { ; { ; } X; (O = U 6, (I = V, 3) )) != 256; )
J O > 256 || (U O, 2), 0)) { ; {
O -= 257; l = u[O] + U P[O], 1);
I = h; O = U 5, 3); O = Q[O] + U L[O], 1);
O = O <= t ?
t - O : K - O + t; X; l--; O M) U S[O++], 2) ; } ; }
}
;} s 3) {
; { X; I->o; I = U 1, 1) ? I->O : I->o); w = I->l; } ;
} s 5) { ; { X O = 17; O--; O[b] =
0); X O++; O < l;
O++[Z][b]++);
X *b = *G = O = 0 ; O < 16; O++) { ; {
G[O+1] = (O[G] + b[O]) << 1; ; }
}
X I = 0, O = 0; O < l; O++) J Z[O]) { ;
{
X e = (q = O[Z][G], Z[O][G]++,
o = Z[O], &I); o-- && (*e || ((*(*e = R) = F), 1));
e = ((q >> o) & 1) ? &(*e)->O : &(*e)->o);
*(*e = R)
= F; (*e)->l = O; } ; } } ; } s 2) { ; {
t++[S] = l; (t M) == (C M)
&& N (C++[S]); } ; } s 8) { ; {
X O = 288; O--; Z[O] = O < 144 ? 8
: O < 256 ? 9 : O < 280 ? 7 : 8); V = (U 288, 5),
I); { ; { X O = 32; O--;
Z[O] = 5);
}
}
h = (U 32, 5), I); } ; } s 1 && l)
{
; { { ; } ; { ; } ; { ; } ; { ; }
X; y < l; y += 8)
j |= 0l + D << y; w = j
& (1 << l) - 1;
j >>= l; y -= l; } ; } s 7) { ; { y % 8 && U y % 8, 1);
X O = U 16, 1), U 16, 1); O--; U U 8, 1), 2));
} ;
}
s 9) { ; {
H p = U 5, 1) + 257, z = U 5, 1) + 1, v = U 4,
1) + 4; { X O = 0; O < v; O++[W][Z] = U 3, 1));
X; 19 > O; W[O++][Z] = 0); { ;
}
}
V = (U 19, 5), I);
{
X l = O = 0; O < (p + z); ) {
I = V; o = U 3, 3); f = o == 16
? (o = l), 3 + U 2, 1) : o == 17 ?
(o = 0), 3 + U 3, 1) : o == 18 ? (o = 0),
11 + U 7, 1) : ((l = o), 1); X q = f; q--;
O++[Z] = o); ; ; ; ; ; { ; }
}
I = V;
{
U 9, 4); }
V = (U p, 5), I);
X O = z; O--;
Z[O] = Z[O+p]);
h = (U z, 5),
I); } ; ; ; } ; ; ; } s
4) { ; ; ; { n *
i = I; i && (
I = i->o, U 7, 4),
I = i->O,
free (i), U 1, 4));
} ; }
return w;
}
main ()
{
return B (3, 0);
}
+69
View File
@@ -0,0 +1,69 @@
Best RFC Obfuscation:
Ron McFarland
7941 Fawncreek Drive
Cincinnati, Ohio 45249
USA
Judges' comments:
To use:
make rcm
./rcm < rfc1951.gz
Also try:
./rcm < rfc1952.gz
And for more information try:
./rcm < rfc1951.gz
./rcm < rfc1952.gz
For a good noop try:
gzip -c < rcm.c | ./rcm
Selected notes from the author:
Except for some silly requirements regarding input validation, CRC
checking, and similar unimportant fluff, this program is a fully
compliant RFC1951/RFC1952 (GNU Gzip) file uncompressor. Feed it a
"gzip" compressed file on standard input, and it will write the fully
uncompressed original file to standard output.
ObJustifications for this entry:
The Design Trade-off Argument
"The 184 characters worth of defines in the build file have been
carefully offset by 184 redundant and unecessary '{', '}', and ';'
characters in the source file."
The Design Review Argument
"Using only 216 characters out of a maximum of 256, the build file
meets and actually exceeds specification."
The Program Metrics Argument
"The program source is less than 3,100 characters in length and
uncompresses file `emacs-19.34b.tar.gz' in about 130 seconds on
my HP 9000/735. The now obsolete source file `inflate.c' from
the GNU gzip source tree is 31,613 characters in length and
uncompresses the emacs distribution file in slightly under 25
seconds. Thus:
3100 / 130 = 23.85 -vs- 31613 / 25 = 1264.52
which represents a better than 530% improvement in the ratio of
source file size to execution time."
The Whining Programmer's Argument
"The inflate algorithm requires that over 400 characters worth
of constants and tables be defined. Which means the program
itself had to be squeezed down to about 1,100 IOCCC countable
bytes."
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+219
View File
@@ -0,0 +1,219 @@
13th International Obfuscated C Code Contest Rules
Copyright (c) Landon Curt Noll, Larry Bassel and Sriram Srinivasan, 1996.
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. :-)
The 13th IOCCC contest window is: |
01-Oct-96 12:00 UTC to 01-Dec-96 12:00 UTC |
NOTE: Some of the changes from the 1995 rules are denoted by change bars. ---> |
However some changes such as 1995 to 1996 are not marked. |
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: 1996-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.
url: http://your/home/page.html or say none if you don't have one |
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 home page URL in the ---author--- section must be fully |
qualified or must be the word `none'. |
* 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.
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 01-Dec-96 12:00 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 01-Oct-96 12:00 UTC. Early entries will be accepted, however. |
We will attempt to EMail a confirmation to the sender of any entry
received after 01-Oct-96 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
+33
View File
@@ -0,0 +1,33 @@
#define _POSIX_SOURCE
#include <time.h>
#include <stdio.h>
#define extern/* ioccc*/
#define condition 22+d+e> 31
#define declarator main ( void )
#define keyword ae(t,d+e-9); ae(m,4)
#define false ae (t, d+ e+ 22); ae (m,3)
#define syntax_error(n); } else if (J < n) {
#define relational_expression(i, o, ccc) i o ccc
#define errno translation_unit/*Apollo 13*/int errno
#define iterative_statement for ( expressions ) block
#define translation_unit declarator compound_statement
#define ae(unary_expression,ae) unary_expression= ae
#define declaration char T[16]; struct tm ae(s,{ 0})
#define if_part {macrolist list ae(b,J%4); type_name
#define tokens if (t==25&&d==28 &&a > 10) ae (t, 18)
#define selection_statement(a,b,c) if(a){b; } else{ c; }
#define storage_class ae(e,(2*b+4*c+6*d+N)%7); statement
#define statement_list iterative_statement return'^'^'^'
#define macro(x,y,cast) ae(M,x); ae(N,y)syntax_error(cast)
#define block { if(relational_expression(J,<,1700))if_part;}
#define declaration_list int J,a,b,c,d, e,t,m,M,N; declaration
#define true keyword; selection_statement(t==26,ae(t,19),tokens)
#define compound_statement { declaration_list ; statement_list ; }
#define expressions ae(J,1582); relational_expression(J,<,2200); ++J
#define list macro (24, 5, 2200) ae(M, 24); ae(N, 6); } ae(a, J % 19);
#define type_name ae (c, J % 7);ae (d, (19 * a + M) % 30); storage_class
#define statement selection_statement ( condition,true,false)pptoken cast
#define macrolist macro(22,2,1800)macro (23, 3,1900) macro (23, 4, 2100)
#define pptoken ae(s.tm_year,J-1900);ae (s.tm_mon,m-1); ae(s.tm_mday,t);
#define cast (void)strftime(T,sizeof T, "%a %b %d %Y",&s),(void)puts(T);
#include <errno.h>
+108
View File
@@ -0,0 +1,108 @@
Worst Abuse of the C Preprocessor:
Jens Schweikhardt
DFN Network Operation Center
Schlartaeckerweg 3 (home address)
D-71384 Weinstadt
Germany
http://www.uni-stuttgart.de/People/schweikhardt/home.html
Judges' comments:
To use:
make schweikh1
./schweikh1
Look at the source. There is something very odd going on here.
Where does the real code come from if everything is a C pre-processor
statement?
Clearly this is either the Best Use or the Worst Abuse of the
C Preprocessor that the judges have seen this year!
Selected notes from the author:
What this program does
----------------------
This program is an implementation of an algorithm that calculates
the date of the Sunday following the first full moon after the
spring equinoxe. (Also known as "Easter", defined this way by the
Nicaean Concilium in 325 Anno Domini.) The algorithm is attributed
to the famous mathematician Carl Friedrich Gauss ["Meyers Handbuch
ueber das Weltall", Meyer, 5th Edition, 1973, p149] and is suitable
for anni domini within the Gregorian Calendar, that is, from 1582 AD
to 2199 AD:
Let J be the year.
If J is from 1582 to 1699, let M be 22, let N be 2
If J is from 1700 to 1799, let M be 23, let N be 3
If J is from 1800 to 1899, let M be 23, let N be 4
If J is from 1900 to 2099, let M be 24, let N be 5
If J is from 2100 to 2199, let M be 24, let N be 6
Let a be the modulus of J divided by 19
Let b be the modulus of J divided by 4
Let c be the modulus of J divided by 7
Let d be the modulus of (19a + M) divided by 30
Let e be the modulus of (2b + 4c + 6d + N) divided by 7
The interesting Sunday is either
March 22 + d + e or
April d + e - 9 (only one of them is a valid date)
with the following exceptions:
April 26 must always be changed to April 19
April 25 must be changed to April 18 if d is 28 and a greater than 10
Example: J = 1962, M = 24, N = 5
a = J % 19 = 5
b = J % 4 = 2
c = J % 7 = 2
d = 119 % 30 = 29
e = 191 % 7 = 2
March 53 is invalid, so the result is April 22 1962
Why I think this is obfuscated
------------------------------
Apart from the calculation of the Easter date, the definition *and*
calculation of which are obfuscations in their own right,
obfuscation lurks in many places. Look at those macro identifiers.
What can be more obvious than a program that explicitly mentions the
grammatical constructs it is composed of? If you look at K&RII A.9.3
you will find that a compound statement consists of an opening brace
followed by a declaration list followed by a semicolon followed by a
statement list followed by another semicolon and a closing brace.
Nobody can learn that by heart so I gently remind the reader by
defining a macro that expresses this clearly (line 25). This goes up
to the definition of a translation unit. Unfortunately, due to the
IOCCC's size restrictions, I had to abbreviate some syntactic
elements. "ae" actually reads "assignment expression". I had to stop
at some arbitrary point, so don't waste your time trying to find out
how preprocessing tokens form type qualifier lists, cast expressions
or direct abstract declarators. Assuming the reader knows about
these easy to remember language elements is justified in my opinion.
The moral:
Try to be as precise as can be and no one will comprehend what you mean.
The formula:
comprehension = 1/(2**precision)
The interpretation:
"Say nothing and everybody will understand."
The -I/usr/include in the build file is needed by gcc on Solaris because
gcc's "fixed" header in gcc-lib/sparc-sun-solaris2.5/2.7.2/include/errno.h
is broken (sort of) because it has *two* identical extern
declarations of errno. This leads to an error due to the
redefinition of main. The -I option makes sure the working
/usr/include/errno.h is found first, which shouldn't harm on other
systems.
Usage
-----
The program is run without arguments. It prints all dates in order.
+98
View File
@@ -0,0 +1,98 @@
#define C " "
#define O( _ ) # _
#define R( n , d ) e ( n , d )
#define e(p,o)o##p
#define D O ( % ) O ( l ) O ( d )
#define U R ( e ( g , n ) , e ( o , l ) )
#define M H ( R ( e ( c , i ) , t ) , R ( e ( a , t ) , s ) )
#define P H ( R ( e ( f , t ) , n ) , R ( e ( i , r ) , p ) ) (
#define H(O,r)R(O,r)
#include<stdio.h>
H ( R ( e ( f , e ) , e ( d , e
) ) , R ( e ( p , y ) , t ) ) H
( R ( e ( t , c ) , u ) , R ( e
( r , t ) , s ) ) { U n , t ; }
F ; H ( R ( e ( f , e ) , e ( d
, e ) ) , R ( e ( p , y ) , t )
) H ( R ( e ( d , e ) , e ( n ,
g ) ) , R ( e ( i , s ) , e ( n
, u ) ) ) U B ; M F I [ 4 * 5 ]
, w [ 4 * 5 ] , p [ 4 ] = { { 9
, 1 } , { 1 , 1 } , { 1 , 1 } ,
{ 6 * 7 , 1 } } ; M R ( e ( t ,
n ) , i ) J ; M R ( e ( d , i )
, e ( o , v ) ) o ( F f ) { e (
f , i ) ( f . t - 1 ) { J = P D
O ( / ) D , f . n , f . t ) ; }
R ( e ( e , s ) , e ( l , e ) )
{ J = P D , f . n ) ; } } M R (
e ( d , i ) , e ( o , v ) ) n (
F * f ) { U a = ( * f ) . n , b
= ( * f ) . t ; e ( f , i ) ( b
) { H ( R ( e ( e , l ) , i ) ,
e ( h , w ) ) ( a ) { U i = b %
a ; b = a ; a = i ; } b = b < 0
? - b : b ; ( * f ) . n e ( = ,
/ ) b ; ( * f ) . t e ( = , / )
b ; } } R ( e ( t , n ) , i ) R
( e ( n , i ) , e ( a , m ) ) (
R ( e ( t , n ) , i ) a , R ( e
( r , a ) , e ( h , c ) ) * v [
] ) { B m , W ; R ( e ( t , n )
, i ) i , c ; R ( e ( r , o ) ,
f ) ( i = 1 ; i < 5 ; i = i + 1
) { e ( f , i ) ( a > i ) { J =
H ( R ( e ( f , n ) , a ) , R (
e ( c , s ) , s ) ) ( v [ i ] ,
D O ( / ) D , & p [ i - 1 ] . n
, & p [ i - 1 ] . t ) ; } n ( p
+ i - 1 ) ; } I [ 0 ] = p [ 1 ]
; R ( e ( r , o ) , f ) ( i = 0
; i < p [ 0 ] . n ; i = i + 1 )
{ I [ i + 1 ] . n = I [ i ] . n
* p [ 2 ] . t + p [ 2 ] . n * I
[ i ] . t ; I [ i + 1 ] . t = I
[ i ] . t * p [ 2 ] . t ; n ( I
+ i + 1 ) ; } R ( e ( r , o ) ,
f ) ( W = ~ ( ~ 0 e ( < , < ) p
[ 0 ] . n * 2 ) ; ~ ( B ) 0 - W
; W = W - 1 ) { w [ c = 0 ] = I
[ 0 ] ; R ( e ( r , o ) , f ) (
m = W , i = 1 ; ! ( i > p [ 0 ]
. n ) ; i = i + 1 , m = m / 4 )
{ e ( f , i ) ( ( m & 3 ) < 2 )
{ e ( f , i ) ( m & 1 ) { w [ c
] . n e ( = , * ) I [ i ] . t ;
e ( f , i ) ( ( w [ c ] . t e (
= , * ) I [ i ] . n ) < 0 ) { w
[ c ] . n e ( = , * ) - 1 ; w [
c ] . t e ( = , * ) - 1 ; } } R
( e ( e , s ) , e ( l , e ) ) {
w [ c ] . n e ( = , * ) I [ i ]
. n ; w [ c ] . t e ( = , * ) I
[ i ] . t ; } } R ( e ( e , s )
, e ( l , e ) ) { w [ c = c + 1
] = I [ i ] ; } } R ( e ( r , o
) , f ) ( m = W , i = c = 0 ; i
< p [ 0 ] . n ; i = i + 1 , m =
m / 4 ) { e ( f , i ) ( ( m & 3
) > 1 ) { w [ 0 ] . n = w [ 0 ]
. n * w [ c + 1 ] . t + ( ( m &
1 ) ? - 1 : + 1 ) * w [ c + 1 ]
. n * w [ 0 ] . t ; w [ 0 ] . t
= w [ 0 ] . t * w [ c = c + 1 ]
. t ; } } n ( w ) ; e ( f , i )
( ! p [ 3 ] . t e ( | , | ) ( !
( p [ 3 ] . n - w [ 0 ] . n ) e
( & , & ) ! ( p [ 3 ] . t - w [
0 ] . t ) ) ) { R ( e ( r , o )
, f ) ( m = W , i = 0 ; i < p [
0 ] . n ; i = i + 1 , m = m / 4
) { o ( I [ i ] ) ; J = P C O (
% ) O ( c ) C , O ( * ) O ( / )
O ( + ) O ( - ) [ m & 3 ] ) ; }
o ( I [ i ] ) ; J = P C O ( = )
C ) ; o ( w [ 0 ] ) ; J = P O (
% ) O ( c ) , e ( 0 , 1 ) ) ; }
} H ( R ( e ( n , r ) , u ) , R
( e ( t , e ) , r ) ) J - 1 ; }
+129
View File
@@ -0,0 +1,129 @@
Best Algorithm:
Jens Schweikhardt
DFN Network Operation Center
Schlartaeckerweg 3 (home address)
D-71384 Weinstadt
Germany
http://www.uni-stuttgart.de/People/schweikhardt/home.html
Judges' comments:
To use:
make schweikh2
./schweikh2
Also try:
./schweikh2 15 1 0 0/0
The program accepts up to 4 parameters:
1) The number of operators in the expression [default: 9]
2) The value of the first operand [default: 1]
3) The (possibly negative) increment to the next operand [default: 1]
4) The goal value or 0/0 [default: 42]
The original program, with only slight obfuscations, may be found
in hunni.c. The perl script, obfuscates it appropriately:
perl ./hunni.pl < hunni.c
This entry was another crowd pleaser at the IOCCC BOF.
Selected notes from the author:
Note: the source must be viewed with tabstop 8. To appreciate the
beauty have your eyes half closed.
Why I think this program is obfuscated:
C is a free format language. It is therefore a question of style how
variables, operators, declarations, functions and syntactic elements
like braces and parentheses are grouped together. As a rule of thumb,
I put spaces around operators, after opening braces and before closing
braces. I have generalized this rule by putting whitespace after *any*
non-white space character (with the exception of preprocessor directives).
There are no recognizable keywords anymore. There are no recognizable
string literals any more. The main function is invisible. All operators
longer than one character have gone. They have been replaced by macro
calls with quite a number of arguments. The keys are the token pasting
and stringizing macros e and O. The "arcane rules of token pasting"
[K&R2] are used up to three levels, H(O,r)R(O,r)! which is needed to make
one 8-character token from 8 characters ('unsigned'). BTW, C has no 9 or
more character reserved words, so a fourth level is only required if
you intend to generate object names from 9 or more components. The final
round even swaps the tokens, so all keywords must be spelled backwards
(sort of, can you spot printf in the P macro?).
Try to indent the source. The unbalanced parentheses confuse Solaris'
indent to the max (although the result does compile):
Looking at the indented source is even *less* fun, because the nice
diamond pattern has been replaced by something that looks like, uhm,
modem noise.
Lint the source. It's clean. How obfuscated...
What's the exit status? The program exits with J - 1 where J is the
return value from several non-void functions (needed to shut up
lint). The last assignment is J = printf ("%c", 10); so the exit
status is 0 unless the last printf failed, which is even a *useful*
status. A further obfuscation is the use of 10 instead of '\n'.
'\n' can not be constructed by token pasting, AFAIK. That's why schweikh2
is likely to produce occasional garbage on non-ASCII execution character
set systems.
What this program does:
-----------------------
The program is an expression evaluator for a limited class of
expressions. Known operators are + - * /, operands are real numbers
(integers or fractions). The operands are restricted in that they must
differ by a constant value, for example 1 + 2 * 3 / 4 - 5. For any
combination of operators the expression is evaluated and compared to a
goal value. If they compare equal the expression is printed. If the goal
value is specified as 0/0 all expressions and results are printed. For
any fraction, the numerator and denominator are divided by their
greatest common divisor.
The program accepts up to 4 parameters:
1) The number of operators in the expression [default: 9]
2) The value of the first operand [1]
3) The (possibly negative) increment to the next operand [1]
4) The goal value or 0/0 [42]
On ANSI/ISO C conformant systems (where long is at least 32 bits)
overflow will occur in the default case (first operand 1, increment 1)
only for more than 11 operators. Because a bit mask is used that needs
twice the number of operands in bits (plus a sentinel value) on those
systems the first parameter must not exceed 15.
If long is at least 64 bits overflow will occur for more than 19
operators but you will probably wait quite some time for every of the
4^19 = 274,877,906,944 combinations to be evaluated... While I'm at it,
on a 50 MHz sparc, 4^11 expressions are evaluated in about 3 cpu
minutes (gcc -O3).
Sample arguments:
-----------------
$ schweikh2 6
$ schweikh2 7 0
$ schweikh2 7 7 0
$ schweikh2 8 9 -1 -67/21
$ schweikh2 8 2 2/5 -98/25
$ schweikh2 2 1/0 1 1/0
Miscellaneous
-------------
The diamond pattern can be continued without a break.
For a nice printout try this on your Bourne compatible shell
% while :; do grep -v '#' schweikh2.c; done
+116
View File
@@ -0,0 +1,116 @@
static char Asm = 'm'
;
#include\
<assert.h>
typedef unsigned long LOGO
;
#include\
<stdio.h>
static void new (char *, LOGO)
;
#include\
<stdlib.h>
#define Pascal (void)printf
#include\
<unistd.h>
static void new (char *Oberon
, LOGO awk)
{ Pascal ("%s to %calloc %luM+%luK+%lu bytes"
, Oberon
, Asm
, awk >> (__LINE__ - 1)
, (awk & 0xffc00) >> (1+sizeof __TIME__)
, awk & 1023)
; } typedef size_t BCPL
; static BCPL far = 0
, Lisp = ~(BCPL)0^(
~ (BCPL)0>>1)
;
#define B\
( C)case SIG##C\
: (void)puts(\
# C)\
; break\
;
int main (int, char**)
;
#define Alloc switch (Asm) { case 'c'\
: Basic = calloc (far\
, 1)\
; break\
; default\
: Basic = malloc (far)\
; }
#include\
<time.h>
static int inline(void)
;
#include\
<float.h>
int main (int F77
, char **F90)
{ switch (F90[--F77][0] == 'c') case 1
: Asm += 'c' - Asm
; switch (setbuf (stdout
, 0)
, fork()) { char *Basic
; case -1
: assert (0)
; break
; case 0
: for (
; far
#include\
<iso646.h>
or_eq Lisp, Lisp not_eq 0
; Lisp >>= 1) { new ("Trying"
, (LOGO) far)
; Alloc switch (Basic not_eq 0) { case 1
: Pascal ("..YEP\n")
; free (Basic)
; break
; default
: Pascal ("..nope\n")
; far and_eq compl Lisp
; } } Alloc assert (Basic not_eq 0)
; new ("Able"
, (LOGO) far)
; (void) putchar ('\n')
; for (Lisp = 0
; Lisp < far
; Lisp += 1 << 10) { time_t COBOL = time (NULL)
; Basic[Lisp] = '\a'
; Pascal ("\r%lu kilo bytes ok "
, (LOGO) (1 + (Lisp >> 10)))
; switch (difftime (time (NULL)
, COBOL) - 5 > FLT_EPSILON) { case 1
: free (Basic)
; return 1
; } } free (Basic)
; return 0
; } return inline()
; }
#include\
<signal.h>
#include\
<sys/wait.h>
static int inline (void) { int PL1
; switch ((void) wait (&PL1)
, WIFSIGNALED (PL1)) { int Algol
; default
: Algol = WTERMSIG (PL1)
; Pascal (" %calloc lied! Killed by SIG"
, Asm)
; switch (Algol) { B(KILL) B(SEGV) default
: Pascal ("NAL %d\n"
, Algol)
; } break
; case 0
: WEXITSTATUS(PL1)==1
? Pascal (" %calloc lied! Thr\aashing\n"
, Asm)
: Pascal ("no overcommit\n")
; } re\
turn PL1
;
}
+165
View File
@@ -0,0 +1,165 @@
Best Utility:
Jens Schweikhardt
DFN Network Operation Center
Schlartaeckerweg 3 (home address)
D-71384 Weinstadt
Germany
http://www.uni-stuttgart.de/People/schweikhardt/home.html
Judges' comments:
To use:
make schweikh3
WARNING!
Do not run this program without reading this text down to the end.
It may render your system unusable for a limited amount of time
or force you to reboot using the Big Red Button! This is not a joke.
You have been warned.
The source fails to compile on compilers that recognize the inline
keyword by default. For gcc, you may need to use -ansi.
See the file, schweikh3.info for example output from various systems.
But still it is a useful utility. To use try:
./schweikh3
and thanks for the virtual memories! :-)
NOTE: On some systems such as SunOS, one may need to compile with:
${CC} ${CFLAGS} \
-I. -D_POSIX_SOURCE '-Ddifftime(a,b)=(double)(b-a)' \
schweikh3.c -o schweikh3
Selected notes from the author:
Why I think my entry is obfuscated
----------------------------------
There are some layout obfuscations that hinder readability, like
some (but not all) one character tokens in column 1. Includes,
defines and declarations of data and functions appear intermixed.
iso646.h is even included in the middle of an expression, how
disgusting. Besides, requiring iso646.h will render the program
uncompilable on many systems that have not yet incorporated
Amendment One to The Standard. If you, dear reader, suffer from
this disease, just read iso646.h.
There are no `if' statements. They have been replaced by
"switch () case 1:" or "switch () case 0:" etc. At least one
switch has a declaration after the opening brace, booh!
Identifiers are named after random programming languages, Basic,
Cobol, F77, awk etc.
You have to select maximum ANSI C conformance of your
compiler. The source fails to compile under a C++ compiler due to
the `new' identifier which is a C++ reserved word:
$ g++ prog.c
prog.c:9: parse error before `new'
prog.c:16: parse error before `new'
prog.c:46: parse error before `void'
prog.c:65: parse error before `Lisp'
prog.c:68: parse error before `;'
[...]
prog.c:91: confused by earlier errors, bailing out
The source fails to compile on compilers that recognize the inline
keyword by default, e.g. gcc:
$ gcc prog.c
prog.c:46: parse error before `void'
prog.c: In function `main':
prog.c:91: parse error before `inline'
prog.c: At top level:
prog.c:97: parse error before `void'
The -ansi option to gcc fixes this.
The source fails to compile on obsolete systems with obsolete
memory models due to the identifier `far' (to be honest: this is
untested :-).
Does your indent cope with backslash/newline pairs inbetween
keywords like in "re\<newline>turn"? Solaris' indent inserts spaces
and thereby renders the source uncompilable...
The indented source will exhibit different semantics when indenting
changes the number of lines (due to using the __LINE__ macro in an
expression).
And what about sizeof __TIME__? This one's for the philosophers
and physicists among us programmers. What is it? sizeof (char *) -- no.
Strlen ("hh:mm:ss")? -- no. It's the same as sizeof __DATE__ -
sizeof "no" :-)
The program is POSIX conformant and lints without warning under
Solaris' Sunpro lint. Allocated memory is correctly freed on all
possible execution paths.
What this program does
----------------------
This program tests your operating system's allocation honesty. It
forks a child that will allocate as much as possible with byte
granularity and then write to every 1024th byte, at the same time
writing a status report on stdout. This way each page of the
allocated virtual memory will eventually be referenced. Without
any arguments, malloc() will be used to allocate memory. If the
first arg starts with c, calloc() will be used instead.
I distinguish three different behaviours:
1) OS without memory overcommit:
malloc does not lie -- you can use all memory the OS granted to you.
2) OS with memory overcommit:
malloc lies -- any program may get killed at random when the
OS can not acquire a free page.
3) OS with pseudo memory overcommit:
malloc lies -- The OS puts processes to sleep for which it can
not acquire a free page. Because other processes are also
affected this way, the system slows down and quickly becomes
totally unusable (also known as "thrashing"). Because more and
more processes wait for memory returned by other exiting processes
the system eventually enters a deadlock situation and effectively
halts.
I had the pleasure and pain to find all three behaviours on the
platforms I use regularly. What follows are the outputs for
Solaris, FreeBSD and Linux. The Linux case is interesting in that
the behaviour changes when calloc is used instead of malloc.
For FreeBSD, the last two lines are not messages stemming from
my program but issued by the syslog daemon.
Implementation remarks
----------------------
How can we distinguish the three different OS types from the
table above?
Obviously, type 1), no overcommit, is easy.
For type 2), random kill, we need to fork a child that can be killed
and whose exit status the parent collects and decodes. Here's
where POSIX enters the scene.
Type 3), thrashing, was the hardest part. The first attempt was to
measure the elapsed processor time it takes to write a single byte
(using clock()). If a certain threshold is reached I assume the
system is thrashing. When thrashing, however, the process does not
consume processor time in a noticeable amount any longer and I lose.
So I switched to measuring wall clock time using time(). On the one
system that I observe thrashing (Linux) this works (although the
value returned by time seems to 'hang' sometimes when the OS thrashes.
Exceeding a threshold of 5 seconds may be detected only after half a
minute or so.
+171
View File
@@ -0,0 +1,171 @@
***** SOLARIS 2.5 (sparc):
% prog
Trying to malloc 2048M+0K+0 bytes..nope
Trying to malloc 1024M+0K+0 bytes..nope
Trying to malloc 512M+0K+0 bytes..nope
Trying to malloc 256M+0K+0 bytes..nope
Trying to malloc 128M+0K+0 bytes..YEP
Trying to malloc 192M+0K+0 bytes..nope
Trying to malloc 160M+0K+0 bytes..YEP
Trying to malloc 176M+0K+0 bytes..nope
Trying to malloc 168M+0K+0 bytes..YEP
Trying to malloc 172M+0K+0 bytes..nope
Trying to malloc 170M+0K+0 bytes..YEP
Trying to malloc 171M+0K+0 bytes..YEP
Trying to malloc 171M+512K+0 bytes..YEP
Trying to malloc 171M+768K+0 bytes..nope
Trying to malloc 171M+640K+0 bytes..nope
Trying to malloc 171M+576K+0 bytes..YEP
Trying to malloc 171M+608K+0 bytes..YEP
Trying to malloc 171M+624K+0 bytes..nope
Trying to malloc 171M+616K+0 bytes..nope
Trying to malloc 171M+612K+0 bytes..YEP
Trying to malloc 171M+614K+0 bytes..YEP
Trying to malloc 171M+615K+0 bytes..YEP
Trying to malloc 171M+615K+512 bytes..YEP
Trying to malloc 171M+615K+768 bytes..YEP
Trying to malloc 171M+615K+896 bytes..YEP
Trying to malloc 171M+615K+960 bytes..YEP
Trying to malloc 171M+615K+992 bytes..YEP
Trying to malloc 171M+615K+1008 bytes..YEP
Trying to malloc 171M+615K+1016 bytes..nope
Trying to malloc 171M+615K+1012 bytes..nope
Trying to malloc 171M+615K+1010 bytes..nope
Trying to malloc 171M+615K+1009 bytes..nope
Able to malloc 171M+615K+1008 bytes
1 kilo bytes ok
2 kilo bytes ok
...
175719 kilo bytes ok no overcommit
***** FreeBSD 2.1 (i386):
% prog
Trying to malloc 2048M+0K+0 bytes..nope
Trying to malloc 1024M+0K+0 bytes..nope
Trying to malloc 512M+0K+0 bytes..nope
Trying to malloc 256M+0K+0 bytes..nope
Trying to malloc 128M+0K+0 bytes..nope
Trying to malloc 64M+0K+0 bytes..nope
Trying to malloc 32M+0K+0 bytes..YEP
Trying to malloc 48M+0K+0 bytes..nope
Trying to malloc 40M+0K+0 bytes..nope
Trying to malloc 36M+0K+0 bytes..nope
Trying to malloc 34M+0K+0 bytes..nope
Trying to malloc 33M+0K+0 bytes..nope
Trying to malloc 32M+512K+0 bytes..nope
Trying to malloc 32M+256K+0 bytes..nope
Trying to malloc 32M+128K+0 bytes..nope
Trying to malloc 32M+64K+0 bytes..nope
Trying to malloc 32M+32K+0 bytes..nope
Trying to malloc 32M+16K+0 bytes..nope
Trying to malloc 32M+8K+0 bytes..nope
Trying to malloc 32M+4K+0 bytes..nope
Trying to malloc 32M+2K+0 bytes..YEP
Trying to malloc 32M+3K+0 bytes..YEP
Trying to malloc 32M+3K+512 bytes..YEP
Trying to malloc 32M+3K+768 bytes..YEP
Trying to malloc 32M+3K+896 bytes..YEP
Trying to malloc 32M+3K+960 bytes..YEP
Trying to malloc 32M+3K+992 bytes..YEP
Trying to malloc 32M+3K+1008 bytes..YEP
Trying to malloc 32M+3K+1016 bytes..YEP
Trying to malloc 32M+3K+1020 bytes..YEP
Trying to malloc 32M+3K+1022 bytes..nope
Trying to malloc 32M+3K+1021 bytes..nope
Able to malloc 32M+3K+1020 bytes
1 kilo bytes ok
...
21668 kilo bytes ok
malloc lied! Killed by SIGKILL
Nov 24 18:11:56 /kernel: swap_pager: out of space
Nov 24 18:11:57 /kernel: Process 5 killed by vm_fault -- out of swap
% prog c
Trying to calloc 2048M+0K+0 bytes..nope
Trying to calloc 1024M+0K+0 bytes..nope
Trying to calloc 512M+0K+0 bytes..nope
Trying to calloc 256M+0K+0 bytes..nope
Trying to calloc 128M+0K+0 bytes..nope
Trying to calloc 64M+0K+0 bytes..nope
Trying to calloc 32M+0K+0 bytes
calloc lied! Killed by SIGKILL
Nov 24 18:14:54 /kernel: swap_pager: out of space
Nov 24 18:14:55 /kernel: Process 7 killed by vm_fault -- out of swap
***** Linux 1.2.13 (i386):
% prog
Trying to malloc 2048M+0K+0 bytes..nope
Trying to malloc 1024M+0K+0 bytes..nope
Trying to malloc 512M+0K+0 bytes..nope
Trying to malloc 256M+0K+0 bytes..nope
Trying to malloc 128M+0K+0 bytes..nope
Trying to malloc 64M+0K+0 bytes..nope
Trying to malloc 32M+0K+0 bytes..nope
Trying to malloc 16M+0K+0 bytes..YEP
Trying to malloc 24M+0K+0 bytes..nope
Trying to malloc 20M+0K+0 bytes..YEP
Trying to malloc 22M+0K+0 bytes..YEP
Trying to malloc 23M+0K+0 bytes..YEP
Trying to malloc 23M+512K+0 bytes..YEP
Trying to malloc 23M+768K+0 bytes..YEP
Trying to malloc 23M+896K+0 bytes..YEP
Trying to malloc 23M+960K+0 bytes..YEP
Trying to malloc 23M+992K+0 bytes..YEP
Trying to malloc 23M+1008K+0 bytes..YEP
Trying to malloc 23M+1016K+0 bytes..YEP
Trying to malloc 23M+1020K+0 bytes..YEP
Trying to malloc 23M+1022K+0 bytes..YEP
Trying to malloc 23M+1023K+0 bytes..YEP
Trying to malloc 23M+1023K+512 bytes..YEP
Trying to malloc 23M+1023K+768 bytes..YEP
Trying to malloc 23M+1023K+896 bytes..YEP
Trying to malloc 23M+1023K+960 bytes..YEP
Trying to malloc 23M+1023K+992 bytes..YEP
Trying to malloc 23M+1023K+1008 bytes..YEP
Trying to malloc 23M+1023K+1016 bytes..YEP
Trying to malloc 23M+1023K+1020 bytes..YEP
Trying to malloc 23M+1023K+1022 bytes..YEP
Trying to malloc 23M+1023K+1023 bytes..YEP
Able to malloc 23M+1023K+1023 bytes
23294 kilo bytes ok malloc lied! Thrashing
% prog c
Trying to calloc 2048M+0K+0 bytes..nope
Trying to calloc 1024M+0K+0 bytes..nope
Trying to calloc 512M+0K+0 bytes..nope
Trying to calloc 256M+0K+0 bytes..nope
Trying to calloc 128M+0K+0 bytes..nope
Trying to calloc 64M+0K+0 bytes..nope
Trying to calloc 32M+0K+0 bytes..nope
Trying to calloc 16M+0K+0 bytes..YEP
Trying to calloc 24M+0K+0 bytes..nope
Trying to calloc 20M+0K+0 bytes..nope
Trying to calloc 18M+0K+0 bytes..nope
Trying to calloc 17M+0K+0 bytes..nope
Trying to calloc 16M+512K+0 bytes..nope
Trying to calloc 16M+256K+0 bytes..nope
Trying to calloc 16M+128K+0 bytes..nope
Trying to calloc 16M+64K+0 bytes..nope
Trying to calloc 16M+32K+0 bytes..nope
Trying to calloc 16M+16K+0 bytes..nope
Trying to calloc 16M+8K+0 bytes..YEP
Trying to calloc 16M+12K+0 bytes..YEP
Trying to calloc 16M+14K+0 bytes..nope
Trying to calloc 16M+13K+0 bytes..nope
Trying to calloc 16M+12K+512 bytes..nope
Trying to calloc 16M+12K+256 bytes..nope
Trying to calloc 16M+12K+128 bytes..nope
Trying to calloc 16M+12K+64 bytes..nope
Trying to calloc 16M+12K+32 bytes..nope
Trying to calloc 16M+12K+16 bytes..nope
Trying to calloc 16M+12K+8 bytes..nope
Trying to calloc 16M+12K+4 bytes..nope
Trying to calloc 16M+12K+2 bytes..nope
Trying to calloc 16M+12K+1 bytes..nope
Able to calloc 16M+12K+0 bytes
1 kilo bytes ok
...
16396 kilo bytes ok no overcommit
+1
View File
@@ -0,0 +1 @@
main() { putchar('!'); putchar('\n'); exit(0); }
+1
View File
@@ -0,0 +1 @@
main(h,m)char**m;{for(time(*m);h/=2;)m[4][m[h][h[(int*)localtime(*m)]]]=m[3][h];puts(m[4]);}
+83
View File
@@ -0,0 +1,83 @@
Best One Liner:
Brian Westley (Merlyn LeRoy on Usenet)
1906 James Ave.
St. Paul, MN 55105
USA
http://www.visi.com/~westley/index.html
Judges' comments:
To use:
make westley
sh ./clock1
Also try:
sh ./clock2
And for a good time, try:
sh ./clock3
Time and time again, Brian Westley seems to come up with a winner!
We are amazed at how much is being done with only one relatively
short line. We think you will as well if you take the time to
understand it.
Selected notes from the author:
This 1-line program allows various analog ASCII clocks
to print out the time; the ASCII clock is built from
the command line arguments, so many different types of
clocks can be generated. Three different scripts are
supplied to print out a grandfather clock, a mantle
clock that runs backwards, and a linear-style clock.
(they are clock1, clock2, and clock3)
The program makes the following (possibly non-portable) assumptions:
1) Command line strings can be written to
2) argv[0] can be written to as if it were a long *
3) The first three elements of the struct * returned by
localtime() are seconds, minutes, hours, and all are ints
4) My sample scripts assume ASCII, though this is not
inherent in the code, just my sample scripts
These assumptions are pretty reasonable. 2) can be eliminated
by makes the code larger.
The code is simple; the arguments passed are:
prog minute_map hour_map hand_symbol clock_image
The program merely takes the minute (0-59) and the hour (0-23)
values, looks up the offsets in minute_map and hour_map
and writes the hand_symbol for each into the clock_image
string. This string is then printed.
The for() loop starts by calling time() with argv[0], so
the time value (a long) is written into the program name.
The for() control value is argc, which starts at 5, but
the /=2 statement is executed before the test, so the for()
loop is executed twice, with h=2, then h=1 (for hour & minute).
The statement of the for() loop takes the hour or minute
field of the struct returned by localtime() by casting it
to an int* and dereferencing element [h]. It is slightly
smaller to use the trick h[(int*)localtime(*m)] instead of
((int*)localtime(*m))[h].
This value is in turn indexed into the hour_map or minute_map
parameter to determine where the 'hand' symbol should be
written into the clock_image.
Note that the hands move in a quantum fashion; 3:59 looks
deceptively like 2:59, since the hour hand will be at the 3
position. It won't move until both hands click over at 4:00.