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:
1 parent
28efc67f5d
commit
c0663537cb
1683 files changed
+220064
No files matched your search
Binary file not shown.
+214
@@ -0,0 +1,214 @@
|
||||
#!/bin/make
|
||||
# 2000 makefile
|
||||
#
|
||||
# Copyright (C) Simon Cooper, Landon Curt Noll, Peter Seebach
|
||||
# and Leonid A. Broukhis, 2000.
|
||||
# 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 the contest judges.
|
||||
|
||||
SHELL= /bin/sh
|
||||
CAT= cat
|
||||
RM= rm
|
||||
SED= sed
|
||||
TRUE= true
|
||||
|
||||
# optimization
|
||||
#
|
||||
# Most compiles will safely use -O2. Some can use only -O.
|
||||
# A few compilers have broken optimizers and thus you may
|
||||
# not want anything.
|
||||
#
|
||||
#OPT=
|
||||
#OPT= -O
|
||||
OPT= -O2
|
||||
|
||||
# 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 (Compaq Tru64 Unix)
|
||||
# want -std1, and 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= -Xa ${OPT}
|
||||
#CFLAGS= -std1 $(OPT)
|
||||
CFLAGS= -ansi ${OPT}
|
||||
|
||||
NO_ANSI_CFLAGS=
|
||||
#NO_ANSI_CFLAGS=
|
||||
|
||||
# NOTE: On some systems, the library path does not include the location
|
||||
# of the X11 libraries. You might need to use a -L/path/to/X11/lib/dir
|
||||
# in order to compile with these libs.
|
||||
#
|
||||
X11CCFLAGS= -I/usr/X11R6/include -I/usr/X11R6/include/X11 -I/usr/include/X11
|
||||
#X11CCFLAGS=
|
||||
X11LDFLAGS= -L/usr/X11R6/lib
|
||||
#X11LDFLAGS=
|
||||
|
||||
# Perl
|
||||
#
|
||||
PERL= perl
|
||||
#PERL= perl5
|
||||
|
||||
# ANSI compiler
|
||||
#
|
||||
# Set CC to the name of your ANSI compiler.
|
||||
#
|
||||
# Some entries seem to need gcc. If you have gcc, set
|
||||
# both CC and MAY_NEED_GCC to gcc.
|
||||
#
|
||||
# If you do not have gcc, set CC to the name of your ANSI compiler, and
|
||||
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
|
||||
# to disable such programs.
|
||||
#
|
||||
CC= cc
|
||||
MAY_NEED_GCC= gcc
|
||||
|
||||
# winners that compile under ANSI C
|
||||
#
|
||||
WINNERS= anderson schneiderwent primenum bellard bmeyer briddlebane dhyang \
|
||||
dmy2jd jarijyrki dlowe natori rince robison thadgavin tomx
|
||||
ALT_NAMES= schneiderwent.orig briddlebane.orig thadgavin.orig
|
||||
DATA_FILES= schneiderwent_files bmeyer_files jarijyrki_files
|
||||
|
||||
|
||||
all: ${WINNERS}
|
||||
|
||||
# Best use of flags
|
||||
#
|
||||
anderson: anderson.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
# Most Timely Output
|
||||
#
|
||||
schneiderwent: schneiderwent.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
schneiderwent_files: schneiderwent.data
|
||||
|
||||
schneiderwent.orig: schneiderwent.orig.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
# Best Abuse of CPP
|
||||
#
|
||||
primenum: primenum.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
# Most Specific Output
|
||||
#
|
||||
bellard: bellard.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
# Best Utility
|
||||
#
|
||||
# machines operating in 64 bit mode:
|
||||
#
|
||||
bmeyer: bmeyer.c
|
||||
${CC} -DY= -O6 $? -o $@ -lm
|
||||
#
|
||||
# linux/x86, glibc 2.0, libc4/5:
|
||||
#
|
||||
# bmeyer: bmeyer.c
|
||||
# ${CC} -DY="__setfpucw(0x127f)" -O6 $? -o $@ -lm
|
||||
#
|
||||
# linux/x86, glibc 2.1:
|
||||
#
|
||||
# bmeyer: bmeyer.c
|
||||
# ${MAY_NEED_GCC} -DY='int x=0x127f; __asm__ ("fldcw %0" : : "m" (*&x))' \
|
||||
# -O6 $? -o $@ -lm
|
||||
|
||||
bmeyer_files: lavabus.pgm lenna.glic michael.pgm
|
||||
|
||||
# Best Abuse of User
|
||||
#
|
||||
briddlebane: briddlebane.c
|
||||
${CC} ${CFLAGS} $? -o $@ -lm
|
||||
|
||||
briddlebane.orig: briddlebane.orig.c
|
||||
${CC} ${CFLAGS} $? -o $@ -lm
|
||||
|
||||
# Best Layout
|
||||
#
|
||||
dhyang: dhyang.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
dmy2jd: dmy2jd.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
# Best of Show
|
||||
#
|
||||
jarijyrki: jarijyrki.c
|
||||
${CC} ${X11CCFLAGS} ${CFLAGS} -DNeedFunctionPrototypes \
|
||||
-DU=40 -DT=98 '-Dz=(T+1)*U*U' -DQ=80 -DS=20 -DN=10 -DB=5 -DG=23 \
|
||||
-Dp=7 '-DM=((p+1)*Q)+S' '-DH=(G*S)+S+S' -DC=XK_Up -DL=XK_Down \
|
||||
-DO=XK_Left -DV=XK_Right -DR=XK_Escape -D_=XK_BackSpace \
|
||||
$? -o $@ ${X11LDFLAGS} -lX11
|
||||
|
||||
jarijyrki_files: sheet1.info
|
||||
|
||||
# Worst Abuse of the Rules
|
||||
#
|
||||
# NOTE: You will need to adjust this path to the place where Perl has been
|
||||
# installed on your system. Running "perl -V" may help you locate
|
||||
# this place.
|
||||
#
|
||||
# The following bit of perl may help determining the values you need:
|
||||
#
|
||||
# perl -MConfig -e 'print "$Config{archlibexp}/CORE\n"'
|
||||
#
|
||||
#
|
||||
dlowe: dlowe.c
|
||||
${CC} ${NO_ANSI_CFLAGS} -DPERL_POLLUTE \
|
||||
`${PERL} -MExtUtils::Embed -e ccopts` $? -o $@ \
|
||||
`${PERL} -MExtUtils::Embed -e ldopts`
|
||||
|
||||
# Best Small Program
|
||||
#
|
||||
natori: natori.c
|
||||
${CC} ${CFLAGS} $? -o $@ -lm
|
||||
|
||||
# Astronomically Obfuscated
|
||||
#
|
||||
rince: rince.c
|
||||
${CC} ${X11CCFLAGS} ${CFLAGS} -DM_PI=3.14159265358979323846 \
|
||||
$? -o $@ -lm ${X11LDFLAGS} -lX11
|
||||
|
||||
# Best game
|
||||
#
|
||||
robison: robison.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
# Most Portable Output
|
||||
#
|
||||
thadgavin: thadgavin.c
|
||||
${CC} ${CFLAGS} $? -o $@ -lcurses -lm
|
||||
|
||||
thadgavin.orig: thadgavin.orig.c
|
||||
${CC} ${CFLAGS} $? -o $@ -lncurses -lm
|
||||
|
||||
# Most Complete Program
|
||||
#
|
||||
tomx: tomx.c
|
||||
${CC} ${CFLAGS} $? -o $@
|
||||
|
||||
everything: ${WINNERS} ${ALT_NAMES} ${DATA_FILES}
|
||||
|
||||
clean:
|
||||
${RM} -f *.o a.out core ${WINNERS}
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${WINNERS}
|
||||
${RM} -f ${ALT_NAMES}
|
||||
|
||||
nuke: clobber
|
||||
@${TRUE}
|
||||
|
||||
install: all
|
||||
${CAT} ${WINNERS} ${ALT_NAMES} > /dev/null
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
2000 marked the "The Fifteenth International Obfuscated C Code Contest"
|
||||
|
||||
Copyright (C) Landon Curt Noll, Simon Cooper, Peter Seebach
|
||||
and Leonid A. Broukhis, 2000.
|
||||
All Rights Reserved. Permission for personal, educational or non-profit
|
||||
use is granted provided this copyright and notice are included in its
|
||||
entirety and remains unaltered. All other uses must receive prior permission
|
||||
from the contest judges.
|
||||
|
||||
|
||||
Standard IOCCC stuff
|
||||
--------------------
|
||||
|
||||
Use make to compile entries. It is possible that on non-Un*x / non-Linux
|
||||
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).
|
||||
|
||||
Some ANSI C compilers are not quite as good as they should be. If
|
||||
yours is lacking, you may need to compile using gcc instead of your
|
||||
local compiler.
|
||||
|
||||
|
||||
New Judge
|
||||
---------
|
||||
|
||||
The judges were unable to contact Jeremy Horn for judging the 2000 contest.
|
||||
|
||||
As a result, Simon Cooper:
|
||||
|
||||
http://www.sfik.com/
|
||||
|
||||
joined our team. Simon is well known for being a co-author of the 2nd
|
||||
edition of the Building Internet Firewalls book.
|
||||
|
||||
|
||||
Remarks on some of the entries
|
||||
------------------------------
|
||||
|
||||
There were some outstanding entries that did not win. Unfortunately
|
||||
some very good entries lost because they:
|
||||
|
||||
+ depended too much on non-portable side effects in expressions;
|
||||
+ depended too much on a particular byte order;
|
||||
+ required the use of a special script, data file or pseudo-machine
|
||||
language that was not supplied with the entry.
|
||||
|
||||
We hope the authors of some of those entries will fix and re-submit
|
||||
them for the next IOCCC.
|
||||
|
||||
We believe you will be impressed with this year's winners. The
|
||||
Best of Show is a fine example of compact obfuscation. But don't
|
||||
ignore the shorter winners. The Best Small Program, Best Abuse of
|
||||
User and Most Complete Program are well worth studying in detail.
|
||||
|
||||
The Worst Abuse of the Rules is technically allowed by the rules.
|
||||
We gave it an award this year, but don't assume you can get away
|
||||
with using it next time ... :-)
|
||||
|
||||
Speaking of time, be sure to check out the Astronomically Obfuscated
|
||||
and the Most Timely Output.
|
||||
|
||||
|
||||
There was no 1999 contest
|
||||
-------------------------
|
||||
|
||||
So what happened to 1999? Landon Curt Noll was scheduled to take a
|
||||
vacation from the IOCCC this year. The remaining judges were
|
||||
unable to contact Jeremy Horn, so the IOCCC stalled.
|
||||
|
||||
But thanks to Landon's returning early from his IOCCC vacation (Landon
|
||||
will take a full IOCCC vacation during some other year), Simon Cooper
|
||||
joining the IOCCC judging team as well as the hard work of Peter Seebach
|
||||
and Leonid A. Broukhis the judging was completed in Dec 2000.
|
||||
|
||||
It was decided that the 15th contest would be the year 2000 contest
|
||||
(the year the judging completed) rather than year 1999 (the initial
|
||||
scheduled start of the contest). That is why there is no 1999 contest.
|
||||
|
||||
|
||||
|
||||
Final Comments
|
||||
--------------
|
||||
|
||||
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:
|
||||
|
||||
questions@ioccc.org
|
||||
|
||||
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.
|
||||
|
||||
You must include the words ``ioccc question'' in the subject of your EMail
|
||||
message when sending EMail to the judges.
|
||||
|
||||
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.
|
||||
|
||||
The next IOCCC is planned to start towards early spring 2001. Watch:
|
||||
|
||||
http://www.ioccc.org/
|
||||
|
||||
for news of the next contest.
|
||||
|
||||
=-=
|
||||
|
||||
p.s. The has been mentioned in an Amici Curiae for the DeCSS case. See:
|
||||
|
||||
http://cryptome.org/mpaa-v-2600-bac.htm
|
||||
|
||||
and seach on the word ioccc (twice).
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include <stdio.h>
|
||||
|
||||
char
|
||||
*T="IeJKLMaYQCE]jbZRskc[SldU^V\\X\\|/_<[<:90!\"$434-./2>]s",
|
||||
K[3][1000],*F,x,A,*M[2],*J,r[4],*g,N,Y,*Q,W,*k,q,D;X(){r [r
|
||||
[r[3]=M[1-(x&1)][*r=W,1],2]=*Q+2,1]=x+1+Y,*g++=((((x& 7)
|
||||
-1)>>1)-1)?*r:r[x>>3],(++x<*r)&&X();}E(){A||X(x=0,g =J
|
||||
),x=7&(*T>>A*3),J[(x[F]-W-x)^A*7]=Q[x&3]^A*(*M)[2 +(
|
||||
x&1)],g=J+((x[k]-W)^A*7)-A,g[1]=(*M)[*g=M[T+=A ,1
|
||||
][x&1],x&1],(A^=1)&&(E(),J+=W);}l(){E(--q&&l ()
|
||||
);}B(){*J&&B((D=*J,Q[2]<D&&D<k[1]&&(*g++=1 ),
|
||||
!(D-W&&D-9&&D-10&&D-13)&&(!*r&&(*g++=0) ,*
|
||||
r=1)||64<D&&D<91&&(*r=0,*g++=D-63)||D >=
|
||||
97&&D<123&&(*r=0,*g++=D-95)||!(D-k[ 3]
|
||||
)&&(*r=0,*g++=12)||D>k[3]&&D<=k[ 1]
|
||||
-1&&(*r=0,*g++=D-47),J++));}j( ){
|
||||
putchar(A);}b(){(j(A=(*K)[D* W+
|
||||
r[2]*Y+x]),++x<Y)&&b();}t ()
|
||||
{(j((b(D=q[g],x=0),A=W) ),
|
||||
++q<(*(r+1)<Y?*(r+1): Y)
|
||||
)&&t();}R(){(A=(t( q=
|
||||
0),'\n'),j(),++r [2
|
||||
]<N)&&R();}O() {(
|
||||
j((r[2]=0,R( ))
|
||||
),r[1]-=q) &&
|
||||
O(g-=-q) ;}
|
||||
C(){( J=
|
||||
gets (K
|
||||
[1]))&&C((B(g=K[2]),*r=!(!*r&&(*g++=0)),(*r)[r]=g-K[2],g=K[2
|
||||
],r[
|
||||
1]&&
|
||||
O())
|
||||
);;}
|
||||
main
|
||||
(){C
|
||||
((l(
|
||||
(J=(
|
||||
A=0)
|
||||
[K],
|
||||
A[M]
|
||||
=(F=
|
||||
(k=(
|
||||
M[!A
|
||||
]=(Q
|
||||
=T+(
|
||||
q=(Y
|
||||
=(W=
|
||||
32)-
|
||||
(N=4
|
||||
))))
|
||||
+N)+
|
||||
2)+7
|
||||
)+7)
|
||||
),Y=
|
||||
N<<(
|
||||
*r=!
|
||||
-A))
|
||||
);;}
|
||||
@@ -0,0 +1,76 @@
|
||||
Best Use of Flags:
|
||||
|
||||
Glyn Anderson
|
||||
Jl. Raya Serang KM 18.2
|
||||
Desa Bojong
|
||||
Cikupa, Tangerang, 15710
|
||||
Indonesia
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make anderson
|
||||
|
||||
To run:
|
||||
|
||||
echo Obfuscate | ./anderson
|
||||
|
||||
This small program might be a nice addition to a digital personal
|
||||
organizer; just in case you are stranded on a desert island and need to
|
||||
signal your distress to passing ships.
|
||||
|
||||
The obfuscation in this program is truly masterful. The program is
|
||||
very cleverly obscured without the use of a single #define!
|
||||
Reformatting this program by hand :-) is the easiest way to understand
|
||||
what is going on.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
This program is a simple filter that translates ASCII text into
|
||||
semaphore code. It reads from standard input and converts all
|
||||
alphanumeric characters to their corresponding semaphore codes.
|
||||
Consecutive whitespace is translated as a single 'break' code. Newlines
|
||||
also cause the next code to be output on a new line. All other
|
||||
characters are ignored. The codes themselves are written to standard
|
||||
output as a depiction of a person holding two flags, using only ASCII
|
||||
characters (semaphore smileys, if you will). For example, given the
|
||||
input "Hello, world!", the output will be:
|
||||
|
||||
<> <> <> <> <> <>
|
||||
_() ()/ ()/ ()/ _\) () (/_ _\)
|
||||
[] /^ |^^ /^^ /^^ [] ^^ |^^| ^^ [] [] ^^
|
||||
<>[ [][ <>][ <>][ ][ [][] ][ ][
|
||||
|
||||
|
||||
<> []
|
||||
_()_ ()/ |() ()
|
||||
[] ^^ [] /^^ ^^| |^^|
|
||||
][ <>][ ][] [][]
|
||||
|
||||
The program is obfuscated without the use of the preprocessor or any
|
||||
special compilation parameters. In fact, the program doesn't even
|
||||
bother using any keywords, save the single 'char' at the beginning.
|
||||
This program was crafted using only operator precedence rules,
|
||||
short-circuit evaluation and recursion. Each function contains a
|
||||
single, non-empty statement. (I did have to add a couple of empty
|
||||
statements to format the code properly.) There is a single string
|
||||
constant which encodes the flag positions and other data needed for
|
||||
drawing the semaphore codes.
|
||||
|
||||
The preprocessor will provide no help in un-obfuscating this code, and a
|
||||
C beautifier won't get you very far either. You just have to crunch
|
||||
through it.
|
||||
|
||||
An ANSI C compiler will generate several warnings when it compiles this
|
||||
program, as none of the functions declare their return type, nor do they
|
||||
return anything. This was necessary to keep the program free of
|
||||
keywords. It's valid in K&R C, and compiles in ANSI C. There are also
|
||||
warnings about conversion from 'int' to 'char' and the resulting loss of
|
||||
data. Again, if it's OK with K&R, it's OK with me.
|
||||
|
||||
This program is a great teaching tool for learning the semaphore code;
|
||||
and if you don't have any flags handy you can just use two copies of the
|
||||
source file.
|
||||
@@ -0,0 +1,37 @@
|
||||
int m = 754974721, N, t[1 << 22], a, *p, i, e = 1 << 22, j, s, b, c, U;
|
||||
f (d)
|
||||
{
|
||||
for (s = 1 << 23; s; s /= 2, d = d * 1LL * d % m)
|
||||
if (s < N)
|
||||
for (p = t; p < t + N; p += s)
|
||||
for (i = s, c = 1; i; i--)
|
||||
b = *p + p[s], p[s] = (m + *p - p[s]) *
|
||||
1LL * c % m, *p++ = b % m, c = c * 1LL * d % m;
|
||||
for (j = 0; i < N - 1;)
|
||||
{
|
||||
for (s = N / 2; !((j ^= s) & s); s /= 2);
|
||||
if (++i < j)
|
||||
a = t[i], t[i] = t[j], t[j] = a;
|
||||
}
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
*t = 2;
|
||||
U = N = 1;
|
||||
while (e /= 2)
|
||||
{
|
||||
N *= 2;
|
||||
U = U * 1LL * (m + 1) / 2 % m;
|
||||
f (362);
|
||||
for (p = t; p < t + N;)
|
||||
*p++ = (*p * 1LL ** p % m) * U % m;
|
||||
f (415027540);
|
||||
for (a = 0, p = t; p < t + N;)
|
||||
a += (6972593 & e ? 2 : 1) ** p, *p++ = a % 10, a /= 10;
|
||||
}
|
||||
while (!*--p);
|
||||
t[0]--;
|
||||
while (p >= t)
|
||||
printf ("%d", *p--);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
Most Specific Output:
|
||||
|
||||
Fabrice Bellard
|
||||
451 chemin du mas de Matour
|
||||
34790 Grabels
|
||||
France
|
||||
|
||||
http://www.enst.fr/~bellard
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make bellard
|
||||
|
||||
To run:
|
||||
|
||||
./bellard
|
||||
|
||||
This code is an nice compact example of a Modular Fast Fourier Transform.
|
||||
While its output is very specific, the internal FFT has a wide variety
|
||||
of uses.
|
||||
|
||||
Can you modify this code to produce primes such as 23523*2^70000-1,
|
||||
48594^65536+1 or 6917!-1?
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
This program prints the biggest known prime number (2^6972593-1)
|
||||
in base 10. It requires a few minutes. It uses a Modular Fast
|
||||
Fourier Transform to compute this number in a reasonable amount
|
||||
of time (the usual method would take ages !).
|
||||
|
||||
The program uses >= 64 bit 'long long' type. It should run on any
|
||||
system with a gcc compiler.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define a typedef
|
||||
a long N;
|
||||
#define i =m(p(r,o,v),e,d
|
||||
N G,l,I,C,B,A,W,L,S
|
||||
, R,O,c,k,s =
|
||||
80, U=13
|
||||
,T=169; a double P;
|
||||
#define F for(
|
||||
a P*E; a char*w; P sqrt(P); N H(){ F;
|
||||
O=scanf(" %[#]%*[^\n]",&O); ); scanf("%ld%*c",&O);
|
||||
#define D return
|
||||
D O; }
|
||||
|
||||
|
||||
|
||||
#define V =malloc(sizeof(
|
||||
#define M M(
|
||||
#define X +=
|
||||
P M N R){ s= s>=k?printf( "%ld%c"
|
||||
+3*(C<1),s-k, R&7?32:10):s; D R>0?B
|
||||
/2?H():getchar ():R?.9+.7*M R+1):0; }
|
||||
P t(N x,P K){ D x?(x>U?0:t(x+2,K)*(x-1)
|
||||
/x/K)+1/sqrt(K): t(2,K*K/U+1)*K; } N _(N
|
||||
J,N x){ F*(x?&W:& A)=W+J+x; (O=x=W/(J=k*k))
|
||||
||A<J||(( O=2*W/J) &&2*A/J<3); A X A-J+1){ F
|
||||
J*=x+O; S--*B&&x==O ; O=x=!J){ s X x+s; M 0); }
|
||||
W X W-J; S X 2; L X L-J*k+M S%8==B); } D 1; } E
|
||||
p(E J,E x,E O){ F R=T; R--; )O[R]=J[R]+.8*x[R]; D O;
|
||||
} P m(E W,E x,P s){ F R = U; --R; ){ E A=W+R*U; W[R]X s/
|
||||
12; *W X s; *A-=*x++; F; A>W; ){ *A/=*W; F O=R; O; O--)A[O]-=
|
||||
W[O]**A; A-=U; } W X 14; } D*W; } int main(int z,w*y){ N K=s,g; Y;
|
||||
M z); s= B=C=15-H(); s=G= M 8); s=l=M C); G*=g=C%3?1:3; if(I=s=M 8)){ N
|
||||
b=G+9,x=b*340+U,J=b*(l+5), * n V N ) * J ),*j=n+5*b; E h V P)*x),q=h+b,e=q+
|
||||
b; P d=K; F; J--; )n[J]=J<b ? 0: I / 2 ; F; x; )h[--x]=0; s=M x); k=256; C
|
||||
=4-C; B=C/4; s=_(_(T,0),0); F ; -- z ; ){ R=atoi(*++y); c=R>0?K=R,c :-2*R;
|
||||
} z=G/K+1; z X g>z; I++; c++; F ; ++ J<l; ){ P u=0,C,y; E H =e+U,o= H+b*T,r
|
||||
=o-2*T,v=r-T; F; x<G; x++){ p( H , o -T,o); o X T; H X T; q[x]= .7*(q[x-1]+h
|
||||
[x] );
|
||||
} p(H,
|
||||
H,r );
|
||||
F; x;
|
||||
) { E S=
|
||||
e ; w l =
|
||||
" !{ ,;lf6D@"
|
||||
; j X 1-g; F; *++l;
|
||||
){ *S++ =*j; j X*l%3*g-
|
||||
g+*l%5*b-3*b; } y =M x-G);
|
||||
y =M-J)* M-x)+ M-J-1)*y+.01; y=
|
||||
sqrt((u+q[--x]+.1)/y ); o-=T; C i)+
|
||||
#define Z(x)(t(0,(x-C)/y)-l+1e-6*(x-Q))
|
||||
.5; K=M-B); { N f=I,Q=0; F; f-Q>c; ){ P l=0
|
||||
; N H = C+c/2+1; H%=c; H X(f+Q+c-2*H)/2/c*c; l=
|
||||
Z(Q); O=(A-W)*Z(H)/Z(f); _(O,R=B?K>= H:L/k>O+W); *(
|
||||
R?&Q:&f)=H; } Q X f; *S=*j=Q/=2; s=B?s:Q+k; f=Q+n[x/z];
|
||||
n[x/z]=x%z+J%(z*2/g)?f:!putc(x?l[4*g*f/z/z/I-8]:10,stderr);
|
||||
H-=U; F O=156; O--; ){ H--; *H=e[O%U]*e[O/U]/y+.8**H; } C-=Q+.5
|
||||
; y i/.9)-Q-C; p(p(r+T,r,r),H,r); h[x]=.7*h[x]+C*C; u X h[x]; u*=.7
|
||||
; d X C>0?-y:y; } } j X 9; } _(_(x,x),x); } D 0; }
|
||||
@@ -0,0 +1,351 @@
|
||||
Best Utility:
|
||||
|
||||
Bernd Meyer
|
||||
Monash University, Melbourne, Australia
|
||||
1/832 Blackburn Rd
|
||||
Clayton, VIC 3168
|
||||
Australia
|
||||
|
||||
http://byron.csse.monash.edu.au/
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make bmeyer
|
||||
|
||||
Compile with the maximum possible optimization on your system.
|
||||
If your system has 80-bit internal representation of floating
|
||||
point values (x86, some Motorola processors) and you want the
|
||||
compressed format to be portable across platforms, you need
|
||||
to set your FPU to use 64 bit mode. See the extra build lines
|
||||
in the Makefile, and read the author's comments below.
|
||||
|
||||
If you cannot work out hwo to get into 64 bit mode, you can
|
||||
try using -ffloat-store if you compile with GCC (this may have
|
||||
a performance penalty). The resulting binary will have a good
|
||||
chance to produce portable files, but due to the resulting
|
||||
double-rounding (first internally to 80 bit, then to 64 bit
|
||||
on writing the value to memory), there is a small but very real
|
||||
chance any given file produced might not be portable.
|
||||
|
||||
To run:
|
||||
|
||||
In a video window (white text on black background):
|
||||
|
||||
./bmeyer < michael.pgm > michael.glic
|
||||
|
||||
Compare the michael.pgm to the screen output.
|
||||
|
||||
To test that you are compressing and decompressing the same way the
|
||||
author was, try
|
||||
|
||||
./bmeyer < lenna.glic
|
||||
|
||||
Also try in a reverse video window:
|
||||
|
||||
./bmeyer < michael.pgm 2>/dev/null | ./bmeyer > new.pgm
|
||||
|
||||
Compare the michael.pgm to the screen output. Compare the new.pgm file
|
||||
to the michael.pgm file.
|
||||
|
||||
Create a large reverse video xterm, say 200 columns wide and try:
|
||||
|
||||
./bmeyer 200 < lavabus.pgm > lavabus.glic
|
||||
|
||||
Produce an even smaller output:
|
||||
|
||||
./bmeyer -2 200 < lavabus.pgm > lavabus.glic2
|
||||
|
||||
Decompress that smaller glic-file:
|
||||
|
||||
./bmeyer -2 200 < lavabus.glic2 > new.pgm
|
||||
|
||||
Compare the new.pgm file to the lavabus.pgm file by viewing
|
||||
them.
|
||||
|
||||
Don't even think of supplying different compression factors (the
|
||||
dashed argument) for compression and decompression! You've been warned.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
GLICBAWLS
|
||||
|
||||
A) Function
|
||||
===========
|
||||
|
||||
"GLICBAWLS" stands for:
|
||||
|
||||
"Grey Level Image Compression By Adaptive Weighted Least Squares".
|
||||
|
||||
And that's exactly what this program does --- feed it a .PGM file
|
||||
(either raw [i.e. P5] or ascii [i.e. P2]) on stdin, and it will
|
||||
output a compressed version to stdout. Feed it a compressed file
|
||||
on stdin, and it will decompress it to stdout --- as either raw or
|
||||
ascii .PGM, depending on what format it was compressed from. For
|
||||
example:
|
||||
|
||||
./bmeyer < michael.pgm > michael.glic
|
||||
|
||||
and then
|
||||
|
||||
./bmeyer < michael.glic > michael.decoded.pgm
|
||||
|
||||
As it turns out, glicbawls compresses greyscale images (or, more
|
||||
precisely, "natural" greyscale images) better than any other
|
||||
program I am aware of (with the exception of the not-yet-published
|
||||
program developed for my PhD thesis). Of course, this might take
|
||||
some time, so a progress indicator is provided. To make things
|
||||
more interesting, instead of a boring bar or percentage display,
|
||||
an ASCII rendition of the image being compressed/decompressed is
|
||||
output to stderr (assuming white text on black background). If you
|
||||
have trouble recognizing the image, try squinting at it ;-).
|
||||
|
||||
If you still have trouble, simply use a terminal or xterm with
|
||||
more than 80 columns, and tell glicbawls about it by giving the
|
||||
number of columns as an argument. For example
|
||||
|
||||
./bmeyer 260 <lavabus.pgm >lavabus.glic
|
||||
|
||||
will allow glicbawls to use up to 260 columns, which makes things
|
||||
much more recognizable.
|
||||
|
||||
Still running out of space? Need to compress those images just a
|
||||
tad more? And maybe you can handle some loss due to the
|
||||
compression? If so, you can use glicbawls' "near lossless"
|
||||
compression mode. In that mode, the decoded pixel values are
|
||||
allowed to differ from tbe originals, but there is an upper limit
|
||||
on the magnitude of the difference. For example, if a maximum
|
||||
error of 2 is allowed, an original pixel value of 37 could be
|
||||
decoded as 35,36,37, 38 or 39. In order to use this mode, simply
|
||||
give the maximum allowed error as an argument, with a dash ('-')
|
||||
before it. For example
|
||||
|
||||
./bmeyer -2 < graph.pgm > graph.2.glic
|
||||
|
||||
will compress in a way that allows decompression with a maximum
|
||||
error of two. You can combine both types of arguments, i.e.
|
||||
|
||||
./bmeyer -3 180 < graph.pgm >graph.3.glic
|
||||
|
||||
will compress with a maximum error of 3, using a 180 column
|
||||
terminal for the progress display, and
|
||||
|
||||
./bmeyer -3 180 < graph.3.glic > graph.3maxerr.pgm
|
||||
|
||||
will decompress the result on such a terminal.
|
||||
|
||||
But wait, there is more --- you can also feed glicbawls .PPM files
|
||||
(i.e. colour images), raw or ascii, your choice. Glicbawls will
|
||||
compress and decompress them just fine. However, it only does
|
||||
"reasonably well" on them; It beats PNG easily, but there are
|
||||
certainly programs out there that can compress colour images
|
||||
considerably better. And don't even *think* about using it for
|
||||
so-called "artistic" images (i.e. anything that wasn't scanned
|
||||
from a photo or camera)....
|
||||
|
||||
*****************************************************************
|
||||
* *
|
||||
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING *
|
||||
* *
|
||||
* *
|
||||
* Glicball is rather CPU and FPU intensive. Don't *
|
||||
* run it on anything slow. Things start to be *
|
||||
* usable around 300+MHz, with 600+ being highly *
|
||||
* desirable. *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
|
||||
|
||||
B) Compile Instructions
|
||||
=======================
|
||||
|
||||
Unlike most compression program, glicbawls makes heavy use of
|
||||
floating point maths --- and not all FPUs are created equal. Most
|
||||
importantly, the x86 and 68k FPUs use 80 bit floating point
|
||||
formats internally, while most other processors use IEEE 64 bit
|
||||
formats by default. If not taken care of, this means that a
|
||||
glicbawls file compressed on one CPU cannot generally be
|
||||
decompressed on another.
|
||||
|
||||
Fortunately, just about all current FPUs can be put into IEEE 64
|
||||
bit mode (or at least something close enough for
|
||||
glicbawls). Unfortunately, there is no standard way of doing
|
||||
so. For this reason, the build file contains *three* compile
|
||||
lines; One for machines that already use 64 bit mode by default
|
||||
(most RISC processors), one for linux/x86 machines using libc4,
|
||||
libc5 or glibc2.0, and one for linux/x86 machines using glibc2.1
|
||||
(glibc2.1 no longer exports the __setfpucw function, necessitating
|
||||
the use of gcc inline assembly. *Grumble*).
|
||||
|
||||
So, if you are building on a machine that does not, by default,
|
||||
use IEEE 64 bit floating point doubles, you'll have to define Y to
|
||||
be a command that switches it into that mode. If you fail to do
|
||||
so, your glicbawls executable will still be able to decompress its
|
||||
own compressed files, but you may be unable to exchange files with
|
||||
glicbawls on other machines.
|
||||
|
||||
|
||||
C) Obfuscation
|
||||
==============
|
||||
|
||||
Most of the obfuscation of this program was driven by the
|
||||
desperate struggle to fit all of glicbawls' features into code
|
||||
that fits the IOCCC's size limits. All identifiers names are
|
||||
single-character, which was only possible by ruthless exploitation
|
||||
of scope. There is a function M() that handles nearly all input
|
||||
from stdin, handles all output to stdout, and also recursively
|
||||
calculates one of the mathematical expressions needed for error
|
||||
modelling. There is a function that calculates (A^(-1)*b)*x with A
|
||||
a matrix and b and x being vectors, and does so in a very
|
||||
efficient way --- but one would be hard pressed to find it. There
|
||||
is an arithmetic coder that is even less recognizable. A lot of
|
||||
loop variables don't get initialized, but instead the code is
|
||||
arranged in such a way that they just happen to have the right
|
||||
value when control flow reaches the loops. Lots of functions use
|
||||
the same two global scratch variables. Variables change their
|
||||
meaning all the time, and the differences between compressing and
|
||||
decompressing are handled in rather subtle ways all over the
|
||||
program. The string that holds the ascii values for displaying the
|
||||
progress image doubles as a description on how to find a pixel's
|
||||
causal neighbours. And then there are a few #define's that really
|
||||
are just in there to save a few characters, but as an added
|
||||
"benefit" make the source ever more unreadable.
|
||||
|
||||
In short --- running it through the preprocessor and the
|
||||
pretty-printer will give you something that looks slightly less
|
||||
like line noise and slightly more like a C program, but unless you
|
||||
are a true wizard, it is unlikely to gain you any insights into
|
||||
what is actually going on....[0]
|
||||
|
||||
|
||||
D) Bugs, Assumptions and TODOs
|
||||
==============================
|
||||
|
||||
Glicbawls assumes that characters are 8 bit wide, and that the
|
||||
character set used is ASCII. If one of these isn't true, all hell
|
||||
will break loose.
|
||||
|
||||
The .PGM headers are not checked very thoroughly --- glicbawls
|
||||
will happily try to encode lots of files that it shouldn't
|
||||
touch. The old adage of "garbage in, garbage out" holds in that
|
||||
case. Furthermore, even if glicbawls detects an incorrect input,
|
||||
it fails to provide a meaningful error message, and instead
|
||||
simply aborts.
|
||||
|
||||
When decompressing a near-losslessy encoded image, the maximum
|
||||
allowed error is required as a command line parameter. This should
|
||||
really be saved in the compressed file!
|
||||
|
||||
Glicbawls relies on the decimal representation of all integers
|
||||
having less than 255 digits. While ANSI C does not guarantee this,
|
||||
it seems rather unlikely that anyone in the foreseeable future
|
||||
would use images with 10^255 rows, columns or different levels of
|
||||
grey. Also, it is assumed that any integer used can be cast to a
|
||||
double and back without loss of precision. This limits the number
|
||||
of rows, columns and grey levels to 9 quintillion, which should
|
||||
also be sufficient for the next few years.
|
||||
|
||||
There is a theoretical chance that you might get a division by
|
||||
zero error. You have a MUCH better chance of getting hit by
|
||||
lightning the very second you realize that you just won a few
|
||||
million in a lottery. But if it happens to you, don't say I
|
||||
didn't warn you! Instead, go out and buy a lightning rod and a
|
||||
lottery ticket ;-)
|
||||
|
||||
At one point, a pointer to int is used as the target of a "%1[#]"
|
||||
conversion in a scanf, which makes gcc rather unhappy, but
|
||||
shouldn't really cause anyone any trouble. The same goes for a
|
||||
couple of assignments which are used as truth values.
|
||||
|
||||
|
||||
E) Algorithm
|
||||
============
|
||||
|
||||
An exhaustive explanation of the algorithm used would go beyond
|
||||
the scope of an info file, and would also be quite difficult in
|
||||
pure ASCII, so the following is just a rough outline, and contains
|
||||
some compression-speak...
|
||||
|
||||
The image is handled in scanline ordering. For each pixel, an
|
||||
expected value is calculated by creating a least squares predictor
|
||||
of order 12 based on all of the previously encoded/decoded
|
||||
pixels. However, the contribution of each pixel is weighted
|
||||
according to its Manhattan-distance from the current pixel,
|
||||
D. That weight used is pow(0.8,D). [1][2][3]
|
||||
|
||||
|
||||
In a similar way, the prediction *errors* for all previous pixels
|
||||
are combined --- a weighted average (with weight pow(0.7,D)) of
|
||||
the squares of all previous prediction errors is taken, and the
|
||||
square root of the (appropriately scaled) result is called sigma.
|
||||
|
||||
The predicted value and sigma are then used as the parameters of a
|
||||
Student or t-distribution (which is similar to a normal
|
||||
distribution, but has more weight in the tails), providing a
|
||||
probability distribution for the current pixel.
|
||||
|
||||
Next, the possible interval of values for the current pixel is
|
||||
halved, and through integration of the probability distribution, a
|
||||
probability is calculated for the pixel value being in the lower
|
||||
half. During encoding, the actual value is examined, and the
|
||||
result encoded using an arithmetic coder. During decoding, the
|
||||
arithmetic decoder provides the information which half the actual
|
||||
value is in. In both cases, the interval borders are adjusted
|
||||
accordingly, the arithmetic coder/decoder updated, and the
|
||||
interval halving repeated until the precise value has been
|
||||
en/decoded[4].
|
||||
|
||||
|
||||
[0] Yes, this could be seen as a challenge....
|
||||
[1] Actually, the weight is pow(0.8,D)/s, where s is the sigma
|
||||
used for en/decoding the particular previous pixel. Dividing
|
||||
by s is a rather arbitrary action justified only by the
|
||||
improvement in results. Mathematically, I can only justify
|
||||
dividing by s^2, or not dividing at all....
|
||||
[2] Obviously, these least squares predictors are not calculated
|
||||
from scratch for each pixel. Some clever reuse of earlier
|
||||
results allows O(1) calculation, rather than the
|
||||
O(previous_rows*columns) this description would suggest.
|
||||
[3] As anyone who has ever tried local least squares knows from
|
||||
bitter experience, there is a lot of numerical instability
|
||||
associated with them. So glicbawls adds a bias towards an
|
||||
averaging predictor to the equation system the least squares
|
||||
predictor is calculated from. The weight that is given to
|
||||
this bias is constantly adjusted throughout coding/decoding,
|
||||
thus justifying the 'a' in "glicbawls".
|
||||
[4] In the case of near-lossless coding, the interval is not
|
||||
necessarily *halved*, but rather split at a convenient point
|
||||
(the split points are chosen in such a way as to minimise the
|
||||
expected number of bits needed for coding). Also, the
|
||||
iteration ends as soon as the interval is small enough to
|
||||
guarantee decoding within the requested maximum error.
|
||||
|
||||
####################################################################
|
||||
|
||||
Photo Credit:
|
||||
|
||||
Lavabus was taken by the judge, Landon Curt Noll. Michael was
|
||||
provided by the author. Lenna is a 1972 Playboy centerfold.
|
||||
|
||||
michael.pgm
|
||||
|
||||
The author's Godchild and nephew.
|
||||
|
||||
lavabus.pgm
|
||||
|
||||
A bus that was trapped by lava from Kilauea volcano in
|
||||
Hawaii, USA. Nobody was in the bus at the time, BTW.
|
||||
Photo date: 1981.
|
||||
|
||||
lenna.glic
|
||||
|
||||
A November 1972 Playboy centerfold was scanned in long ago and
|
||||
has been used for image compression research since then. Playboy
|
||||
originally threatened to prosecute unauthorized use, but
|
||||
eventually granted that, having been in use for image compression
|
||||
testing for so long, it was now a useful benchmark. (Note: This
|
||||
picture doesn't show very much.)
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#define e(t, v, w) n t(u x, u y) { n a = sqrt(x+y); r ((v - a) * (w - a)); }
|
||||
#define w while(
|
||||
#define r return
|
||||
typedef char u; typedef short q; typedef double n;
|
||||
u *z = "Z\253\345\252\256\351\325\232\265f\256\246nyZf\253U^\266\232]z\352i\236\226i[m\266\351\252\255\246\235V\247e\235\226\276Z\371jUg\x3\362\212pX\254\251PH\253\332\225\373\235\b\v\336HO.\203Qf\201\x1d\207\211\357\367S7|)=\331n\x4!E<\233Z\246\x1flv\232d(r\263\274\375\313\305\200\361\302\327\274\375\300\201c\250-|\246]\304\253I\377W\227R^\251\350\x2""C\251\203\311O\346\242\vDh\r\357\306x\325\274\315\366c\th\325\272\376\311X+:\325\354q\263|\257\x1c\327\316g\204\266s\211\357\370A(\x11""D\321\x1d:\352\327\x1bk@\x11""E-\310s\271\235\304\273\x2+\x4I\274jT\256\363\214\307{\232a\3270\a+qm\270\aI\315\337\220\x17\x18\315G\217\371@\215\335\v[v\335\205\343\250-|\246\373:\225\f\2552Oe]\206U\272\355\x10\327)u\rY]\276>\243\333w{3\x19\v""acC8\3775\351\b\377\204lJnsy.:\330\2553rKx'\362'!%\302\271\376|\236skq\242C\251\263&\x15K\x4""fA\227\211\242r7]\371\333\200z%\277\207CJ\255^}\264\237\327\275Z\n;L\x1aN#\371N\354G\256skq\242K!\364\211E\214\x17\377\343z\340w\233\272\354eTD\262t\365\335[_\233\225J\313\2746\334\x3\b\244F&\240]\222\332\210\351\376rJs<\2265I;\203Xd\272\377\345\214\x17\263]2I\237\302\253\346\355\332\343\350G\327\"\350f}\301n\223\366\300\210\343j\247\316%\363\210\345\n\252\215c\255\314\3248\300\261\350RM7\203\261\371\265\r_\220\x17\x19\a(+u\x1d=I\235\314\331@\310Cl\x16\210\307\345\357\306\x1f""e\345R\354y\257\367\350!.\x1f`\345uW&\204\246\367>\226\335\205\353\x18\336;\302\334\266\213Fn\233\201vAE\325+qnVR\222e\237E<e\203!f\333\345[\x17#\205\273I\314\371n\340\304\205\225h\323\336\371\x1c""7\227\201%\327\201p\326\263\351f\x19\a\v\336;uI\312?\214\265I1$\302+\373\233v\336\x5\306,y\313OD\351d*\350f\357H\262]\x3\332l\365L\237Qs\320{\231\244\204d\352v\335\215\327\357\200\247\302W\x10", x, y;
|
||||
n g() { r (n)rand()/18972; } n t, v; q F, B, C; e(a, 0, 3.0) e(b, 3.0, 4.125)
|
||||
e(c, 4.125, 9) u f(n (*h)()) { do { t=g() * 6.283184; v = sqrt(g() * 72); y =
|
||||
sin(t) * v; x=cos(t)*v; } w (h(x*x,y*y)>=0)||(fabs(x) > 5) || (fabs(y) > 5));
|
||||
r ((y+5) * 11) + x + 7; } u k(q x, u l) { u o = 0; F = 0; w F < 189) { B =C =
|
||||
0; w 1) { y = ((z[F/4]>>((F++%4)*2))&3) - 1; if (y&2)
|
||||
break; C = (C*2)+y, ++B; } if (!(C - x | B - l)) r (o<26)?o+0x61:((2108973>>(
|
||||
(o-26)*8))&47); ++o; } r 1; } u s[1079]; u *E(u v) { u *x = s; w v--)w *(x++)
|
||||
); r x; } main() { q A = 0, B = 0, C = 1078; u l = 0; u *p = s; srand(time( 0
|
||||
) ); w C) { A = (A*2) + ((((z[B/8+48]+114)^2)>>(7-(B++%8)))&1),++l; x = k(A,l
|
||||
); if (x-1) { *(p++)=x, A=l=0, C--; } } printf("%s%s %s%s%s\n", E(0), E(f(c))
|
||||
, E(f(a)), E(1), E(f(b))); }
|
||||
@@ -0,0 +1,56 @@
|
||||
Best Abuse of User:
|
||||
|
||||
Moxen N. Briddlebane
|
||||
24 Oxtree Ave.
|
||||
The Xoemn, MN 68214
|
||||
|
||||
Lord Zarbon
|
||||
24 Oxtree Ave.
|
||||
The Xoemn, MN 68214
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make briddlebane
|
||||
|
||||
To run:
|
||||
|
||||
./briddlebane
|
||||
|
||||
One could argue that this program was a "diseased dumpster of tripe"
|
||||
but I suspect that would only result in the judges being heckled as a
|
||||
"scum-encrusted congress of obscurity" (but only if it was in the early
|
||||
evening of Dec 22, 2000).
|
||||
|
||||
Can you find out how it stores the insult strings? Can you then take
|
||||
an insult and figure out when it will be uttered?
|
||||
|
||||
[sc] The code also contains a buffer overflow bug which I have fixed!
|
||||
The array size of "s" should be 1079 characters long. (From 0 to 1078
|
||||
inclusive!). Without this it results in an error in the encoding of
|
||||
"decrepit" -- For a 32bit little endian machine using GCC (because of
|
||||
the way it assigns variables to memory) it will terminate "decrepit"
|
||||
with the character '\200' (the last value of F) instead of '\0'.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
This program was broadcast from deep within the Zarbonic Cluster
|
||||
and received at 9:03pm on March 21st, 2000 by Moxen N. Briddlebane.
|
||||
The original author, as designated by other components of the
|
||||
transmission, refers to himself simply as "Lord Zarbon", though
|
||||
offers no information in relation to the significance of that
|
||||
post. The sole purpose of this program appears to be to degrade
|
||||
and humiliate the people of this planet by calling them names.
|
||||
It takes no input, only produces a single line of slanderous output.
|
||||
|
||||
The program appears to be rather confused, internally. It is
|
||||
unclear whether or not "Lord Zarbon" truly understands the
|
||||
mechanics of programming. What is particularly disturbing is
|
||||
the curious method of insult-encoding employed by this program.
|
||||
Furthermore, it is ambiguous how said data is arranged and why
|
||||
it is necessary to resort to trigonometric functions to handle
|
||||
it. One of the real mysteries involves the numbers "114" and
|
||||
"2", which are, according to Lord Zarbon, very deliberate.
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#define e(t, v, w) n t(u x, u y) { n a = sqrt(x+y); r ((v - a) * (w - a)); }
|
||||
#define w while(
|
||||
#define r return
|
||||
typedef char u; typedef short q; typedef double n;
|
||||
u *z = "Zォ蟐ョ鰈垠fョヲnyZfォU^カ咯z麒椁i[mカ鬪ュヲ抃ァe摶セZ�Ug\x3�pXャゥPHォレ方拿b\v゙HO.ゲf―x1d㊨�S7|)=ルn\x4!E<媚ヲ\x1flv單(rウシ�ヒナ�ラシ�タ…ィ-|ヲ]トォI�W由^ゥ鐔x2""CゥλO譴\vDh\r�xユシヘ�\thユコ�ノX+:ユ�ウ|ッ\x1cラホg┯s会�(\x11""Dム\x1d:�\x1bk@\x11""E-ネsケ敍サ\x2+\x4IシjTョ�ヌ{啾ラ0\a+qmク\aIペ申x17\x18ヘG錠@在\v[vン�ィ-|ヲ�:表fュ2Oe]�コ偆x10ラ)u\rY]セ>」ロw{3\x19\v""acC8�5饅b��Jnsy.:リュ3rKx'�'!%ツケ�|枹kq「Cゥウ&\x15K\x4""fA莱「r7]�z%ソ④Jュ^}エ湶スZ\n;L\x1aN#��ョskq「K!�E圭x17�縻烱崋�TDイt�[_尓Jヒシ6ワ\x3\b、F&�]嬬磯�rJs<�5I;スdコ�蛹\x17ウ]2I淞ォ跫レ肛Gラ\"鑁}チn賑タ医jァホ%�藹nェ皇ュフヤ8タア鏗M7Τ�\r_申x17\x19\a(+u\x1d=I變ル@ネCl\x16杏襃ニ\x1f""e薐�ッ�!.\x1f`蛄W&┬�>餅�\x18゙;ツワカ祈n宦vAEユ+qnVR弾檸<e�!fロ藜\x17#�Iフ�狷�hモ゙�x1c""7浴%ラ}ヨウ馭\x19\a\v゙;uIハ?厳I1$ツ+蕙v゙\x5ニ,yヒOD馘*鑁�イ]\x3レl�櫺sミ{勁�黐ン細�ァツW\x10", x, y;
|
||||
n g() { r (n)rand()/18972; } n t, v; q F, B, C; e(a, 0, 3.0) e(b, 3.0, 4.125)
|
||||
e(c, 4.125, 9) u f(n (*h)()) { do { t=g() * 6.283184; v = sqrt(g() * 72); y =
|
||||
sin(t) * v; x=cos(t)*v; } w (h(x*x,y*y)>=0)||(fabs(x) > 5) || (fabs(y) > 5));
|
||||
r ((y+5) * 11) + x + 7; } u k(q x, u l) { u o = 0; F = 0; w F < 189) { B =C =
|
||||
0; w 1) { y = ((z[F/4]>>((F++%4)*2))&3) - 1; if (y&2)
|
||||
break; C = (C*2)+y, ++B; } if (!(C - x | B - l)) r (o<26)?o+0x61:((2108973>>(
|
||||
(o-26)*8))&47); ++o; } r 1; } u s[1079]; u *E(u v) { u *x = s; w v--)w *(x++)
|
||||
); r x; } main() { q A = 0, B = 0, C = 1078; u l = 0; u *p = s; srand(time( 0
|
||||
) ); w C) { A = (A*2) + ((((z[B/8+48]+114)^2)>>(7-(B++%8)))&1),++l; x = k(A,l
|
||||
); if (x-1) { *(p++)=x, A=l=0, C--; } } printf("%s%s %s%s%s\n", E(0), E(f(c))
|
||||
, E(f(a)), E(1), E(f(b))); }
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
#define/**/X
|
||||
char*d="X0[!4cM,!"
|
||||
"4cK`*!4cJc(!4cHg&!4c$j"
|
||||
"8f'!&~]9e)!'|:d+!)rAc-!*m*"
|
||||
":d/!4c(b4e0!1r2e2!/t0e4!-y-c6!"
|
||||
"+|,c6!)f$b(h*c6!(d'b(i)d5!(b*a'`&c"
|
||||
")c5!'b+`&b'c)c4!&b-_$c'd*c3!&a.h'd+"
|
||||
"d1!%a/g'e+e0!%b-g(d.d/!&c*h'd1d-!(d%g)"
|
||||
"d4d+!*l,d7d)!,h-d;c'!.b0c>d%!A`Dc$![7)35E"
|
||||
"!'1cA,,!2kE`*!-s@d(!(k(f//g&!)f.e5'f(!+a+)"
|
||||
"f%2g*!?f5f,!=f-*e/!<d6e1!9e0'f3!6f)-g5!4d*b"
|
||||
"+e6!0f%k)d7!+~^'c7!)z/d-+!'n%a0(d5!%c1a+/d4"
|
||||
"!2)c9e2!9b;e1!8b>e/! 7cAd-!5fAe+!7fBe(!"
|
||||
"8hBd&!:iAd$![7S,Q0!1 bF 7!1b?'_6!1c,8b4"
|
||||
"!2b*a,*d3!2n4f2!${4 f. '!%y4e5!&f%"
|
||||
"d-^-d7!4c+b)d9!4c-a 'd :!/i('`&d"
|
||||
";!+l'a+d<!)l*b(d=!' m- a &d>!&d'"
|
||||
"`0_&c?!$dAc@!$cBc@!$ b < ^&d$`"
|
||||
":!$d9_&l++^$!%f3a' n1 _ $ !&"
|
||||
"f/c(o/_%!(f+c)q*c %! * f &d+"
|
||||
"f$s&!-n,d)n(!0i- c- k) ! 3d"
|
||||
"/b0h*!H`7a,![7* i] 5 4 71"
|
||||
"[=ohr&o*t*q*`*d *v *r ; 02"
|
||||
"7*~=h./}tcrsth &t : r 9b"
|
||||
"].,b-725-.t--// #r [ < t8-"
|
||||
"752793? <.~;b ].t--+r / # 53"
|
||||
"7-r[/9~X .v90 <6/<.v;-52/={ k goh"
|
||||
"./}q; u vto hr `.i*$engt$ $ ,b"
|
||||
";$/ =t ;v; 6 =`it.`;7=` : ,b-"
|
||||
"725 = / o`. .d ;b]`--[/+ 55/ }o"
|
||||
"`.d : - ?5 / }o`.' v/i]q - "
|
||||
"-[; 5 2 =` it . o;53- . "
|
||||
"v96 <7 / =o : d =o"
|
||||
"--/i ]q-- [; h. / = "
|
||||
"i]q--[ ;v 9h ./ < - "
|
||||
"52={cj u c&` i t . o ; "
|
||||
"?4=o:d= o-- / i ]q - "
|
||||
"-[;54={ cj uc& i]q - -"
|
||||
"[;76=i]q[;6 =vsr u.i / ={"
|
||||
"=),BihY_gha ,)\0 " , o [
|
||||
3217];int i, r,w,f , b ,x ,
|
||||
p;n(){return r <X X X X X
|
||||
768?d[X(143+ X r++ + *d ) %
|
||||
768]:r>2659 ? 59: ( x = d
|
||||
[(r++-768)% X 947 + 768] ) ?
|
||||
x^(p?6:0):(p = 34 X X X )
|
||||
;}s(){for(x= n (); ( x^ ( p
|
||||
?6:0))==32;x= n () ) ;return x ; }
|
||||
void/**/main X () { r = p
|
||||
=0;w=sprintf (X X X X X X o
|
||||
,"char*d="); for ( f=1;f < * d
|
||||
+143;)if(33-( b=d [ f++ X ] )
|
||||
){if(b<93){if X(! p ) o
|
||||
[w++]=34;for X(i = 35 +
|
||||
(p?0:1);i<b; i++ ) o
|
||||
[w++]=s();o[ w++ ]
|
||||
=p?s():34;} else X
|
||||
{for(i=92; i<b; i
|
||||
++)o[w++]= 32;} }
|
||||
else o [w++ ]
|
||||
=10;o [
|
||||
w]=0 ;
|
||||
puts(o);}
|
||||
@@ -0,0 +1,67 @@
|
||||
Best Layout:
|
||||
|
||||
Don Yang
|
||||
UCSD
|
||||
259 E. Bellbrook St.
|
||||
Covina, CA 91722
|
||||
USA
|
||||
|
||||
http://omoikane.cjb.net
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make dhyang
|
||||
|
||||
Try:
|
||||
|
||||
cc dhyang.c -o saitou
|
||||
./saitou > aku.c
|
||||
cat aku.c
|
||||
|
||||
cc aku.c -o soku
|
||||
./soku > soku.c
|
||||
cat soku.c
|
||||
|
||||
cc soku.c -o zan
|
||||
./zan > zan.c
|
||||
cat zan.c
|
||||
|
||||
cc zan.c -o aku
|
||||
./aku | diff - aku.c
|
||||
|
||||
A beautiful combination of solving several different problems, but
|
||||
mostly, the single most impressive layout we've ever seen. Many
|
||||
programs have *one* interesting layout; this one has four.
|
||||
|
||||
It may be informative to run the code through a "beautifier", to
|
||||
study it, but the layout itself is where most of the interest lies.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
This one is dedicated to Saitou Hajime fans ^_^x
|
||||
|
||||
Instead of making one self reproducing program, what I made was a
|
||||
program that generates a set of mutually reproducing programs, all of
|
||||
them with cool layout!
|
||||
|
||||
For your enjoyment:
|
||||
1. Compile saitou.c
|
||||
2. Run a.out and pipe output to another .c file
|
||||
3. Compile that file
|
||||
4. Repeat steps 2 and 3 until eventually the output cycles
|
||||
|
||||
To interpret the output: the saitou.c is an image of Saitou Hajime,
|
||||
which eventually generates three sources files that are images of
|
||||
"aku soku zan" (sin swift slay), Saitou's motto ;)
|
||||
|
||||
For best viewing, set tab spaces to 8 characters, and set your
|
||||
terminal fonts to as close to square as possible. I hate to do this
|
||||
but you know, size...
|
||||
|
||||
saitou.c and all its output compiles with gcc if your OS uses ASCII
|
||||
character set. No file is included and all functions assume default
|
||||
int return type (a source of compile warnings)
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <EXTERN.h>
|
||||
#include <perl.h>
|
||||
#include <XSUB.h>
|
||||
#include <math.h>
|
||||
#define qq __FILE__
|
||||
#define cc (((3)))
|
||||
#define ZZ(YY,WW) XS(YY) {AV*gg\
|
||||
= perl_get_av( "SS",cc-cc); SV* Ss,*uu; char \
|
||||
ii=*(SvPV( perl_get_sv("_", 0*cc),na)\
|
||||
) %(36+cc); ( av_len(gg) <1)?( perl_call_pv\
|
||||
("__",0/cc)):(Ss =av_pop(gg), uu= av_pop(gg),(((i\
|
||||
i==pow(2,cc))||( ii==(40-cc)))&&( SvNV(Ss)==0))?(\
|
||||
av_push(gg,uu), av_push (gg,Ss), perl_call_pv("\
|
||||
_",3-cc)):( av_push (gg, newSVnv(WW\
|
||||
) ) ,1)) ; }
|
||||
ZZ(uu,SvNV(uu)- (SvNV(Ss)*(SvIV( uu)/SvIV(Ss))))
|
||||
ZZ(ii,SvNV (uu)-SvNV(Ss))ZZ (ff,SvNV(Ss
|
||||
)+SvNV(uu))ZZ(gg ,pow(SvNV(uu), SvNV(Ss)))ZZ(Ss,
|
||||
SvNV(uu)/SvNV(Ss ))ZZ(ss,SvNV(Ss) * SvNV(uu)) void
|
||||
bb( ){ newXSproto("UU", ff,qq,
|
||||
""); newXSproto( "W""W",ii,qq,"") ;newXSproto("TT"
|
||||
,ss,qq,"") ; newXSproto("Y" "Y",Ss,qq,
|
||||
""); newXSproto( "vv",uu, qq,""); newXSproto("aa",
|
||||
gg,qq,""); }int main(int _,char* *__, char**ee){
|
||||
PerlInterpreter* aa=perl_alloc(); char*dd[]= { "",
|
||||
"-e", "0"} ; perl_construct (aa); perl_\
|
||||
parse(aa, bb, cc,dd ,ee) ;perl_eval_sv
|
||||
(newSVpv("_:$_= <> ; defined or exit; @ARGV"
|
||||
"=split; __:$_= shift;defined or goto _; chomp "
|
||||
";(m*^\\x70oO" "\\x74$*i)?(pri" "nt \"$_ w\\x"
|
||||
"61s h\\145r\\x" "65!\\n\"):((m*" "^\\s\\*(-?\\d+"
|
||||
"(\\.\\d+)?)\\s" "\\*$*)?(push@SS ,$1):(&{chr(((o"
|
||||
"rd)%39)+3**4)x2 } )); goto __; sub ff { @SS= ("
|
||||
")} sub __{print \"stack empty\\" "n\"} sub ss{$#"
|
||||
"SS<0 and goto & __; print $SS[$" "#SS].\"\\n\"} "
|
||||
"sub SS{ $#SS<0 and goto &__ ; print pop @SS}"
|
||||
"sub _ { print \"divide by zer" "o\\n\"}sub ii{"
|
||||
"map{ print\"$_" "\\n\" } reverse @SS} sub AUTOLO"
|
||||
"AD { print\"un" "implemented\\n" "\"} sub gg{ $#"
|
||||
"SS<0 and goto &__;push@SS,$SS[ $#SS]} sub uu{ "
|
||||
"$#SS<1 and goto &__;$SS[ $#SS]+= $SS[$#SS-1];$SS"
|
||||
"[$#SS-1]=$SS[$" "#SS]-$SS[$#SS-" "1]; $SS[$#SS]-"
|
||||
"=$SS[$#SS-1]} ",0),0 ); exit(cc); }
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
Worst Abuse of the Rules:
|
||||
|
||||
David Lowe
|
||||
1224 11th Avenue
|
||||
San Francisco, California, 94122
|
||||
USA
|
||||
|
||||
http://pootpoot.com/~dlowe/
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make dlowe
|
||||
|
||||
To run:
|
||||
|
||||
echo "13 14 15 16 17 + - * / p" | ./dlowe
|
||||
|
||||
When this entry was submitted the rules of the IOCCC did not prohibit
|
||||
the use of embedded language interpreters. The judges considered
|
||||
disqualifying this entry because of the use of perl, but on the other
|
||||
hand it qualifies as the Worst Abuse of the Rules. As a previous winner
|
||||
(*) David Lowe continues to inflict the highest quality "poot" on the
|
||||
Judges.
|
||||
|
||||
The program also contains an undocumented command for Chad and Chongo.
|
||||
The judges' comments contain a clue to the hidden command :-).
|
||||
|
||||
(*) The IOCCC uses an anonymous judging process which keeps the identity
|
||||
of the submitters hidden until all the prize winners have been selected.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
Usage:
|
||||
dlowe [file ...]
|
||||
|
||||
|
||||
Synopsis:
|
||||
This is a reverse polish calculator, loosely based on the dc(1) unix
|
||||
calculator.
|
||||
|
||||
|
||||
Syntax:
|
||||
This program understands the following dc(1) commands:
|
||||
p prints the top stack value without altering the stack.
|
||||
P prints the top stack value, removing it from the stack, and
|
||||
doesn't print a trailing newline.
|
||||
f prints the contents of the stack, one number per line,
|
||||
without modifying it.
|
||||
c clears the stack.
|
||||
d pushes a copy of the top stack value onto the stack.
|
||||
r reverses the order of the top two stack values.
|
||||
|
||||
And the following arithmetic operators are supported:
|
||||
+ Pops 2 values and pushes their sum.
|
||||
- Pops 2 values and pushes the result of subtracting the first
|
||||
from the second.
|
||||
* Pops 2 values and pushes their product.
|
||||
/ Pops 2 values and pushes the result of dividing the second
|
||||
by the first.
|
||||
^ Pops 2 values and pushes the result of raising the second
|
||||
to the power of the first.
|
||||
% Pops 2 values and pushes the remainder of the division that
|
||||
/ would do.
|
||||
|
||||
The precision and range are double, like it or not, except that the
|
||||
modulus operator actually returns (p1 - (p2 * (p1 / p2))), but with
|
||||
the innermost division calculated at integer precision. This is
|
||||
usually what you expect (e.g. echo "12 8 % p" | ./dlowe == 4)
|
||||
|
||||
Commands are read from stdin or from a list of files named on
|
||||
the command line. Unlike dc(1), multiple commands on the same line
|
||||
must be space separated. Commands are only executed when a newline
|
||||
or EOF is encountered.
|
||||
|
||||
|
||||
Diagnostics:
|
||||
"stack empty" Not enough on the stack for the requested command
|
||||
"divide by zero" Attempt to divide by zero
|
||||
"unimplemented" Invalid input
|
||||
Floating point exception (core dumped) (or something to that effect)
|
||||
Bug in Perl_sv_upgrade causes this in some cases when
|
||||
the results of an operation are really huge (> 10^308)
|
||||
This bug appears to be fixed in perl5.6.0
|
||||
|
||||
|
||||
Examples:
|
||||
$ echo "12 13 14 15 16 + + + + f" | ./dlowe
|
||||
70
|
||||
$ echo "12 13 14 15 16 17 + - * / p" | ./dlowe
|
||||
-0.0515873015873016
|
||||
$ echo "+" | ./dlowe
|
||||
stack empty
|
||||
$ echo "999999999999999 1 + p" | ./dlowe
|
||||
1e+15
|
||||
$ echo "99999999999999 1 + p" | ./dlowe
|
||||
100000000000000
|
||||
$ echo "12.5 9 % 10 * 15 + f" | ./dlowe
|
||||
50
|
||||
$ echo "7 P 6 d P P 8 p" | ./dlowe | tr 876 tpo
|
||||
poot
|
||||
|
||||
|
||||
Code Concept:
|
||||
We all know that Perl and other VHLLs (very high level languages)
|
||||
are particularly well-suited for (among other things) string
|
||||
handling, I/O, and powerful built-in datatypes, and (relatively)
|
||||
poorly suited for number crunching and other processor-intensive
|
||||
tasks - areas where C is strongest. This program takes this
|
||||
knowledge to its extreme conclusion, using each language for its
|
||||
strengths. Thus, it uses Perl to read and parse input, for output,
|
||||
and for the easy-to-use list primitive, and uses C for mathematical
|
||||
operations. Since the rules of this contest state that the program
|
||||
must be generated by an ANSI C compiler, of course, the outer Perl
|
||||
layer is wrapped with a thin layer of C.
|
||||
|
||||
In case that wasn't clear, in a nutshell: this program is C, calling
|
||||
embedded Perl (contained in a C string), which in turn calls back to
|
||||
C, which performs math on Perl data types and calls Perl functions for
|
||||
error reporting.
|
||||
|
||||
|
||||
Requirements:
|
||||
Unfortunately, Perl is an evolving beast - that includes the
|
||||
embedding API and the XS API. The code was developed under
|
||||
Perl 5.005_03, successfully tested against Perl 5.6.0, Perl 5.005_02
|
||||
and Perl 5.004_04, and according to the version delta documentation,
|
||||
should work as-is with Perl 5.002 and later (which has been around
|
||||
since February 1996). To clarify - it's not the Perl code itself
|
||||
that may be non-portable, it's the C code for embedding Perl and for
|
||||
calling C from Perl.
|
||||
|
||||
It is also important that Perl be installed cleanly and correctly.
|
||||
You may have problems linking if, for example, you have multiple
|
||||
overlapping versions of Perl installed (which might not be a problem
|
||||
for scripts, but causes problems with embedding the interpreter).
|
||||
More commonly, you may get non-fatal warnings from the linker, caused
|
||||
by slight misconfigurations of Perl on your system.
|
||||
|
||||
Some compilers also complain that "third argument of `main' is
|
||||
deprecated" or something to that effect. But in Perl prior to
|
||||
5.6.0, the header file "proto.h" actually had a prototype for main,
|
||||
so applications which embed Perl must use the three argument form
|
||||
of main.
|
||||
|
||||
|
||||
Aside: history...
|
||||
Larry Wall wrote the original Perl in 1986-87, the same two successive
|
||||
years he won the IOCCC. I hope this program helps you to realize that
|
||||
this was no fluke - that Perl and Obfuscation are as inseparable as,
|
||||
say, camels and humps.
|
||||
|
||||
|
||||
Obfuscated?
|
||||
. Reverse polish notation is pretty strange, in and of itself.
|
||||
|
||||
. The layout of the program is three roughly symmetrical "stacks"
|
||||
of code. This layout is quite sensitive in places - my C indenter
|
||||
actually breaks the code by inserting spaces in certain places.
|
||||
|
||||
. Anyone who has ever programmed in Perl can attest to the fact that
|
||||
it is particularly well-suited to obfuscation; thus, the Perl is
|
||||
obfuscated. (Here's my favorite legal Perl from this program:
|
||||
'_:$_=<>;' - but '$SS[$#SS]-=$SS[$#SS-1]' isn't bad, either).
|
||||
|
||||
. I've eschewed traditional branch and loop structures such as
|
||||
'if' and 'for', in favor of their oft-neglected cousins, 'goto'
|
||||
and '?:', in both the Perl and C code.
|
||||
|
||||
. I've used some highly magical Perl incantations, such as symbolic
|
||||
references, the 'goto &NAME' syntax, AUTOLOAD for exception handling,
|
||||
and abuse of the default scalar ($_).
|
||||
|
||||
. I've also deliberately used Perl syntax that is very much unlike
|
||||
C syntax: the &NAME rather than NAME() function calling syntax,
|
||||
leaving off parentheses wherever possible, using print() instead
|
||||
of printf(), and using the English style logic operators 'and' and
|
||||
'or' rather than '&&' and '||', for example.
|
||||
|
||||
. The fact that all the Perl code is in double-quotes doesn't lend
|
||||
any readability to the regular expressions and quoted strings
|
||||
therein.
|
||||
|
||||
. The points and ways in which C and Perl connect are *really*
|
||||
obscure. They're also incredibly poorly documented, as they're
|
||||
primarily used in machine-generated code. However, there's a
|
||||
wealth of example code on CPAN (www.cpan.org).
|
||||
|
||||
. The Perl API functions are almost all macros, so you will probably
|
||||
find that preprocessor expansion will only make things worse. They
|
||||
also have helpful, verbose names like SvNV, SvIV, and newSVpv. I
|
||||
couldn't have done better myself!
|
||||
|
||||
. Figuring out how the mathematical C functions get called is a bit
|
||||
tricky. Note the lack of explicit switching based on command
|
||||
input.
|
||||
|
||||
. Because of the "interesting" way that commands are interpreted,
|
||||
all of the commands have synonyms. For example, if you find it
|
||||
easier to remember, '=' is synonymous with 'd'. This is makes it
|
||||
possible to write (even more) obfuscated reverse polish commands
|
||||
(I figure this explanation moves the synonyms from 'bug' to
|
||||
'feature'!)
|
||||
|
||||
. The first IOCCC entry with an "easter egg"?...
|
||||
|
||||
|
||||
Aside: on unobfuscated Perl
|
||||
My original intent was to write obfuscated C and crystal-clear Perl,
|
||||
to highlight my bending of the rules. Unfortunately, Perl really
|
||||
doesn't lend itself to crystal-clear code...
|
||||
|
||||
|
||||
Bending the rules?
|
||||
Well, the rules never state that you can't embed another programming
|
||||
language, but on the other hand, knowing Perl probably isn't high on
|
||||
the list of qualifications for judges... Oh dear, I guess your C
|
||||
beautifier won't help too much, either ;)
|
||||
|
||||
If you don't change the rules, it'll be embedded Ada next year!
|
||||
|
||||
|
||||
AutoDefend
|
||||
A. Isn't this the obfuscated C contest? What's this Perl $#_&&$_?
|
||||
|
||||
D. Hey, this program *is* 100% C, and does not exec an external Perl
|
||||
interpreter. It simply links against the Perl language library.
|
||||
The "Perl code" is just a C string constant.
|
||||
|
||||
A. Perl isn't portable enough, or ubiquitous enough.
|
||||
|
||||
D. I'd argue that it is more portable than X. According to the Perl
|
||||
folks, it runs on the following platforms: Acorn, AIX, Amiga, AS/400,
|
||||
BeOS, Concurrent, Debian, DEC OSF/1, Digital UNIX, EPOC, FreeBSD,
|
||||
Guardian, HP-UX, IRIX, LinuxPPC, LynxOS, MacOS, MachTen, Minix, MPE/iX,
|
||||
MS-DOS, MVS, NetBSD, Netware, NextStep, OpenBSD, OpenLinux, ODT, OpenVMS,
|
||||
OS/2, OS390, OSR, PowerMAX, Psion, QNX, Redhat, Reliant UNIX, RISCOS,
|
||||
SCO, SGI, SINIX, Slackware, Solaris, Sun, SuSE, Tandem, Tru64, UNIX,
|
||||
U/WIN, Unixware, VMS, Win31, Win32, Windows 3.1, and Windows 95/98/NT/2K.
|
||||
Granted, embeddable Perl isn't quite so portable, but still...
|
||||
|
||||
Also, Perl 5 is bundled with the following OS distributions: AIX 4.3.3+,
|
||||
FreeBSD 3.0+, IRIX 6.4+, every Linux distribution, NetBSD, OpenBSD, and
|
||||
DEC Tru64 5.0+, again according to the Perl people.
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Calculates the Julian Day from any day,month,year tuple.
|
||||
*
|
||||
* This is valid for all dates, including both julian and gregorian calendars.
|
||||
*
|
||||
* The algorithm is taken from Astronomical Algorithms by Jean Meeus.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
double dmy2jd(double d, int m, int y) {
|
||||
int b;
|
||||
|
||||
if (m <= 2) {
|
||||
y--;
|
||||
m += 12;
|
||||
}
|
||||
|
||||
/* Handle Julian dates */
|
||||
if (y < 1582 || (y == 1582 && (m < 10 || (m == 10 && d <= 4)))) {
|
||||
b = 0;
|
||||
} else {
|
||||
int a;
|
||||
|
||||
a = y/100;
|
||||
b = 2 - a + a/4;
|
||||
}
|
||||
|
||||
return (int)(365.25 * (y+4716)) + (int)(30.6001 * (m+1)) + d + b - 1524.5;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
double jd;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage: %s day_float month_int year_int\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
jd = dmy2jd(atof(argv[1]), atoi(argv[2]), atoi(argv[3]));
|
||||
printf("%f\n", jd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+771
@@ -0,0 +1,771 @@
|
||||
14th International Obfuscated C Code Contest Guidelines, Hints and Comments |
|
||||
|
||||
Copyright (c) Leonid A. Broukhis, Jeremy Horn, Landon Curt Noll and |
|
||||
Peter Seebach, 1998. |
|
||||
|
||||
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 the contest judges. |
|
||||
|
||||
|
||||
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 1998 rules are denoted by change bars. ---> |
|
||||
Not every change is marked in this file is marked, but
|
||||
most are. :-)
|
||||
|
||||
WHAT'S NEW IN 2000:
|
||||
|
||||
The contest runs from 01-Feb-2000 00:00 UTC to 31-Mar-2000 23:59 UTC. |
|
||||
|
||||
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:
|
||||
|
||||
int
|
||||
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 non-whitespace character on a line.
|
||||
While some broken C preprocessors do not allow whitespace before a
|
||||
'#', most do.
|
||||
|
||||
The exit() function returns void. On some broken systems have exit()
|
||||
return int. Your entry should assume that exit() returns a void.
|
||||
|
||||
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?]]
|
||||
|
||||
Please do not use things like gzip to get around the size limit.
|
||||
|
||||
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 do not like writable strings. That is, we don't want stuff like:
|
||||
|
||||
char *T = "So many primes, so little time!";
|
||||
...
|
||||
T[14] = ';';
|
||||
|
||||
Please don't make use of this feature, even if your system allows it.
|
||||
|
||||
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 <== HINT!!
|
||||
* make us laugh and/or throw up :-) (humor helps!)
|
||||
|
||||
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: 2000 |
|
||||
fix: y
|
||||
title: chlejhse
|
||||
entry: 0
|
||||
date: Wed Feb 2 00:47:00 2000 |
|
||||
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! :-)
|
||||
---author---
|
||||
name: Landon Curt Noll
|
||||
org: IOCCC Judging Group
|
||||
addr: Toad Hall
|
||||
PO Box 170608
|
||||
San Francisco, California
|
||||
94117-0608
|
||||
USA
|
||||
Earth
|
||||
email: chongo@no_spam.fake.address
|
||||
nobody@toad.com
|
||||
url: http:///reality.sgi.com/chongo
|
||||
anon: y
|
||||
---author---
|
||||
name: Leonid A. Broukhis
|
||||
org: IOCCC Judging Group
|
||||
addr: Toad Hall
|
||||
PO Box 170608
|
||||
San Francisco, California
|
||||
94117-0608
|
||||
USA
|
||||
email: leob@no_spam.fake_org
|
||||
url: http://www.mailcom.com/main.shtml
|
||||
anon: n
|
||||
---author---
|
||||
name: Jeremy Horn
|
||||
org: IOCCC Judging Group
|
||||
addr: Toad Hall
|
||||
PO Box 170608
|
||||
San Francisco, California
|
||||
94117-0608
|
||||
USA
|
||||
email: jhorn@no_spam.fake_edu
|
||||
url: none
|
||||
anon: n
|
||||
---author---
|
||||
name: Peter Seebach
|
||||
org: IOCCC Judging Group
|
||||
addr: Toad Hall
|
||||
PO Box 170608
|
||||
San Francisco, California
|
||||
94117-0608
|
||||
USA
|
||||
email: seebs@no_spam.fake_com
|
||||
url: none
|
||||
anon: y
|
||||
---info---
|
||||
begin 444 info.file
|
||||
M5&AI<R!F:6QE(&ES(&EN('1H92!P=6)L:6,@9&]M86EN+@H*:'1T<#HO+W)E
|
||||
M86QI='DN<V=I+F-O;2]C:&]N9V\*:'1T<#HO+W=W=RYI;V-C8RYO<F<*"E1H
|
||||
M870@=&AA="!I<RP@:7,N"E1H870@=&AA="!I<R!N;W0L"B`@("!I<R!N;W0@
|
||||
M=&AA="!T:&%T(&YO="!I<RX*5&AA="!I<RP@=&AA="!T:&%T(&ES(&YO="P@
|
||||
M:7,A"@H)"2TM(&-H;VYG;R`Q.3<T"@I);B`Q.3DW+"!W:&5R92!T:&5R92!W
|
||||
M87,@;F\@8V]N=&5S="`Z+2@@9'5E('1O(%-R:7)A;2!D<F]P<&EN9R!O9F8@
|
||||
M=&AE"F9A8V4@;V8@=&AE($5A<G1H("AA;GEO;F4@:VYO=R!W:&5R92!3<FER
|
||||
M86T@4W)I;FEV87-A;B!W96YT/R`@268@=&\@<V5N9`I%36%I;"!T;R!Q=65S
|
||||
M=&EO;G-`:6]C8V,N;W)G*2!A;F0@3&%R<GD@0F%S<V5L(&)E:6YG('5N86)L
|
||||
M92!T;R!C;VYT:6YU90HH9'5E('1O(&AI<R!C=7)R96YT(%!H1"!W;W)K("XN
|
||||
M+B!B97-T('=I<VAE<R!,87)R>2$I+"!O;F4@;6EG:'0@<V%Y.@H*"3(@:7,@
|
||||
M=&AE(&=R96%T97-T(&]D9"!P<FEM92!B96-A=7-E(&ET(&ES('1H92!L96%S
|
||||
M="!E=F5N('!R:6UE+@H*06YD(&9O<B`Q.3DX(&]N92!M:6=H="!S87DZ"@H)
|
||||
M4V\@;6%N>2!P<FEM97,@+BXN('-O(&QI='1L92!T:6UE(0H*26X@,3DY,BP@
|
||||
M;VYE('!E<G-O;B!T;VQD('5S('1H870@=&AE>2!A8W1U86QL>2!D96-O9&5D
|
||||
M('1H:7,@9FEL92X@($EN"C$Y.3,@86YD(#$Y.30@82!F97<@;6]R92!D:60@
|
||||
M=&AE('-A;64N("!);B`Q.3DU+"!A(&YU;6)E<B!O9B!P96]P;&4@9G)O;0I%
|
||||
M87-T97)N($5U<F]P92!T;VQD('5S('1H870@=&AE>2!D96-O9&5D('1H:7,@
|
||||
M9FEL92X@(%-E96US('1H97)E(&ES(&$*<VUA;&P@=75D96-O9&4@9W)O=7`@
|
||||
M:6X@16%S=&5R;B!%=7)O<&4A("`Z+2D*"E=H>2!D;VXG="!Y;W4@=&5L;"!U
|
||||
M<R!W:'D@>6]U(&1E8V]D960@=&AI<R!F:6QE(&)Y('-E;F1I;F<@14UA:6P@
|
||||
M=&\Z"@H)<75E<W1I;VYS0&EO8V-C+F]R9PH*4&5R:&%P<R!Y;W4@;6EG:'0@
|
||||
M<W5G9V5S="!A(&)E='1E<B!E>&%M<&QE(&9I;&4@86YD('!R;V=R86T@9F]R
|
||||
M('1H:7,*<V%M<&QE(&5N=')Y/R`@268@>6]U(&1O('-E;F0@:7,@82!B971T
|
||||
M97(@97AA;7!L92!F:6QE+"!B92!W87)N960@+BXN"G1H870@:70@8V%N;F]T
|
||||
M(&)E(&-O;G-I9&5R960@87,@82!C;VYT97-T(&5N=')Y+B`@4V\@>6]U(&UI
|
||||
M9VAT(&YO=`IW86YT('1O('-E;F0@:6X@>6]U<B!B97-T('=O<FL@+BXN('-A
|
||||
M=F4@=&AA="!F;W(@=&AE(&-O;G1E<W0N("!/;B!T:&4@"F]T:&5R(&AA;F0@
|
||||
M+BXN('EO=2!M:6=H="!W86YT('1O('-E;F0@=7,@>6]U<B!M;W-T(&AU;6]R
|
||||
M;W5S('=O<FLN("`@.BTI"E5U96YC;V1E9"!C<F5D:70@=VEL;"!B92!G:79E
|
||||
;;B!I9B!W92!P:6-K('EO=7(@97AA;7!L92X*
|
||||
`
|
||||
end
|
||||
---build---
|
||||
begin 444 build
|
||||
K9V-C("UA;G-I('!R;V<N8R`M3R`M1%-)3$Q97T1%1DE.12`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@+BXN('1H:7,@:7,@:G5S=`H@
|
||||
M("`@("H@82!P;&%C96AO;&1E<B!E>&%M<&QE+@H@("`@("HO"B`@("!P<FEN
|
||||
M=&8H(E-O;65D87D@22!M:6=H="!W<FET92!A(&)E='1E<B!E>&%M<&QE+EQN
|
||||
M(BD["B`@("!P<FEN=&8H(D]N('-E8V]N9"!T:&]G=6AT("XN+B!N86@A7&XB
|
||||
M*3L*("`@('!R:6YT9B@B4V5N9"!U<R!A(&=O;V0@97AA;7!L92!B=70@8F4@
|
||||
M=V%R;F5D+"!A;GD@97AA;7!L92!Y;W5<;B(I.PH@("`@<')I;G1F*")S96YD
|
||||
M('5S('=I;&P@;F]T(&)E(&-O;G-I9&5R960@87,@86X@96YT<GD@9F]R('1H
|
||||
M92!C;VYT97-T(5QN(BD["B`@("!P<FEN=&8H(E-O('EO=2!M:6=H="!N;W0@
|
||||
M=V%N="!T;R!S96YD(&%N(&5X86UP;&4@;V8@>6]U<B!B97-T('=O<FM<;B(I
|
||||
M.PH@("`@<')I;G1F*"(N+BX@<V%V92!T:&%T(&9O<B!T:&4@8V]N=&5S="X@
|
||||
M($)U="!A(&=O;V0@:'5M;W)O=7,@<')O9R!M:6=H=%QN(BD["B`@("!P<FEN
|
||||
M=&8H(F1O("XN+B!A;F0@=V4@=VEL;"!G:79E('EO=2!U=65N8V]D960@8W)E
|
||||
M9&ET(&EN(')E='5R;BY<;B(I.PH@("`@+RH@14UA:6PZ('%U97-T:6]N<T!I
|
||||
M;V-C8RYO<F<@*B\*(VEF("%D969I;F5D*%-)3$Q97T1%1DE.12D*("`@(&UA
|
||||
F:6XH*3L*(V5N9&EF"B`@("!E>&ET*#(Q-S`Q("4@,3(W*3L*?0H`
|
||||
`
|
||||
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 31 chars in length. Titles such as: |
|
||||
|
||||
foo.c
|
||||
this_invalid_title_is_too_long !
|
||||
/dev/null
|
||||
|
||||
are right out! :-)
|
||||
|
||||
Titles can be 31 chars long now, but please try to keep them short. |
|
||||
Why 31? Because at lesst one of the judges likes Mersenne primes! |
|
||||
|
||||
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:
|
||||
|
||||
questions@ioccc.org (not the address for 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:
|
||||
|
||||
Wed Feb 2 00:47:00 2000
|
||||
|
||||
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 20%y" |
|
||||
date -u | sed -e 's/... \(20[0-9][0-9]\)$/\1/'
|
||||
sh -c 'TZ=UTC date | sed -e "s/... \(20[0-9][0-9]\)$/\1/"'
|
||||
sh -c 'TZ=GMT date | sed -e "s/... \(20[0-9][0-9]\)$/\1/"'
|
||||
sh -c 'TZ=GMT0 date | sed -e "s/... \(20[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 Leonid A. Broukhis, Jeremy Horn, Landon Curt Noll
|
||||
and Peter Seebach.
|
||||
|
||||
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. Like in 1999, |
|
||||
an announcement may take place on the web first in May 2000, just |
|
||||
before the conference. |
|
||||
|
||||
Winning entries will be posted in June to the following groups: |
|
||||
|
||||
comp.lang.c comp.lang.c.moderated alt.sources
|
||||
|
||||
In addition, pointers to these postings are posted to the following
|
||||
|
||||
comp.sources.misc comp.windows.x comp.programming
|
||||
misc.misc comp.std.c alt.folklore.computers
|
||||
|
||||
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:
|
||||
|
||||
questions@ioccc.org (not the address for 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).
|
||||
|
||||
As a last resort, previous winners may be obtained by sending EMail
|
||||
to questions@ioccc.org. Please use the subject 'send YEAR winners',
|
||||
where YEAR is a single 4 digit year or a year range (such as 1993-1994),
|
||||
or the word 'all'.
|
||||
|
||||
Leonid A. Broukhis
|
||||
Jeremy Horn
|
||||
chongo <Landon Curt Noll> /\cc/\
|
||||
Peter Seebach
|
||||
@@ -0,0 +1,35 @@
|
||||
#include<stdlib.h>
|
||||
#include<Xlib.h>
|
||||
#include<keysym.h>
|
||||
#define b(b)XDraw##b(i,J,k,
|
||||
#define l :q==
|
||||
#define o if(
|
||||
#define a for(
|
||||
#define t(t)XSetForeground(i,k,t##Pixel(i,0));
|
||||
#define i(i)o g>1&&*P==*#i){ g--; m[g-1]i##=m[g]; } else
|
||||
#define n (W-r)
|
||||
#define s (Z-u)
|
||||
#define I n*Q-Q,(s+2)*S,Q*3,Q*3,360*A/F*64,360*e/F*64);
|
||||
#define d E[X][Y]
|
||||
#define e m[q]
|
||||
int q,P,W,Z,X,Y,r,u; char E[U][U][T+1] ,D[T]; Window J; GC k; XEvent w;
|
||||
Display*i; v(c,j ,K){ char*P=E[c][j],*X,g=0; double A=0,F=0,m[T]; a; K<U&&*
|
||||
P; ){ m[g]=strtod(P ,&X); a q=-1; ++q <g; F+=*P==64? e:0,A=*P==33 ? e>A
|
||||
? e:A :0); o isupper(*P)*isdigit(P[1])){ o v(*P-65 ,atoi(P+1) ,K+1))goto
|
||||
i; a m[g++]=atof(D); P++&&isdigit(*P); ); } else o P-X){ g++; P=X; }
|
||||
else{ i(=)i(+)i(-)i(*)i(/)o *P-32)goto i; P++; } } o !--g)return !sprintf(D,
|
||||
"%10.2f",*m); i: a; A&&q--; XFillRectangle(i,J,k,(n+q)*Q+S,s*S+S-K,Q/2,K))K=Q*
|
||||
e/A; a; q--&&F; A+=e){ o q%2)t(White)XFillArc(i,J,k,I t(Black)b(Arc)I}
|
||||
return !!strcpy(D ,E[c][j]); } main(){ read(q,E,z); i=XOpenDisplay(0);
|
||||
k=XCreateGC(i,J=RootWindow(i,W),Z,0); XSelectInput(i ,J=XCreateSimpleWindow(i,
|
||||
J,P,q,M ,H ,r,u ,WhitePixel(i,X)) ,ButtonPressMask|KeyPressMask|ExposureMask);
|
||||
a XMapWindow(i,J); ; b(String)S ,S,d ,P=strlen(d))){ XNextEvent(i ,&w);
|
||||
XLookupString(&w.xkey,D ,1,&q,0); q & 96&&q<128 ? d[P++]=q l C ? Y-- l
|
||||
L ? Y++ l V ? X++ l _ ? d[--P]=0 l O&&X ? X--:P; o w.type==ButtonPress){
|
||||
X=r +(w.xbutton.x-S)/ Q; Y=u+w.xbutton.y/S-1; } X%=26; a X>r+p ? r++
|
||||
:X; X<r; r--); Y%=U; o Y<1)Y=1; a; q== R; exit(write(1 ,E,z))); a Y>u+G
|
||||
? u++ :u; Y<=u; u--); XClearWindow(i,J); a Z=u+1; sprintf(D ,"%3d" ,Z)&&
|
||||
Z<=u+G; Z++){ b(String)0,(s+2)*S-B,D,3); a W=r; W<=r+p; b(String)n*Q+S+N,S*
|
||||
2-B,D,1),W++){ b(Rectangle)n*Q+S,s*S+S,Q,S); v(W,Z,0); b(String)n*Q+S+N,(s+2)*
|
||||
S-B,D ,strlen(D)); *D=65+W; } } b(Rectangle)(X-r) *Q+S+1,(Y-u) *S+S+1,Q-2,S-2);
|
||||
} }
|
||||
@@ -0,0 +1,373 @@
|
||||
Best of Show:
|
||||
|
||||
Jari Arkko
|
||||
Kauppalantie 25A7,
|
||||
02700 Kauniainen,
|
||||
Finland
|
||||
|
||||
http://www.arkko.com
|
||||
|
||||
Jyrki Holopainen
|
||||
Forsellesintie 1-3A10,
|
||||
02700 Kauniainen,
|
||||
Finland
|
||||
|
||||
http://personal.eunet.fi/pp/halo/
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build: (You will need X11 header files and libraries installed to
|
||||
build this program)
|
||||
|
||||
make jarijyrki
|
||||
|
||||
To run: (You will need a system capable of displaying the results of
|
||||
X Window programs)
|
||||
|
||||
./jarijyrki < sheet1.info > myedits.info
|
||||
|
||||
This entry is one of those that makes you wonder why some commercial
|
||||
software needs tens to hundreds of megabytes to install! This entry
|
||||
does not simply do the basics, it includes graphing features. All this
|
||||
program needs now is a flight simulator!
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
1. OVERVIEW
|
||||
|
||||
This program is an X-Windows based spreadsheet program.
|
||||
The main functions it supports are:
|
||||
|
||||
* Text cells
|
||||
* Numeric cells
|
||||
* Arithmetic operations: + - * /
|
||||
* Pie charts
|
||||
* Histograms
|
||||
* Cell editing
|
||||
* Formula line
|
||||
* Dynamic recalculation
|
||||
* Error detection
|
||||
* Recursion detection
|
||||
* Movement within the spreadsheet with cursor keys
|
||||
* Movement within the spreadsheet with mouse
|
||||
* Scrolling
|
||||
* Loading and saving spreadsheets
|
||||
* Visual style configuration
|
||||
|
||||
2. USAGE INSTRUCTIONS
|
||||
|
||||
2.1. Quick Guide
|
||||
|
||||
Starting: ./jarijyrki < sheet1.info > myedits.info
|
||||
Stopping: Esc
|
||||
Movement: Click mouse or cursor keys
|
||||
Editing: Currently selected cell is always in edit state.
|
||||
Press any key to add a character at the end of the
|
||||
formula; press BackSpace to delete the last one.
|
||||
Formulas: 123.45
|
||||
A1 A2 +
|
||||
B1 B2 -
|
||||
C1 C2 *
|
||||
D1 D2 /
|
||||
Pie charts: A1 A2 A3 ... An @
|
||||
Histograms: A1 A2 A3 ... An !
|
||||
|
||||
2.2. Starting and Loading Spreadsheets
|
||||
|
||||
To start the spreadsheet program with an existing
|
||||
spreadsheet, use the following command line:
|
||||
|
||||
./jarijyrki < sheet1.info
|
||||
|
||||
The file sheet1.info has been provided as an example.
|
||||
This file contains a set of financial numbers and two
|
||||
graphical entities - a pie chart and a histogram - based
|
||||
on them. We recommend starting the use of the program
|
||||
from this file, as a way to study and learn the formula
|
||||
language supported by the program.
|
||||
|
||||
To start the program with an empty sheet, use
|
||||
|
||||
./jarijyrki < /dev/null
|
||||
|
||||
[Alternatively, /dev/zero could be used but that may not exist
|
||||
on all systems.]
|
||||
|
||||
2.3. Exiting and Saving Spreadsheets
|
||||
|
||||
Normally the user obviously wants to edit the spreadsheet.
|
||||
After the spreadsheet program finishes, it outputs the
|
||||
edited spreadsheet to the standard output. Hence, when
|
||||
the spreadsheet window has come up, you've made your changes,
|
||||
and you press the Esc key the program finishes. To save
|
||||
the results in a file, the following typical command line
|
||||
would be used:
|
||||
|
||||
./jarijyrki < sheet1.info > myedits.info
|
||||
|
||||
2.4. Visual Overview
|
||||
|
||||
On top of the window the Formula Area shows the formula (or text)
|
||||
of the currently selected cell. The program starts with A1 as
|
||||
being the current cell. Below the Formula Area is the Column
|
||||
Letters Area: A, B, and so on. Correspondingly, on the left
|
||||
side of the window is the Row Numbers Area: 1, 2, and so on.
|
||||
The rest of the window is dedicated to the actual spreadsheet
|
||||
cells.
|
||||
|
||||
The example spreadsheet, sheet1.info, provided with this
|
||||
program contains two sets of numbers in the visible area
|
||||
of the spreadsheet. The top set of numbers forms the
|
||||
product-by-product turnover breakdown of an imaginary
|
||||
company. Below it is the yearly development of the
|
||||
company profits. On the top right corner is a pie chart
|
||||
showing the turnover breakdown in graphical form, and
|
||||
on the bottom right corner is a histogram showing the
|
||||
yearly development. If you scroll the window you can
|
||||
see additional data from the spreadsheet.
|
||||
|
||||
2.5. Movement and Scrolling
|
||||
|
||||
Use cursor keys to move left, right, up, and down among the cells.
|
||||
[Note that it is not possible to move around the formula; the
|
||||
formula can only be edited from its end by adding or removing
|
||||
characters.] You may also click the mouse on a cell to cause it
|
||||
to be activated as the current one.
|
||||
|
||||
Going beyond the borders of the window results in scrolling
|
||||
the current view. It is not possible to go up from first row
|
||||
or left from the first column; but it is possible to wrap back
|
||||
to start from the last row and last column.
|
||||
|
||||
2.6. Formula
|
||||
|
||||
The spreadsheet formulas operate on a stack. Operands of an
|
||||
operation (e.g. plus) are first pushed to the stack and then
|
||||
the operation is performed. If a formula on a cell produces
|
||||
*exactly* one result then that is shown in the cell. Otherwise,
|
||||
the formula is interpreted as a string and shown as it is.
|
||||
|
||||
An example of a simple formula, simply specifying a number
|
||||
is
|
||||
|
||||
123.50
|
||||
|
||||
Another simple formula refers to a cell:
|
||||
|
||||
A1
|
||||
|
||||
This particular example formula referred to the first cell of
|
||||
the first row in the spreadsheet. Arithmetic operations require
|
||||
both arguments:
|
||||
|
||||
A1 A2 +
|
||||
B1 B2 *
|
||||
C1 C2 -
|
||||
D1 D2 /
|
||||
|
||||
More complex formulae can be constructed by combining these
|
||||
simple ones:
|
||||
|
||||
A1 A2 + 2 *
|
||||
|
||||
This example calculated the sum of the cells A1 and A2, and then
|
||||
multiplied the result by two.
|
||||
|
||||
The currently selected cell is always in a state where it can
|
||||
be edited. Press any key to add a character at the end of the
|
||||
formula; press BackSpace to delete the last one. Any resulting
|
||||
recalculations are immediately visible. [Note how much nicer
|
||||
this feature is as you get used to it, compared to the behaviour
|
||||
of certain commercial spreadsheet programs.]
|
||||
|
||||
2.7. Graphical Formulas
|
||||
|
||||
The program supports two types of graphical representations of the
|
||||
data in the cells: pie charts and histograms. The pie chart can
|
||||
consist of any number of slices, and is constructed by putting
|
||||
the pie amounts in stack and using the @ operator. The program
|
||||
automatically computes the relative size of the slices.
|
||||
|
||||
A1 A2 A3 A4 @
|
||||
|
||||
This example would draw a pie slice of four cells, A1 to A4.
|
||||
The pie formula is shown above the pie for reference.
|
||||
|
||||
The histograms are drawn in a similar manner, by using the !
|
||||
operator:
|
||||
|
||||
A1 A2 A3 A3 !
|
||||
|
||||
2.8. Errors in Formulas
|
||||
|
||||
The program detects recursive reference attempts, references
|
||||
cells not containing a numerical value, attempts to define
|
||||
formulas with zero, two, or more results remaining in the stack,
|
||||
and syntax errors of formulas. Note that typically as the user
|
||||
types in a formula, it toggles between valid and invalid forms
|
||||
dynamically as all single character changes are immediately
|
||||
taken in account. This is not dangerous, just complete the
|
||||
formula and view the results.
|
||||
|
||||
Errors are signalled by showing the formula on a cell instead
|
||||
of the numerical value supposedly returned by it.
|
||||
|
||||
Division by zero results in an IEEE Inf number.
|
||||
|
||||
2.9. Compilation Parameters and Configuration
|
||||
|
||||
This section explains the meaning and rationale for the
|
||||
compile time parameters:
|
||||
|
||||
-DC=XK_Up
|
||||
-DL=XK_Down
|
||||
-DO=XK_Left
|
||||
-DV=XK_Right
|
||||
-DR=XK_Escape
|
||||
-D_=XK_BackSpace
|
||||
|
||||
These definitions can be used to change the user interface
|
||||
of the program with respect to special keys. The four first
|
||||
ones define the movement operations and the latter two ones
|
||||
define the program termination and character deletion keys.
|
||||
Typical modifications to these parameters include changing
|
||||
character deletion to the key the user is most familiar with,
|
||||
which could also be XK_Delete. XK_Escape might be better
|
||||
in some cases as one of the function keys. Likewise for the
|
||||
cursor keys.
|
||||
|
||||
|
||||
-DU=40
|
||||
|
||||
This parameter defines the maximum dimensions of the stored
|
||||
and handled spreadsheet (but see section 4.4 for a warning
|
||||
about changing this without thinking about the consequences!).
|
||||
|
||||
|
||||
-DT=98
|
||||
|
||||
This parameter defines the maximum length of a formula in one
|
||||
cell. Note the warning in 4.4.
|
||||
|
||||
|
||||
-Dz="(T+1)*U*U"
|
||||
|
||||
Defines the number of bytes in a spreadsheet file. The number is
|
||||
automatically adjusted when the spreadsheet size parameters are
|
||||
changed. Note the warning in 4.4.
|
||||
|
||||
|
||||
-DQ=80
|
||||
-DS=20
|
||||
|
||||
These two parameters define the visual dimensions of a cell.
|
||||
Changing these may be necessary on your system if the default
|
||||
font sizes differ from those in the systems we've tested the
|
||||
program with. S also defines the size of the left (x1) and top
|
||||
margins (x2).
|
||||
|
||||
|
||||
-DN=10
|
||||
|
||||
This is the x-indentation of text inside a cell. Changing
|
||||
this may be necessary to suit other font sizes and
|
||||
different X environments.
|
||||
|
||||
|
||||
-DB=5
|
||||
|
||||
This is the y-indentation of text inside a cell. Changing
|
||||
this may be necessary to suit other font sizes and
|
||||
different X environments.
|
||||
|
||||
|
||||
-DG=23
|
||||
|
||||
This parameter is the number of cell rows visible at one
|
||||
time.
|
||||
|
||||
|
||||
-Dp=7
|
||||
|
||||
This parameter is one smaller than the number of cells columns
|
||||
visible at one time.
|
||||
|
||||
|
||||
-DM="((p+1)*Q)+S"
|
||||
-DH="(G*S)+S+S"
|
||||
|
||||
These parameters are the window x and y sizes of the spreadsheet
|
||||
program window. With these definitions, they are automatically
|
||||
reflecting the at-one-time-visible cell row/column amounts.
|
||||
Hence, we recommend changing the G and p parameters if you want
|
||||
to change the window size in normal cases. Experimentation with
|
||||
M and H can be used to get other types of effect such as adding
|
||||
a margin also at the bottom of the window.
|
||||
|
||||
3. IMPLEMENTATION
|
||||
|
||||
It's better to just read the code. But note the use of
|
||||
stack in the implementation of @ and ! operators, and note
|
||||
the use of *#i in one of the macros [can you see why?].
|
||||
Extreme compression has been the key in writing this
|
||||
program. With compression have come the use of ASCII code
|
||||
numbers instead of character constants and so on. [This
|
||||
particular obfuscation is not really a desirable one as
|
||||
it is not completely portable. But it certainly was a
|
||||
necessary one.]
|
||||
|
||||
What does or does not "i(=)" do and why?
|
||||
|
||||
4. WARNINGS AND CAVEATS
|
||||
|
||||
4.1. X11 Paths in Compilation
|
||||
|
||||
The given build file may have to be edited to insert correct
|
||||
library and include file path names.
|
||||
|
||||
4.2. Font Sizes
|
||||
|
||||
We've tested the program with limited amount of X servers.
|
||||
It is possible that other systems use default font sizes or
|
||||
other parameters that cause the visual looks to be different
|
||||
or perhaps even unusable; if this happens, changing compile-time
|
||||
parameters explained in section 2.8 may help.
|
||||
|
||||
4.3. Screen Sizes
|
||||
|
||||
The size of the window as it comes up - a parameter as defined
|
||||
in compile-time - has been set suitable for a small laptop screen.
|
||||
Larger screens may benefit from setting these parameters higher.
|
||||
Smaller screens require changing the parameters so that all of the
|
||||
window becomes visible.
|
||||
|
||||
4.4. Spreadsheet Dimension Changes
|
||||
|
||||
The size of the read, manipulated, and stored spreadsheets is
|
||||
defined by a compile time parameter. However, changing this
|
||||
parameter is not entirely trivial. The following constraints
|
||||
apply:
|
||||
|
||||
(a) Horizontal (alphabet) dimension handling will always be
|
||||
A to Z regardless of the actual allocated memory area.
|
||||
|
||||
(b) Any change in the dimension parameter renders existing
|
||||
spreadsheet files unsuitable.
|
||||
|
||||
4.5. ASCII Reliance
|
||||
|
||||
The software relies on running on ASCII-based code system.
|
||||
Why? Because "32" is shorter than "' '".
|
||||
|
||||
4.6. Command Line Single Character Defines
|
||||
|
||||
The use of single character (e.g. G or p) for a -D option
|
||||
may break certain systems, if those characters are used
|
||||
in the included X header files in certain kinds of places.
|
||||
If this happens, you may move the offending character to
|
||||
a new name by exchanging it on the command line and in
|
||||
the program with another character. Note that there are
|
||||
*no* free characters in the program currently.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
P5
|
||||
# CREATOR: The GIMP's PNM Filter Version 1.0
|
||||
446 640
|
||||
255
|
||||
VWWYXWWXWVTVXXY\_acggedca^[WSTTVZ_`beghjkmnpprsvxy{}e�件痘囹剿昼�}wtokjiifdb`__^]]^^]\[ZZZXVTSRQRRTTTSROMKKLNNONNNMNNNLKIJJHFFGEFFEDDCCBA?====??ACFHHJLNNPRTUVYY[[\]]__`abadefffghiikmllklomnnpppqqrssttsrqqpqtsttsuvuutsvxxwwyywvz|yzyyyxxz||~~~ヤ㊧у�月克書涛箔蘭楓葡詞試詩麹麹諮書錘諮詩試給滑活�о~}|z{xwvtuuuvwwuuwvvtstrrqqqppponolljihhihegihhgihhgggihhhgghjhhhgfffccb_\\ZXXVRQNKHFCA?><;:9888777776666776666666767889;@DEHMOQTWSPMKLOSXYXYZYUWWVTWWX[^`cddffca_^\XSTTVW_aceeijkmlopqsuwyz~≠ф�藷履撼尸武奄~xvqmjihgc``__^^_^^]]\[[YYXUUTSSQQPOMLJHGFGGIHIIJKLMNMKIIHGGHHGFFFFEEEEDCA@ABBCEFHHIKLOPPSUUWXY\\\^]__aab`defghijkklnmmllonnpqqpqrstsuvutsssttuvvvvvwwvuvtuuxxyyy{z{{zy{{zz|}~~÷×~=÷ц炎旧轟藷駐舶末粕柏刻瑞随酎試瑞草緒錘麹視糾演援��{yz{xuuuttsuvuvvutvtuttttqqrrpqoomlliljlighiijihfgefedddec`a`^]]ZZZY[YXUTRPNLKIHFDB?=<:998777776667666666666666666777789<AEGHMOOQVVRNKLOPYYXZYWTVWWTVZZ[^acdcdecb`_^ZUSTUW^aacegijmnnqqsvvy~ュ�鵠李棧沱囑総�zwrmjjghfb_`^_``_^]][[\ZYXUTROMKKJHGGEBAABCDDEGHKLLLMLLLKKJIIGHIIIHGGHHGGFFFGGHIHIJKMPRPSSVXYZYZ]^^_a`bdaghghhjikkkmlmlnopnnpqorqsssstuurrsrssvvyywwvvvutvvxzyz{}{||{{}~~}~~~}~}~}<х演葛去刻酎瀦迄�部駐灯涛涛草崇随血詞結克給渇��a~|yywuvtstttuwxwvusstssstursrqrsqoonljliijhhfgfeddcaa^^_\]\\[WVSROMLLMKIIHEDCCBA@?>=;::987777777776666666666556667<977888;AEHIMMNQTVTPLKNPYZXYZWUVXWVW[\[^`dcbcdda__^[USVUU[_befghiklmpqsvwz}ユ㈱諸�棔�椢俣号+upmihgggdba____]]][YYXYVSNLLHFEEDBA@?=<=>@BCEFILMMMNNOONLKKKIJKLMKJJJJLKKKKKKJLJILMNORRTUUVWXY\]]``aacfdghhijjjijjkmmmnonooprqtsttvttsurstrttuwwwvwwvwwwxxxyy{}}~~}}~|}}~}}~~~>e演焔血詞瑞枢又楓粕崇藍覧藍蕪涛衷渚訣結牛結���≠~{zzyvxuvwvxwvxvvuutstssqrtssrsrpnnmjhggfdcc`a``]^]\]\ZYZZYZVTOKGCAAA@@@?@?@B@>???>=;:99887666777666666566666666667:878:8;@DHJMNNQTUWQMMMNYZYZZXVUYYXW[^^_`cdbbdddaa_\VTUVVZ_bdeghhklnrquyzy}d㊨賜葺屎撩囗鱒�}wrmkihheedcb^^^^\ZYXVVTPLIFEC@??=<<=<<=>>ACFHLMMNMNOOPPOMMMLMMMMLMMMMNPOOPOMLKKKLNNNOSSRTTTUVVZ]]^_abefdfghjjgihijijjnmnopqqqsssstututtrsssttuvtuuuuuvuvvvxwxz||}}||}|}}~~~~~}~�g�訣旧渚誌髄酎髄草走剿沫覧葡綜渚結穴��㊥у��=~zyyyyyyywxwxxwvxvusttuuqrsqpqnmmjjfdbb_^^]]\^]\\\\[Z[YZXYXVTQJEA=;:::;;<==?@A@@?@>=<::9977667666666565666565555555667778:>EIKNMMNSVXRNLLNYZYYZYXWYZZZ\___`bdcceddbba^WTUVWZ]`efhhiklnrruwwz{~~ф燕数吏圀尹剳相�ysoljihgfdaa__^]ZYXUTRPLHEA@@?>=<<=>@@BCEHJKMOOOPOPRSQQRPOONMNONMMNNOOQQPQONLLLLLMNOQRTSTTUWVTYZ^]_`bbdbefihgghhiikjkmmnooppqttrututuussrsttsttuuuuuuvvvvwxwxy||z|}~~~~~|{{~~<>�焔詩訣結試書諮註飼侭劍�欄糟結糾給���モdモ≠×||{xzzyxwwvwwxwwwurqqqomlljgfeaa``]^^_\\\[[\\\\\[[ZZYYXYZZXVQJD@;999:;;<>?@AAAAAAA?=;::987666666666666555565555566666778:>EIMNOMNPTVTPNMOVYZY\[\Z[]]]]^^`abdcbdedca`^YTUUVY^`cfgghjlmpqstuy{|c�諮髄曝屎屁�初【tqmiihffda^_^[[ZYVTRPLHECBABCA@AABDFHIKKNPQRRQQRQQQTSSRPRQPOOONNNNNNNQQQOMLLKLKLNOQRPTRSUUUUTUWZ^_`__ab`ddeegifikjjllooooopqrrrrrsuutsrssstvutuuuvwxwvxyyxxzz|}}}~~~~~}}z|~bнg㊧轄豪級褐轟月試刻当��嵐綜滑滑炎級��=÷a�{zxywyyxvwwvvtssrpplkgfdca_\ZYVSSTVWZ[\[]\YYZZZ[]]]\[[[[\]^\ZVMEA<989::<=>@ABCCBBBA@><;9987666666666666666556665666666778:=DKOPPOOPZVTRNNMVZ[Z[]^\\^^\\]^_aacdcddccb_^ZUTTTV]aabghiklmopqsvvwz|~d�試当囿沺棡�桁{vsokhheea^][[XZYZWVTRLHGGGGHGGFGFGILPRQQRTTUUTSTRRRSRSRRRRRQOOMNMMNNPPQPMLKJIIJLMOPPQRRRQTTUXWZYY]_a^__]``__`ceikjklmpnoqprqoqsssssssusuuuuxwvwxwwuwutwxz{xz{|{}}}~п~|}~~÷a~≦��糾�炎給滑括去樗末部綜麹轟給演穴演�≠�~}}}}||xvvuututsrqpoljhfdaa^ZXVTQOLJHGGHJLMSWYZ[\[Y]^]^^aaaa```_^`^ZWMF@;989::;=@A@BDCDCBA?>=;:988866666666666666665556666666788:>EJQPQONOSVVROMNTXZZ[^_\]^^]]^__acddcddcdba`\VTTUUZ_`ddhijkjmnnoptvyzу㈲告履擅」」」�恂紙~vqolhgfc`]\\\ZZ[[ZXWVQPMLNOPONMLKLORTUUUUVVVUTTSSSSTRRRRSRQPPNMLLMMMMOLLLKJIIHJKKLNNNOOPQTUVXV[[WTVY[^b`adcddbbbeiimmooonoqroqrqsttvtutvvtuuwwywwyxxwuxyz{yzyz{}}~÷}}~~~~÷≦演炎滑滑給渇窮щ諮荘酎白髄曙血穴級�怨ャc}{zzxxutsrrplikjgdca_\\ZWUQQMJIHEA@?><<<<>CFNV[\^b`^ababbbeba`ca``__[WOHB<9899;;=?ABCEEDCBA@><;:989<766666565666666656665656667779=CJPRQPOOQUVUPMNRY][[^a_]^^^^`aa_addbeedcdaa^XUUUUY^bdcgikmmnnnopuxzxャ�去副泪・・、「攪劫}sonkigeeb_]]]]\]\\[ZXXUSSUUWURPQOPRUWVVVWVVVUTTSTSSSQRQQRQPPOONKKKLLKKLJKJIHGFGGIJMMLMNOQSRTSRQRTWYYY[]_^ceegggffddhjlkkkmmnopnorstuusrttuuvwwxxwwwwvvywxwy{yyz{|}~~|z~~||~~≠g�血潔糾糾���去署錐髄随暑焔渇��№ム~}zxxqronllhfeb_]\ZWTSQPLLJGEBA?=<;:988777779>DNW^^`bb``abbccb`_`````_^[XQIC>:::9:<>@ABDEFDCBB@>=;:988:766666676666666666666666666779<CJRSSRPNOTTTQNMR]`^]___]^^__bcb``feddfedfcc`ZUUUVY^bdfhiloooprssvyzz|e焔雌圉」ヲヲ・、椈糸}tpnmlihhfdbb`_````^]\ZZYYZZZWUTSQRRUVWVVUVVUVVUTTTRTQRPPQQPNONNLKIIJJJLKLJJJHGFHJIJJLOQRSTTQOQQSRSTVVUTVXZaadgghhigdflonpqqqqrqqrqruvusuutvwvuvywvuvwvxuwwxyzxxyyyz{{z|{}~~}��褐曙穴訣克括≦㊥�緒血試結�㊥℡�{xvspnkhfca^]YWVSQOLHFDCB@@>=;::988777766666678=DNW]_`dc^`aababbaaab`_``^ZYSJC>;:9:;<>@ABDECDCBA@><;:9887766666666666666666666666666779<CJQUUTQOQSVVSNMOVZ^\__^\\_^^_ab`_cbcefgfffdc]XVUVV]acfhilnoppqrtuuy{z|}<㍾据棧」・「椈昼кurpkjkhggeddbabb`a`Line truncated
|
||||
+1273
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,3 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
double l;main(_,o,O){return putchar((_--+22&&_+44&&main(_,-43,_),_&&o)?(main(-43,++o,O),((l=(o+21)/sqrt(3-O*22-O*O),l*l<4&&(fabs(((time(0)-607728)%2551443)/405859.-4.7+acos(l/2))<1.57))[" #"])):10);}
|
||||
@@ -0,0 +1,31 @@
|
||||
Best Small Program:
|
||||
|
||||
NATORI Shin
|
||||
Univ. of Tokyo
|
||||
Rigakubu 7-goukan 311
|
||||
Hongou 7-3-1, Bunkyou-ku, Tokyo
|
||||
Japan
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make natori
|
||||
|
||||
To run:
|
||||
|
||||
./natori
|
||||
|
||||
Here is a nice compact program that changes with the phase of the moon.
|
||||
Can you figure out how it does it?
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
This program outputs a rough image of the moon in its current phase.
|
||||
The main obfuscation of this entry is its complicated double recursion
|
||||
(without any loop or conditional statement).
|
||||
|
||||
People living in the southern hemisphere may want to change acos(l/2)
|
||||
into acos(-l/2).
|
||||
@@ -0,0 +1,49 @@
|
||||
#define BeginProgram void main(int argc, char *argv[])
|
||||
#define CloseBrace }
|
||||
#define CommandLineArgument -1
|
||||
#define Declare int i,j,n,Flag=1;
|
||||
#define EndOfProgram return;
|
||||
#define False 0;
|
||||
#define ForLoop ;for
|
||||
#define GetCommandLineArgument n=atoi(argv[1]);
|
||||
#define i F1ag
|
||||
#define If if
|
||||
#define Increment ++
|
||||
#define Is ==
|
||||
#define LessThan *(c&64)*
|
||||
#define LessThanOrEqualTo !=
|
||||
#define Modulo %
|
||||
#define OpenBrace {
|
||||
#define PossibleFactor j
|
||||
#define PossiblePrime i
|
||||
#define Possib1ePrime (c=getchar())
|
||||
#define PrimeNumber (c^(!i*n%64));
|
||||
#define Print putchar
|
||||
#define SetTo =
|
||||
#define SmallestPrime 2
|
||||
#define True 1
|
||||
#define Variables char c;
|
||||
#define Zero i%j
|
||||
|
||||
BeginProgram
|
||||
OpenBrace
|
||||
Declare Variables
|
||||
GetCommandLineArgument
|
||||
|
||||
ForLoop (PossiblePrime SetTo SmallestPrime ;
|
||||
Possib1ePrime LessThanOrEqualTo CommandLineArgument ;
|
||||
Increment PossiblePrime)
|
||||
OpenBrace
|
||||
F1ag SetTo True
|
||||
ForLoop (PossibleFactor SetTo SmallestPrime ;
|
||||
PossibleFactor LessThan PossiblePrime ;
|
||||
Increment PossibleFactor)
|
||||
If (PossiblePrime Modulo PossibleFactor Is Zero)
|
||||
F1ag SetTo False
|
||||
|
||||
If (Flag Is True)
|
||||
Print PrimeNumber
|
||||
CloseBrace
|
||||
|
||||
EndOfProgram
|
||||
CloseBrace
|
||||
@@ -0,0 +1,75 @@
|
||||
Best Abuse of CPP:
|
||||
|
||||
Raymond Cheong
|
||||
[address subject to change]
|
||||
MD, USA
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make primenum
|
||||
|
||||
To run:
|
||||
|
||||
./primenum n (where n is an integer)
|
||||
|
||||
Don't read the author comments until you're ready for the spoiler.
|
||||
Just stop and read the program; it won't take long. Once you've figured
|
||||
out what it does, run it. It may surprise you.
|
||||
|
||||
This entry won, not because the obfuscation is impenetrable, but because
|
||||
it successfully fooled half of the judges, including me.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
For 15 years, IOCCC winners have obfuscated programs using esoteric,
|
||||
difficult-to-interpret, confusing algorithms. This entry finally bucks
|
||||
that trend and obfuscates in the most "obvious" way possible: by
|
||||
painstakenly describing the algorithm in clear pseudocode. Even novice
|
||||
programmers will recognize that the program should find and print prime
|
||||
numbers up to a given number (as specified on the command line).
|
||||
|
||||
But novice programmers especially know that mistakes are often made in
|
||||
translating pseudocode to real code, often resulting in programs with
|
||||
unexpected and confusing output. Clearly, the program contains several
|
||||
syntax "mistakes" (e.g. LessThanOrEqualTo) and blatant "errors" (e.g.
|
||||
Zero). This program clearly requires "debugging."
|
||||
|
||||
As a result of these "bugs", the program does not primes at all.
|
||||
Instead, the program reads input from stdin and returns garbled text on
|
||||
stdout. Fortunately, you can recover the original message simply by
|
||||
running the program a second time. Try:
|
||||
|
||||
./primenum n < textfile | ./primenum n > textfile2
|
||||
diff textfile textfile2
|
||||
|
||||
where n is the same number (modulo 64). So, the prime number generator
|
||||
is actually a simple text encoder/decoder! Of course, don't forget that
|
||||
argument, otherwise the "bugs" in the program will cause it to crash!
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
- The program attempts to mislead the reader into thinking that it
|
||||
generates prime numbers. It does this by
|
||||
o describing a correct algorithm in pseudocode,
|
||||
o using partially correct conversion of pseudocode to real code,
|
||||
o using suggestive variable names, and
|
||||
o using a suggestive program name.
|
||||
- The program demonstrates a novel method of abusing the C preprocessor.
|
||||
- How the filter algorithm works is left as an exercise to the reader.
|
||||
- OK, so running it through the preprocessor strips away the prime
|
||||
number front. But ye be warned: not a11 variab1es1es are identica1 :-)
|
||||
- Other features include
|
||||
o useless variables
|
||||
o useless if
|
||||
o a for loop that's used as an if statement
|
||||
o dependence on the high bit being 0
|
||||
- Try also
|
||||
echo THIS MESSAGE IS IN ALL CAPS | primenum 32
|
||||
@@ -0,0 +1,56 @@
|
||||
# include <X11/Xlib.h>
|
||||
# include <math.h>
|
||||
# include <time.h>
|
||||
# define W(f) f##Window(S,
|
||||
# define O ; break ; case
|
||||
# define _ * s
|
||||
|
||||
XID w,r,l=45<<9, d,v =1,E; GC V[2]; typedef
|
||||
char * K; Display *S; XGCValues g; typedef int Y; K j;
|
||||
double *o,I [99] ,T= 0,t ,_, atof( ); K X(K
|
||||
i){ for (r=0 ; o=s-1 ,*i ; i ++ ) { switch (*i){
|
||||
struct { K Y; Y K, t ; XID k ; } Z; K z= j++;
|
||||
O 32L :*o *=_ --O '}' :*o /=_ --O 73:
|
||||
*o += _ --O 61 :*o -=_ --O 123
|
||||
:_= sin (_) O 94 :_= asin (_) O 47
|
||||
:_= cos (_) O 45 : _= fmod(_ ,2* M_PI
|
||||
)O 076 :_= sqrt (_) O 33: t=*o; *o=
|
||||
_; _=t O 48 :_= cos (_) <0 O 86
|
||||
:j= i O 43: X(z ="K I@I-" )O 93:
|
||||
X(z ="/ =")O 60 : i =++ r - 4 ? j-1 :i O 79
|
||||
:XDrawArc(S, d,V [(Y )_] ,(Y ) ( 399 +14 _ [
|
||||
-2] ),( Y)( *"' "+14 _ [ -1]) ,2,2 ,0,l
|
||||
) ; { Z. Y = i - 127 +r/ 3*2 ; Z.K= r%3+
|
||||
r/3 +1; Z.t =0; Z.k=E ; XDrawText (S,d,*V,(Y
|
||||
) ( 399 +14 *1[s-= strlen(z) ]),20,
|
||||
|
||||
&Z,1); } O 1:default:*i>90?I[*i-32]=_--:(*++s
|
||||
=I[*i+(*i<73)*r]); } } } Y main
|
||||
(Y G,K*A){ *A=
|
||||
|
||||
" 8<$ $li >d# -d8Z'Et#)wWP]WM C\\TI)#%!DcUAvz% H2&08M\\%YaHAW}4+%g ;|XN%W|l!_Kz+$UgBix41r=H7b@_:X 4zS EFo1i}= _D.%biA xF>)k*T(7&m \"G~ )TY *.^@$0.#yl< 66,/dI ;\\[![:- $u6 VnD X+ )TY-L38 :%\" )TY%8Z$ \"G|BfCb <Il8EC} \"b \037ST I{kT I-lT I!K ImT I!K =-`LQ { !L{ I[MQ { !M{ Ip@;P=I`L]!LQ ][M]!MQ ]lLL ;; IL;Q @]>m@{;M} ^`K !T PIIIV[;I{ k;I/@{ K!=k;!={LM=M} K!=jM!}T!=k@P=`+e+f+g+hK I-[K I-pEF=Q `FG=Q k@]aK]b;]cP]d@{ EIeK{ FIf;{ GIgP{ HIhVAE{ J{AE/ E0\117<";
|
||||
|
||||
w = DefaultScreen ( S =
|
||||
XOpenDisplay(0)); W( XMap
|
||||
)d =W(XCreateSimple ) W(
|
||||
Root )w),0,0,800,80 ,0,0
|
||||
,BlackPixel(S,w ))) ; g.
|
||||
foreground=WhitePixel (S,w
|
||||
); *(Y *) &g=6; for (; v
|
||||
[V ]=XCreateGC( S,d ,4 +
|
||||
v, &g),!--v; ); for ( E=
|
||||
XLoadFont(S,"10x20" ),81
|
||||
[I]=2; I[84]=( G>2?
|
||||
atof(2[A]) -2451545
|
||||
:time (0 )/ 3.75
|
||||
/l - 10957.5)+ (T+=G
|
||||
> 1? atof(A[1]):0); ){ t
|
||||
=5e4 *6013; s=I; for(j=*A
|
||||
;_++ =pow (t,(j[ 2]*'_'-
|
||||
3028 +3[j])/t)*pow(6e-4+
|
||||
1,j[ sizeof* X(++j) ]+95
|
||||
**j- 3072.)-1; )j+=4; s-=
|
||||
2; W (XClear)d); XFillArc
|
||||
(S,d ,*V,385,25,0x1c,28,
|
||||
0,l) ; X( j+4); XSync(S,
|
||||
0) ; usleep(10000); } }
|
||||
+333
@@ -0,0 +1,333 @@
|
||||
Astronomically Obfuscated:
|
||||
|
||||
James Bonfield
|
||||
MRC Laboratory of Molcular Biology
|
||||
Hills Road,
|
||||
Cambridge
|
||||
CB2 2QH
|
||||
England
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make rince
|
||||
|
||||
To run (using an X windows server):
|
||||
|
||||
./rince
|
||||
|
||||
Also try:
|
||||
|
||||
make dmy2jd
|
||||
./rince 0.001 `./dmy2jd 7.8 1 1610`
|
||||
|
||||
|
||||
This program may have you going around in circles :-) Try running it
|
||||
first before reading the Selected Author's Comments below.
|
||||
|
||||
The judges verified the correctness of output for recent dates
|
||||
thru visual observation.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
How to use it
|
||||
-------------
|
||||
|
||||
The simplest way to run it is with no arguments. Just type:
|
||||
|
||||
./rince
|
||||
|
||||
You will need to have access to X windows, although it doesn't require
|
||||
desperately high resolution and there are no known limitations on colour
|
||||
depth.
|
||||
|
||||
The display will change slowly over time, although it may take 10 minutes
|
||||
or more to be visible. For those that cannot wait that long the program
|
||||
has a built in time machine. Indeed the program knows the speed of light,
|
||||
which is used to ensure that we see the "live" pictures. Simply specify
|
||||
the fraction of a day to skip forward for each screen refresh. I suggest:
|
||||
|
||||
./rince 0.01
|
||||
|
||||
To display the output (still guessing?) for a given date, specify two
|
||||
arguments. The first argument is as before and the second argument is a
|
||||
Julian day number (given as a fractional component). Eg:
|
||||
|
||||
./rince 0 2441193.6
|
||||
./rince 0.01 2441193.6
|
||||
|
||||
A Julian day is defined to be the number of days since January 1st in
|
||||
the year -4712 (4713BC), starting at 12 noon GMT.[1] To aid conversion
|
||||
from our time (GMT) to Julian day there is a supplementary program
|
||||
named: dmy2jd.c. Run it with "day_float month year" as arguments. See
|
||||
below for an example.
|
||||
|
||||
|
||||
What it does
|
||||
------------
|
||||
|
||||
This program plots the positions of the four Galilean moons of Jupiter,
|
||||
as seen from earth. It doesn't correct for your location on earth, but I
|
||||
assure you that the parallax is minimal!
|
||||
|
||||
The moons are labelled with roman numerals from I to IV. I being the
|
||||
closest to the planet and IV being the furthest. They are:
|
||||
|
||||
I Io
|
||||
II Europa
|
||||
III Ganymede
|
||||
IV Callisto
|
||||
|
||||
Amazingly, all it takes is a pair of binoculars to see the Galilean moons,
|
||||
so the results can be experimentally checked. (Note that at present, the
|
||||
best views of Jupiter are over the autumn/winter.)
|
||||
|
||||
The positions of the moons should be correct for binoculars, but possibly
|
||||
not if you have a telescope or if you are in the southern hemisphere. In
|
||||
that case I suggest that to get the correct image you look at the screen
|
||||
from inside the monitor whilst standing on your head. In case of
|
||||
confusion, please consult the following chart (*):
|
||||
|
||||
N
|
||||
^
|
||||
|
|
||||
E <---+---> W
|
||||
|
|
||||
v
|
||||
S
|
||||
|
||||
(*) Not to scale.
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
Galileo discovered the moons in January 1610.
|
||||
"http://www-isds.jpl.nasa.gov/cwo/cwo_54ga/html/cd/galileo.htm" states
|
||||
the following:
|
||||
|
||||
By early 1610, Galileo had further improved his telescope by
|
||||
double its power, so it now enlarged objects a thousand
|
||||
times. He began looking at the stars and couldn't believe how
|
||||
many more he could now see! The number seemed infinite. He was
|
||||
beginning to realize the fixed stars weren't a flat distant
|
||||
wall on a globe, but a three-dimensional expanse bigger than
|
||||
anyone had ever thought!
|
||||
|
||||
Then, on January 7, about an hour after sunset, Jupiter rose
|
||||
in the east, and Galileo happened to turn his powerful scope
|
||||
on its bright disk. It wasn't the first time he had looked at
|
||||
Jupiter, but before it was with one of his lesser-powered
|
||||
telescopes. This time, though, he noticed three small but
|
||||
bright stars near the planet, two to one side and one to the
|
||||
other. He wondered at how bright the small stars were and how
|
||||
they were arranged in what seemed like a straight line. The
|
||||
next night he decided to look at Jupiter again, and to his
|
||||
surprise, the stars had moved. But not in such a way as he
|
||||
would expect. If Jupiter was moving as it normally should, the
|
||||
stars would be east of Jupiter. But all three were to the
|
||||
west! The next night was cloudy, but on January 10, Galileo
|
||||
was able to observe the planet again. One of the stars was
|
||||
gone, and the other two were now on the east side. As the
|
||||
stars moved around Jupiter on each succeeding night, and were
|
||||
finally joined by a fourth star, it dawned on Galileo that
|
||||
what he had found were moons orbiting Jupiter! Almost at once
|
||||
he realized that this was proof that not all objects orbited
|
||||
the Earth. Here were four bodies that were orbiting
|
||||
Jupiter. One argument against the sun-centered theory was, if
|
||||
the Earth orbited the sun, wouldn't the moon get left behind?
|
||||
Here he could see for himself that somehow, a planet could
|
||||
orbit the sun, and not leave a moon behind!
|
||||
|
||||
Thus we can plot Galileo's discoveries using the following three plots:
|
||||
|
||||
./rince 0 `./dmy2jd 7.8 1 1610`
|
||||
./rince 0 `./dmy2jd 8.8 1 1610`
|
||||
./rince 0 `./dmy2jd 10.8 1 1610`
|
||||
|
||||
However we can go one better by seeing what Galileo would have seen if it
|
||||
wasn't cloudy on the 9th. Try "./rince 0 `./dmy2jd 9.85 1 1610`" to see
|
||||
what he was missing out on. I wonder what he'd have made of that!
|
||||
|
||||
Galileo discovered the fourth moon a few days later.
|
||||
|
||||
I've tried typing these dates in to two Java based Jovian moon plotters,
|
||||
but both I tried had problems dealing with dates earlier than 1900. More
|
||||
professional software, such as the SkyMap program [3] gets these values
|
||||
correct and this compares well with the above description and with this
|
||||
IOCCC entry.
|
||||
|
||||
|
||||
The year 4713BC was chosen by Joseph Justus Scaliger in the 16th Century,
|
||||
so clearly this program has a long history :-) A more complete description
|
||||
of the origins of Julian Days can be found at:
|
||||
|
||||
http://aa.usno.navy.mil/AA/faq/docs/millennium.html
|
||||
|
||||
|
||||
Assumptions
|
||||
-----------
|
||||
|
||||
1. The ASCII character set is used.
|
||||
|
||||
2. That an enormous comet hasn't changed the course of Jupiter (or Earth!).
|
||||
|
||||
3. That the date has not been specified as the gap between the Julian
|
||||
and Gregorian calendar.
|
||||
|
||||
4. That the DISPLAY environment variable is set and the X display can
|
||||
opened. If this is not the case the program will crash.
|
||||
|
||||
5. There is a year 2000BC problem :-)
|
||||
More specifically, the plots for dates that far back are too inaccurate
|
||||
to be of realistic use. Comparisons against SkyMap Pro [3] show that
|
||||
there is a good similarity (but not much more) up to about 500BC.
|
||||
|
||||
6. The code definitely is not portable - it will produce incorrect results
|
||||
if run from the surface of Mars.
|
||||
|
||||
|
||||
Obfuscations
|
||||
------------
|
||||
|
||||
In addition to the normal obfuscations, I feel that the code contains
|
||||
some less common tricks. Taken through the standard rounds listed in the
|
||||
guidelines, the code attempts to pass these as follows:
|
||||
|
||||
1. Look at the original source
|
||||
|
||||
With luck, pure casual inspection should not reveal much except
|
||||
that the program contains the X Windows logo (a big clue) and
|
||||
contains a date. This date may give a clue to a few people that
|
||||
this is an astronomical program.
|
||||
|
||||
Unfortunately I was stretched for space which meant that the
|
||||
large string constant could not be split up using a "partA"
|
||||
"partB" method which clearly limits the code layout. However the
|
||||
space saved by using a single long string constant is more than
|
||||
outweighed by ability to further obfuscate.
|
||||
|
||||
2. convert ANSI tri-graphs to ASCII
|
||||
|
||||
These are not used.
|
||||
|
||||
3. C pre-process the source ignoring #include lines
|
||||
4. C pre-process the source ignoring #define and #include lines
|
||||
|
||||
This does a good job of expanding out the code, but it does not
|
||||
clarify things greatly. The use of #defines has been restricted
|
||||
primarily to a space-saving mechanism.
|
||||
|
||||
Additionally, the use of typedefs means that the types used are
|
||||
still obscured unless further replacement edits are made.
|
||||
|
||||
5. Run it through a C beautifier.
|
||||
|
||||
GNU indent seems to do a reasonable job, provided that the
|
||||
#defines are expanded first. This doesn't lay the algorithm
|
||||
particularly bare though as most of the obfuscations are not
|
||||
simple code layouts.
|
||||
|
||||
6. Examine the algorithm.
|
||||
|
||||
The algorithm operates on two levels. The main visible level is
|
||||
by taking a large string and breaking this down into a series of
|
||||
op-codes (which I have termed J-code). These are then executed.
|
||||
|
||||
To get to the real method of how it works, you need to decode
|
||||
the op-code string (which deliberately contains as many ; { and
|
||||
} symbols as possible), which will give you a reverse-polish
|
||||
notation chunk of mathematics.
|
||||
|
||||
Sensible people amongst you will simply refer to the referenced
|
||||
book :-)
|
||||
|
||||
7. Lint it.
|
||||
|
||||
I no longer have lint, although I do have access to Purify. I'm
|
||||
happy to say that purify does not detect any memory errors or
|
||||
memory leaks.
|
||||
|
||||
See below for compilation warnings.
|
||||
|
||||
8. Compile it.
|
||||
|
||||
I'm sorry to say that there are several warnings issued by the
|
||||
compiler.
|
||||
|
||||
Firstly, the return type for X() is not specified, so it
|
||||
defaults to int. Horror of all horrors - this function does not
|
||||
return an integer type (it doesn't contain any specific
|
||||
returns). The return value from X() is not accessed. The same
|
||||
problem occurs in main - it does not return. However main never
|
||||
exits unless there is a serious error.
|
||||
|
||||
The 6th argument of XDrawText (which should be XTextItem) is
|
||||
passed as a compatible structure, but without casting. This is
|
||||
to reduce code space. A more elegant solution is to remove the
|
||||
"struct {...} Z" completely and use "XTextItem
|
||||
f={i-127+r/3*2,r%3+r/3+1,0,E}" at the start of XDrawText
|
||||
block. Although this is accepted by several compilers, it is not
|
||||
strict ANSI due to the non-constant initialisers. A pity.
|
||||
|
||||
Note that I make use of usleep(). This is a POSIX call (it is
|
||||
BSD), but it supported on many systems. It may be implemented
|
||||
using select() or poll() if required, or as a final solution you
|
||||
may change the usleep(10000) to sleep(1). To compile on systems
|
||||
which do not have usleep, but do have select, the following may
|
||||
suffice as an additional compiler argument:
|
||||
|
||||
-Dusleep={time_t v[2]={0,10000};select(0,0,0,0,v);}
|
||||
|
||||
Gcc complains about "unreachable code at beginning of switch
|
||||
statement", although removing some of this code will prevent
|
||||
the algorithm from working.
|
||||
|
||||
Gcc also suggests that I should be using extra parenthesis, but
|
||||
I'm taking this as good comment :-)
|
||||
|
||||
|
||||
In addition to the above, the program has the following useful(?)
|
||||
obfuscations:
|
||||
|
||||
1. The algorithm requires many floating point numbers (about
|
||||
50). These are encoded as ASCII.
|
||||
|
||||
2. The J-code algorithm has op-codes designed to be space
|
||||
saving. They are all one byte, but many are also considered as
|
||||
white-space by the rules. This algorithm forms part of the same
|
||||
string that the floating point constants are embedded
|
||||
within. What does the ";" command do in J-code?
|
||||
|
||||
3. The J-code language is both stack based and variable based. This
|
||||
"uncleanliness" is not ideal from a computer science angle, but
|
||||
when has cleanliness been considered as good in IOCCC? :-)
|
||||
|
||||
4. Association of unconnected data by implied function usage. Eg
|
||||
use of strlen() and sizeof() simply to return useful numerical
|
||||
values, using irrelevant arguments.
|
||||
|
||||
5. As we already have a dependency on ASCII this has been abused
|
||||
further. Specifically some integer constants are specified as
|
||||
ASCII and some ASCII constants are integers. This hides the true
|
||||
meaning for the values.
|
||||
|
||||
6. Red herrings: there's a couple of pieces of code whose
|
||||
appearance is just there to mislead the unfirm of mind.
|
||||
I've only tried to include such examples in places where at
|
||||
first glance the code appears to be executed.
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
[1] Astronomical algorithms (1st ed): page 59
|
||||
Jean Meeus. Published by Willmann-Bell Inc.
|
||||
|
||||
[2] Astronomical algorithms (1st ed): pages 285-299.
|
||||
Jean Meeus. Published by Willmann-Bell Inc.
|
||||
|
||||
[3] Skymap Pro, by Chris Marriott
|
||||
http://www.skymap.com/
|
||||
+829
@@ -0,0 +1,829 @@
|
||||
#define A B.
|
||||
#define C if(
|
||||
#define D >>E&1
|
||||
#define F return
|
||||
#define G typedef
|
||||
#define H printf( I(
|
||||
#define J(E,K) for(E=K; E--; )
|
||||
#define L(M) =N(O.M)+3*N(O.M&O.P),
|
||||
G
|
||||
int
|
||||
Q;
|
||||
G
|
||||
unsigned
|
||||
R;
|
||||
G
|
||||
struct
|
||||
{
|
||||
Q
|
||||
N,
|
||||
S,
|
||||
P,
|
||||
T,
|
||||
U,
|
||||
V;
|
||||
}
|
||||
W;
|
||||
R
|
||||
_;
|
||||
R
|
||||
N(
|
||||
R
|
||||
X)
|
||||
{
|
||||
R
|
||||
Y=
|
||||
2,
|
||||
Z;
|
||||
for
|
||||
(;
|
||||
Y
|
||||
;
|
||||
Y*=
|
||||
Y)
|
||||
{
|
||||
Z=
|
||||
-1
|
||||
/-
|
||||
~Y
|
||||
;
|
||||
X=
|
||||
(X
|
||||
/Y
|
||||
&Z
|
||||
)+
|
||||
(X
|
||||
&Z
|
||||
)*
|
||||
(Y
|
||||
*_
|
||||
-~-
|
||||
_)
|
||||
;
|
||||
}
|
||||
F
|
||||
X;
|
||||
}
|
||||
W
|
||||
S(
|
||||
W
|
||||
a)
|
||||
{
|
||||
W
|
||||
B;
|
||||
_=
|
||||
1;
|
||||
A
|
||||
N=
|
||||
N(
|
||||
a.
|
||||
S)
|
||||
;
|
||||
A
|
||||
S=
|
||||
N(
|
||||
a.
|
||||
N)
|
||||
;
|
||||
A
|
||||
P=
|
||||
N(
|
||||
a.
|
||||
P)
|
||||
;
|
||||
A
|
||||
U=
|
||||
-1
|
||||
<<
|
||||
30
|
||||
;
|
||||
A
|
||||
V=
|
||||
-a
|
||||
.U
|
||||
;
|
||||
F
|
||||
B;
|
||||
}
|
||||
Q
|
||||
P(
|
||||
Q
|
||||
Y,
|
||||
Q
|
||||
b,
|
||||
R
|
||||
c)
|
||||
{
|
||||
Q
|
||||
E=
|
||||
Y+
|
||||
(b
|
||||
+8
|
||||
)%
|
||||
10
|
||||
-5
|
||||
+Y
|
||||
/4
|
||||
%2
|
||||
&31
|
||||
;
|
||||
F
|
||||
c
|
||||
D||
|
||||
Y/
|
||||
4-
|
||||
E/
|
||||
4-
|
||||
~-
|
||||
(b
|
||||
&2
|
||||
)?
|
||||
-1
|
||||
:E
|
||||
;
|
||||
}
|
||||
Q
|
||||
T(
|
||||
W
|
||||
B,
|
||||
Q
|
||||
a,
|
||||
Q
|
||||
b)
|
||||
{
|
||||
Q
|
||||
E=
|
||||
P(
|
||||
a,
|
||||
b,
|
||||
A
|
||||
N)
|
||||
;
|
||||
F~
|
||||
E?
|
||||
A
|
||||
S
|
||||
D?
|
||||
~P
|
||||
(E
|
||||
,b
|
||||
,A
|
||||
S|
|
||||
A
|
||||
N)
|
||||
?128
|
||||
|b
|
||||
*32
|
||||
|a
|
||||
:-
|
||||
1:
|
||||
b*
|
||||
32
|
||||
|a
|
||||
:E
|
||||
;
|
||||
}
|
||||
Q
|
||||
U(
|
||||
W
|
||||
B,
|
||||
R
|
||||
c,
|
||||
Q
|
||||
Y)
|
||||
{
|
||||
Q
|
||||
E,
|
||||
b;
|
||||
J(
|
||||
E,
|
||||
32
|
||||
)C
|
||||
(A
|
||||
N&
|
||||
c)
|
||||
D)
|
||||
J(
|
||||
b,
|
||||
2<<
|
||||
(A
|
||||
P
|
||||
D)
|
||||
)C
|
||||
T(
|
||||
B,
|
||||
E,
|
||||
b)
|
||||
>=
|
||||
Y<<
|
||||
7)
|
||||
F
|
||||
1;
|
||||
F
|
||||
0;
|
||||
}
|
||||
W
|
||||
V(
|
||||
W
|
||||
B,
|
||||
Q
|
||||
Z)
|
||||
{
|
||||
R
|
||||
E=
|
||||
Z&
|
||||
31
|
||||
,b
|
||||
=Z
|
||||
/32
|
||||
&3
|
||||
,Y
|
||||
=A
|
||||
T=
|
||||
P(
|
||||
E,
|
||||
b,
|
||||
0)
|
||||
,K
|
||||
=1
|
||||
<<
|
||||
Y;
|
||||
A
|
||||
N|=
|
||||
K;
|
||||
A
|
||||
P&=
|
||||
~K
|
||||
;
|
||||
A
|
||||
P|=
|
||||
(A
|
||||
P
|
||||
D)
|
||||
<<
|
||||
Y;
|
||||
_=
|
||||
A
|
||||
S
|
||||
D&&
|
||||
U(
|
||||
B,
|
||||
K,
|
||||
1)
|
||||
;
|
||||
A
|
||||
P|=
|
||||
K&-
|
||||
1<<
|
||||
28
|
||||
;
|
||||
A
|
||||
N&=
|
||||
E=
|
||||
~(
|
||||
1<<
|
||||
E)
|
||||
;
|
||||
A
|
||||
P&=
|
||||
E;
|
||||
A
|
||||
S&=
|
||||
E;
|
||||
F
|
||||
Z>>
|
||||
7?
|
||||
V(
|
||||
B,
|
||||
b<<
|
||||
5|
|
||||
Y)
|
||||
:B
|
||||
;
|
||||
}
|
||||
W
|
||||
d(
|
||||
W
|
||||
B,
|
||||
Q
|
||||
b)
|
||||
;
|
||||
R
|
||||
e;
|
||||
W
|
||||
f(
|
||||
W
|
||||
B,
|
||||
Q
|
||||
E,
|
||||
Q
|
||||
b,
|
||||
Q
|
||||
g)
|
||||
{
|
||||
Q
|
||||
h,
|
||||
i=
|
||||
0,
|
||||
I,
|
||||
j,
|
||||
K,
|
||||
k,
|
||||
Z,
|
||||
Y;
|
||||
J(
|
||||
h,
|
||||
2<<
|
||||
(A
|
||||
P
|
||||
D)
|
||||
){
|
||||
j=
|
||||
T(
|
||||
B,
|
||||
E,
|
||||
h)
|
||||
;
|
||||
C~
|
||||
j&&
|
||||
j>>
|
||||
7!=
|
||||
!~
|
||||
g)
|
||||
{
|
||||
++
|
||||
i;
|
||||
C
|
||||
A
|
||||
U<=
|
||||
A
|
||||
V)
|
||||
{
|
||||
W
|
||||
O;
|
||||
O=
|
||||
V(
|
||||
B,
|
||||
j)
|
||||
;
|
||||
K=
|
||||
g<
|
||||
0?
|
||||
j:
|
||||
g;
|
||||
++
|
||||
e;
|
||||
I=
|
||||
_?
|
||||
f(
|
||||
O,
|
||||
O.
|
||||
T,
|
||||
b,
|
||||
K)
|
||||
.U
|
||||
:(
|
||||
Y=
|
||||
b+
|
||||
U(
|
||||
O=
|
||||
S(
|
||||
O)
|
||||
,-
|
||||
1,
|
||||
1)
|
||||
)?
|
||||
-(
|
||||
d(
|
||||
O,
|
||||
~-
|
||||
Y)
|
||||
.U
|
||||
):
|
||||
(_
|
||||
=0
|
||||
,Z
|
||||
L(
|
||||
N)
|
||||
k
|
||||
L(
|
||||
S)
|
||||
(k
|
||||
-Z
|
||||
<<
|
||||
24
|
||||
)/
|
||||
(k
|
||||
+Z
|
||||
)+
|
||||
(short
|
||||
)rand
|
||||
()
|
||||
);
|
||||
C
|
||||
I>=
|
||||
A
|
||||
U)
|
||||
{
|
||||
A
|
||||
U=
|
||||
I;
|
||||
A
|
||||
T=
|
||||
K;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_=
|
||||
i;
|
||||
F
|
||||
B;
|
||||
}
|
||||
W
|
||||
d(
|
||||
W
|
||||
B,
|
||||
Q
|
||||
b)
|
||||
{
|
||||
Q
|
||||
E=
|
||||
32
|
||||
,Y
|
||||
=
|
||||
~U
|
||||
(B
|
||||
,-
|
||||
1,
|
||||
1)
|
||||
;
|
||||
for
|
||||
(;
|
||||
E--
|
||||
&&
|
||||
A
|
||||
U<=
|
||||
A
|
||||
V;
|
||||
)C
|
||||
A
|
||||
N
|
||||
D)
|
||||
{
|
||||
B=
|
||||
f(
|
||||
B,
|
||||
E,
|
||||
b,
|
||||
Y)
|
||||
;
|
||||
}
|
||||
F
|
||||
B;
|
||||
}
|
||||
char
|
||||
l[
|
||||
4095
|
||||
],
|
||||
*O
|
||||
=l
|
||||
,*
|
||||
b;
|
||||
char
|
||||
*I
|
||||
(char
|
||||
*X
|
||||
){
|
||||
Q
|
||||
Z=
|
||||
1,
|
||||
W=
|
||||
0,
|
||||
E,
|
||||
M=
|
||||
0,
|
||||
B;
|
||||
b=
|
||||
O;
|
||||
for
|
||||
(;
|
||||
E
|
||||
=
|
||||
*X
|
||||
++
|
||||
;
|
||||
){
|
||||
E=
|
||||
E%
|
||||
65
|
||||
%6
|
||||
^2
|
||||
;
|
||||
M+=
|
||||
B=
|
||||
Z+
|
||||
1+
|
||||
E/
|
||||
4;
|
||||
W=
|
||||
W<<
|
||||
B^
|
||||
E;
|
||||
Z=
|
||||
E<
|
||||
2;
|
||||
J(
|
||||
E,
|
||||
M/
|
||||
7)
|
||||
{
|
||||
M%=
|
||||
7;
|
||||
W^=
|
||||
(*
|
||||
O++=
|
||||
W>>
|
||||
M)
|
||||
<<
|
||||
M;
|
||||
}
|
||||
}
|
||||
*O
|
||||
++=
|
||||
0;
|
||||
F
|
||||
b;
|
||||
}
|
||||
Q
|
||||
main
|
||||
()
|
||||
{
|
||||
Q
|
||||
K,
|
||||
Y,
|
||||
E,
|
||||
m,
|
||||
n,
|
||||
o=
|
||||
4,
|
||||
g,
|
||||
b,
|
||||
Z;
|
||||
W
|
||||
B;
|
||||
srand
|
||||
(clock
|
||||
()
|
||||
);
|
||||
A
|
||||
S=
|
||||
(A
|
||||
N=
|
||||
4095
|
||||
)<<
|
||||
20
|
||||
;
|
||||
A
|
||||
P=
|
||||
0;
|
||||
for
|
||||
(;
|
||||
;
|
||||
){
|
||||
J(
|
||||
K,
|
||||
8)
|
||||
{
|
||||
J(
|
||||
Y,
|
||||
8)
|
||||
{
|
||||
E=
|
||||
K*
|
||||
4+
|
||||
Y/
|
||||
2;
|
||||
H" } { }"
|
||||
)+
|
||||
(K
|
||||
^Y
|
||||
^1
|
||||
)%
|
||||
2*
|
||||
2,
|
||||
".xoXO"
|
||||
[(
|
||||
A
|
||||
P
|
||||
D)
|
||||
*2
|
||||
+(
|
||||
A
|
||||
S
|
||||
D)
|
||||
*2
|
||||
+(
|
||||
A
|
||||
N
|
||||
D)
|
||||
])
|
||||
;
|
||||
}
|
||||
H" } } } } } } "
|
||||
),
|
||||
-~
|
||||
E)
|
||||
;
|
||||
}
|
||||
J(
|
||||
g,
|
||||
1)
|
||||
{
|
||||
O=
|
||||
l;
|
||||
H"} } } } { } } } } { ; ; }"
|
||||
)+
|
||||
o/
|
||||
2*
|
||||
2)
|
||||
;
|
||||
e=
|
||||
0;
|
||||
C
|
||||
o<
|
||||
4)
|
||||
B=
|
||||
S(
|
||||
B)
|
||||
;
|
||||
C!
|
||||
U(
|
||||
B,
|
||||
-1
|
||||
,0
|
||||
))
|
||||
{
|
||||
H" } } { ; { ; } ; } } "
|
||||
))
|
||||
;
|
||||
F
|
||||
0;
|
||||
}
|
||||
H" { { ; { ; ; { ; ; { { } } ; ; { } } } ; ; { ; } } } { ; { ; ; { { ; } } "
|
||||
)+
|
||||
(o
|
||||
&1
|
||||
)*
|
||||
13
|
||||
,I
|
||||
(" } { { } ; } "
|
||||
)+
|
||||
U(
|
||||
B,
|
||||
-1
|
||||
,1
|
||||
))
|
||||
;
|
||||
C
|
||||
o&
|
||||
4)
|
||||
{
|
||||
o&
|
||||
1?
|
||||
scanf
|
||||
("%d"
|
||||
,&
|
||||
n)
|
||||
:(
|
||||
scanf
|
||||
("%d%d"
|
||||
,&
|
||||
m,
|
||||
&n
|
||||
),
|
||||
--
|
||||
m)
|
||||
;
|
||||
Z=
|
||||
A
|
||||
N>>
|
||||
m&
|
||||
1?
|
||||
T(
|
||||
B,
|
||||
m,
|
||||
n)
|
||||
:-
|
||||
1;
|
||||
C
|
||||
g=
|
||||
Z>>
|
||||
7!=
|
||||
U(
|
||||
B,
|
||||
-1
|
||||
,1
|
||||
))
|
||||
{
|
||||
H"{ ; { { } { } { ; } ; { "
|
||||
))
|
||||
;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
A
|
||||
U=
|
||||
-(
|
||||
A
|
||||
V=
|
||||
1<<
|
||||
30
|
||||
);
|
||||
for
|
||||
(b
|
||||
=4
|
||||
;
|
||||
e<
|
||||
65536
|
||||
&&
|
||||
b<
|
||||
20
|
||||
;
|
||||
b++
|
||||
){
|
||||
Z=
|
||||
(o
|
||||
&1
|
||||
?f
|
||||
(B
|
||||
,m
|
||||
,b
|
||||
,-
|
||||
2)
|
||||
:d
|
||||
(B
|
||||
,b
|
||||
))
|
||||
.T
|
||||
;
|
||||
}
|
||||
o&
|
||||
1?
|
||||
H" } { } "
|
||||
),
|
||||
Z>>
|
||||
5&
|
||||
3^
|
||||
3)
|
||||
:H
|
||||
" } { } } } { } "
|
||||
),
|
||||
32
|
||||
-(
|
||||
Z&
|
||||
31
|
||||
),
|
||||
Z>>
|
||||
5&
|
||||
3^
|
||||
3)
|
||||
;
|
||||
}
|
||||
}
|
||||
B=
|
||||
V(
|
||||
B,
|
||||
Z)
|
||||
;
|
||||
g=
|
||||
o;
|
||||
C
|
||||
_)
|
||||
{
|
||||
o|=
|
||||
1;
|
||||
m=
|
||||
A
|
||||
T;
|
||||
}
|
||||
else
|
||||
{
|
||||
o=
|
||||
o/
|
||||
2*
|
||||
2^
|
||||
4;
|
||||
}
|
||||
C
|
||||
g<
|
||||
4)
|
||||
{
|
||||
B=
|
||||
S(
|
||||
B)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
Best game:
|
||||
|
||||
Arch D. Robison
|
||||
1406 Country Lake Drive
|
||||
Champaign IL 61821
|
||||
USA
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make robison
|
||||
|
||||
To run:
|
||||
|
||||
./robison
|
||||
|
||||
The program plays almost always reasonably, but does not always detect
|
||||
illegal moves. Try "9 1" as your first move, then "13 2". Also it
|
||||
tends to think for quite a while in the beginning of a game. It is
|
||||
also smart enough to give up by making a losing move at the end of
|
||||
a game when its position is hopeless.
|
||||
|
||||
Unfortunately, due to the contest rules, we're unable to grant the
|
||||
author a patent he applied for. :-)
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
TITLE OF INVENTION
|
||||
|
||||
Highly Compressed Program for Playing Hygienic Checkers
|
||||
|
||||
FIELD OF INVENTION
|
||||
|
||||
The present invention generally relates to checkers.
|
||||
|
||||
BACKGROUND OF THE INVENTION
|
||||
|
||||
Within the field of checkers, the problem of finding a hygienic opponent
|
||||
is difficult, as good opponents are peculiar to the tavern habitat of
|
||||
cracker-barrels, pot-belly stoves, tobacco, and spittoons.
|
||||
|
||||
BRIEF SUMMARY OF THE INVENTION
|
||||
|
||||
The present invention plays checkers without spitting.
|
||||
|
||||
BRIEF DESCRIPTION OF SEVERAL VIEWS OF THE INVENTION
|
||||
|
||||
FIG. 1 shows a numbering of positions.
|
||||
|
||||
FIG. 2 shows a numbering of directions.
|
||||
|
||||
FIG. 3 shows a sample board.
|
||||
|
||||
FIG. 4 shows a method in accordance with the present invention.
|
||||
|
||||
DETAILED DESCRIPTION OF THE INVENTION
|
||||
|
||||
Operator plays Black (x); the program plays White (o). Said Black goes
|
||||
first. On operators turn, said program requests a position and direction.
|
||||
FIG. 1 shows the numbering of the squares. FIG. 2 shows the numbering of
|
||||
directions. As per standard rules, if one or more jumps are possible, one
|
||||
of the jumps must be taken in preference to other moves. Said operator
|
||||
enters the numbers for the position and direction. If after jumping over a
|
||||
piece, another jump is possible, and said piece did not become a king after
|
||||
said jump, standard rules require that another jump be taken. In said case,
|
||||
said program requests a direction only in which to continue jumping from the
|
||||
present position. Kings are denoted by upper case. FIG 3. shows a sample
|
||||
board. There is a black king (X) on square 30 and a red king (O) on square
|
||||
2. The numbers on the right are the numbers of the rightmost square in each
|
||||
row.
|
||||
|
||||
A player loses if they cannot make a legal move. Said loss is trivially
|
||||
true if player loses all of his/her pieces. The present invention announces
|
||||
said loser.
|
||||
|
||||
FIG. 4 shows a C program in accordance with the present invention. Control
|
||||
flow is straightforward: control enters routine ``main'', executes a
|
||||
plurality of statements, and exits via return statement. FIG. 4 presumes
|
||||
that type int is 32 bits and short is 16 bits, which are essential to the
|
||||
preferred embodiment of the invention. FIG. 4 also presumes that the host
|
||||
computer uses ASCII encoding for characters. It should be obvious that
|
||||
practitioners skilled in the art of C programming can remove said
|
||||
limitations.
|
||||
|
||||
The disclosure here describes a particular embodiment of the present
|
||||
invention, and other embodiments within the spirit of this disclosure
|
||||
are possible, as well as consumption of spirits while playing.
|
||||
|
||||
CLAIMS
|
||||
|
||||
I claim, by letters patently absurd:
|
||||
|
||||
1. A method for playing checkers on a computer-based system, where said
|
||||
method's source code fits into 1536 countable bytes of source code,
|
||||
where a byte is countable if
|
||||
|
||||
(a) it is not whitespace and
|
||||
(b) it is not a {, }, or ; immediately followed by whitespace.
|
||||
|
||||
2. The method of claim 1, further comprising a method of alpha-beta pruning
|
||||
that exploits the zero-sum nature of the game to unify alpha
|
||||
and beta cuts.
|
||||
|
||||
3. The method of claim 1, further comprising the step of formatting the
|
||||
source code with short lines, in order to impress manager with
|
||||
high productivity, when measured in lines of code.
|
||||
|
||||
4. The method of claim 3, further comprising the step for telling
|
||||
skeptical manager that this is the well-known technique of
|
||||
"linear programming".
|
||||
|
||||
5. The method of claim 1, where ~- and -~ replace the obvious arithmetic
|
||||
operations.
|
||||
|
||||
6. The method of claim 1, further comprising a method where
|
||||
|
||||
(a) strings are encrypted in a manner suitable as C strings, and
|
||||
(b) 7-bit ASCII characters with uniform distribution are maximally
|
||||
packed subject to the restriction that
|
||||
(c) each byte is not countable.
|
||||
|
||||
7. A method for a computer-based system that uses a single shared code
|
||||
sequence to either sum a plurality of bits in an N-bit word or reverses
|
||||
them, in lg(N) time, depending upon a parameter.
|
||||
|
||||
DRAWINGS
|
||||
|
||||
FIG 1.
|
||||
|
||||
+--+--+--+--+--+--+--+--+
|
||||
|32| |31| |30| |29| |
|
||||
+--+--+--+--+--+--+--+--+
|
||||
| |28| |27| |26| |25|
|
||||
+--+--+--+--+--+--+--+--+
|
||||
|24| |23| |22| |21| |
|
||||
+--+--+--+--+--+--+--+--+
|
||||
| |20| |19| |18| |17|
|
||||
+--+--+--+--+--+--+--+--+
|
||||
|16| |15| |14| |13| |
|
||||
+--+--+--+--+--+--+--+--+
|
||||
| |12| |11| |10| | 9|
|
||||
+--+--+--+--+--+--+--+--+
|
||||
| 8| | 7| | 6| | 5| |
|
||||
+--+--+--+--+--+--+--+--+
|
||||
| | 4| | 3| | 2| | 1|
|
||||
+--+--+--+--+--+--+--+--+
|
||||
|
||||
FIG. 2.
|
||||
|
||||
1 0
|
||||
\ /
|
||||
.
|
||||
/ \
|
||||
3 2
|
||||
|
||||
FIG. 3.
|
||||
|
||||
o o X . 29
|
||||
o . . . 25
|
||||
o . . o 21
|
||||
. o . o 17
|
||||
x . . . 13
|
||||
. . x . 9
|
||||
x x . . 5
|
||||
x x O x 1
|
||||
|
||||
FIG. 4
|
||||
|
||||
[See attached listing.]
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
15th International Obfuscated C Code Contest Rules |
|
||||
|
||||
Copyright (c) Leonid A. Broukhis, Jeremy Horn, Landon Curt Noll and |
|
||||
Peter Seebach, 2000. |
|
||||
|
||||
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 the contest judges. |
|
||||
|
||||
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 15th IOCCC contest window is: |
|
||||
|
||||
01-Feb-2000 00:00 UTC to 31-Mar-2000 23:59:59 UTC |
|
||||
|
||||
NOTE: Some of the changes from the 1998 rules are denoted by change bars. ---> |
|
||||
However some changes such as 1998 to 2000 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: 2000
|
||||
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 31 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 31-Mar-2000 23:59:59 UTC. (UTC is
|
||||
essentially equivalent to Greenwich Mean Time) EMail your entries to:
|
||||
|
||||
entry@ioccc.org
|
||||
|
||||
We request that your message use the subject 'ioccc entry'.
|
||||
|
||||
If possible, we request that you hold off on EMailing your entries
|
||||
until 01-Feb-2000 00:00 UTC. Early entries will be accepted, however.
|
||||
We will attempt to EMail a confirmation to the sender of any entry
|
||||
received after 01-Feb-2000 00: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 Leonid A. Broukhis, Jeremy Horn, Landon
|
||||
Curt Noll and Peter Seebach. Please send questions or comments
|
||||
about the contest, to:
|
||||
|
||||
questions@ioccc.org (not the address for 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, visit the IOCCC web page:
|
||||
|
||||
http://www.ioccc.org
|
||||
|
||||
It has rules, guidelines and winners of previous contests (1984 to date).
|
||||
|
||||
As a last resort, previous winners may be obtained by sending EMail
|
||||
to questions@ioccc.org. Please use the subject 'send YEAR winners',
|
||||
where YEAR is a single 4 digit year or a year range (such as 1993-1994),
|
||||
or the word 'all'.
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include <time.h>
|
||||
|
||||
#define I ??(i??)??(j??)
|
||||
#define K ??(i-1??)??(j??)
|
||||
#define S strtok(NULL,",\n\0")
|
||||
#define P printf(
|
||||
#define NB_MSGS 42
|
||||
#define C( f, m ) mNb = m;\
|
||||
s = setjmp( sT??( sI++ ??) );\
|
||||
if (!s) goto f;
|
||||
#define bck longjmp( sT??( --sI ??), 0 );
|
||||
|
||||
jmp_buf sT??( 256 ??);
|
||||
int m5??(84??),sI=0,c1='J'%2,mNb=0,s=0,mI=0,r=1;
|
||||
unsigned long m1??(32??),q=0,z;
|
||||
unsigned char m??( NB_MSGS ??)??( 11 ??);
|
||||
|
||||
int main( int argc, char *argv??(??) )
|
||||
{
|
||||
time_t tmT = time( NULL );
|
||||
struct tm *tmS = localtime( &tmT );
|
||||
char tms??( 7 ??);
|
||||
int hr,n,i=1,j=0;
|
||||
FILE *info = NULL;
|
||||
char iS??( 2048 ??);
|
||||
|
||||
if ( argc > 1 ) info = fopen( argv??(1??), "r" );
|
||||
strftime( tms, 7, "%H:%M\n", tmS );
|
||||
if ( info != NULL ) {
|
||||
fgets( iS, 2048, info );
|
||||
m5??( 0 ??) = atoi( strtok( iS, ",\0" ) );
|
||||
for ( hr = 1; hr < 85; hr++ ) m5??(hr??) = atoi(S);
|
||||
for ( hr = 0; hr < 32; hr++ )
|
||||
m1??( hr ??) = strtoul( S, NULL, 10 );
|
||||
for ( hr = 0; hr < NB_MSGS; hr++ )
|
||||
for ( n = 0; n < 11; n++ )
|
||||
m??(hr??)??(n??) = (unsigned char)atoi( S );
|
||||
fclose( info );
|
||||
hr = atoi( strtok( tms, ":\0" ) );
|
||||
n = atoi( strtok( NULL, ":\0" ) );
|
||||
C( mA, 0 )
|
||||
C( out, 40 )
|
||||
s = setjmp( sT??( sI++ ??) );
|
||||
if ( s ) {
|
||||
s = setjmp( sT??( sI++ ??) );
|
||||
if ( s ); else goto doHr;
|
||||
} else goto doMin;
|
||||
} else {
|
||||
P "%s", tms );
|
||||
goto eoj;
|
||||
doMin:
|
||||
z = 22;
|
||||
C( doIt, 0 )
|
||||
bck
|
||||
doHr:
|
||||
hr = ( n >= 36 ) ? hr+1 : hr;
|
||||
if ( hr == 24 ) hr=0;
|
||||
if (hr&&hr!=12)(hr<12)?(P "%d ",hr)):(P "%d ",hr-12));
|
||||
n = hr + 61;
|
||||
q = 0;
|
||||
r = 1;
|
||||
z = 16;
|
||||
C( doIt, 0 )
|
||||
P "\n" );
|
||||
bck
|
||||
doIt:
|
||||
if ( r & m1??( m5??(n??) ??) ) {
|
||||
if (z == 22) q = q << 1;
|
||||
C( out, q )
|
||||
if (z == 22) q = q >> 1;
|
||||
}
|
||||
r = r << 1;
|
||||
q++;
|
||||
if ( q < z ) goto doIt;
|
||||
bck
|
||||
out:
|
||||
mI = 0;
|
||||
mNb += c1;
|
||||
while ( m??( mNb ??)??( mI ??) )
|
||||
P "%c", m??( mNb ??)??( mI++ ??) );
|
||||
bck
|
||||
mA:
|
||||
129<=m I ? 137>=m I ? m K=m I-32
|
||||
: 145<=m I ? 153>=m I ? m K=m I-39
|
||||
: 162<=m I ? 169>=m I ? m K=m I -47
|
||||
: j : j : j : 125==m I ? m K=39
|
||||
: 64==m I ? m K=32 : j;
|
||||
j++;
|
||||
if (m I) goto mA;
|
||||
i+=2;
|
||||
j = 0;
|
||||
if ( i < NB_MSGS ) goto mA;
|
||||
bck
|
||||
}
|
||||
|
||||
eoj: exit( 0 );
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
0,1,1,1,1,1,2,2,2,2,3,4,4,5,5,6,7,7,8,8,9,10,10,10,10,10,11,11,11,11,12,13,13,13,13,13,14,14,14,14,15,16,16,17,17,18,19,19,20,20,21,22,22,22,22,22,23,23,23,23,24,25,26,26,26,27,27,27,27,27,27,27,27,28,29,29,29,29,30,30,30,31,31,31,31,256,2560,561152,557312,166400,143360,139520,140800,200704,196864,199168,544768,540928,542208,331776,327936,329216,274432,270592,271872,299008,295168,296448,4096,0,1,20,68,256,1028,4100,16384,0,0,0,0,0,0,0,0,0,0,0,148,137,132,149,137,135,136,163,64,0,0,0,0,0,0,0,0,0,0,0,0,0,137,149,64,163,136,133,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,166,133,133,64,136,150,164,153,162,64,0,0,0,0,0,0,0,0,0,0,0,0,148,150,153,149,137,149,135,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,149,150,150,149,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,134,163,133,153,149,150,150,149,64,0,0,0,0,0,0,0,0,0,0,0,0,133,165,133,149,137,149,135,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,163,64,149,137,135,136,163,64,0,0,0,0,0,0,0,0,0,0,0,0,0,133,167,129,131,163,147,168,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,145,164,162,163,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,134,163,133,153,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,129,162,163,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,147,148,150,162,163,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,64,152,164,129,153,163,133,153,64,0,0,0,0,0,0,0,0,0,0,0,0,136,129,147,134,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,163,133,149,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,163,166,133,149,163,168,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,134,163,133,153,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,125,163,137,147,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,151,129,162,163,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,137,163,125,162,64,0,0,0,0,0,0
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
Most Timely Output:
|
||||
|
||||
Craig Schneiderwent
|
||||
WI, USA
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make schneiderwent
|
||||
|
||||
To run:
|
||||
|
||||
./schneiderwent schneiderwent.data
|
||||
|
||||
Very nice play by the rules and portable text obfuscation.
|
||||
This far surpasses old tricks like adding or subtracting 1
|
||||
from every character in a C string.
|
||||
|
||||
Translating the messages into your language of preference while
|
||||
keeping the program portable between different encodings
|
||||
(Chinese, Japanese, Russian - anyone?) may be an entertaining task.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
This entry displays the current time to the console, for example:
|
||||
|
||||
it's just after ten 'til 6 in the evening
|
||||
|
||||
FWIW, none of the compilers with which this entry was tested issued
|
||||
any warnings or errors in compiling the source for this entry. No
|
||||
doubt lint will complain about the goto statements.
|
||||
|
||||
The schneiderwent.data file consists of the values used by multiple
|
||||
table lookups. This is simply good program design, separating
|
||||
these values from the source code allows changing the behavior of
|
||||
the application without recompiling.
|
||||
|
||||
Having learned COBOL at an early age, the pthreads of my thought
|
||||
processes tend to be translated into code in a verbose manner. Some
|
||||
of the #defines in this entry's code are to mitigate this personal
|
||||
deficiency.
|
||||
|
||||
Obfuscation in this entry consists of:
|
||||
|
||||
> printfing console messages stored as EBCDIC character values - this
|
||||
is not an attempt at encryption, but rather at cross platform
|
||||
compatibility
|
||||
> ASCII character values are calculated from the EBCDIC in a
|
||||
particularly ugly abuse of the '?' operator
|
||||
> detection of whether to print the ASCII or EBCDIC values is done by
|
||||
taking the remainder of dividing the character 'J' by 2 - the ASCII
|
||||
value of the character is even, the EBCDIC value is odd
|
||||
> the messages to be printfed are determined via multiple table
|
||||
lookups and bitmasked values
|
||||
> for minutes, the bit position turned on is multiplied by two
|
||||
to determine the message to be printfed
|
||||
> for hours, the straight bit position is used
|
||||
> this entry mostly eschews function calls for the often overlooked
|
||||
setjmp/longjmp combination
|
||||
> the trigraphs are not there as obfuscation nor are they there to
|
||||
annoy the judges - it's just the easiest way to get around the
|
||||
absence of square brackets in a normal 3270 environment
|
||||
@@ -0,0 +1,103 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include <time.h>
|
||||
|
||||
#define I ??(i??)??(j??)
|
||||
#define K ??(i-1??)??(j??)
|
||||
#define S strtok(NULL,",\n\0")
|
||||
#define P printf(
|
||||
#define NB_MSGS 42
|
||||
#define C( f, m ) mNb = m;\
|
||||
s = setjmp( sT??( sI++ ??) );\
|
||||
if (!s) goto f;
|
||||
#define bck longjmp( sT??( --sI ??), 0 );
|
||||
|
||||
jmp_buf sT??( 256 ??);
|
||||
int m5??(84??),sI=0,c1='J'%2,mNb=0,s=0,mI=0,r=1;
|
||||
unsigned long m1??(32??),q=0,z;
|
||||
unsigned char m??( NB_MSGS ??)??( 11 ??);
|
||||
|
||||
int main( int argc, char *argv??(??) )
|
||||
{
|
||||
time_t tmT = time( NULL );
|
||||
struct tm *tmS = localtime( &tmT );
|
||||
char tms??( 7 ??);
|
||||
int hr,n,i=1,j=0;
|
||||
FILE *info = NULL;
|
||||
char iS??( 2048 ??);
|
||||
|
||||
if ( argc > 1 ) info = fopen( argv??(1??), "r" );
|
||||
strftime( tms, 7, "%H:%M\0", tmS );
|
||||
if ( info != NULL ) {
|
||||
fgets( iS, 2048, info );
|
||||
m5??( 0 ??) = atoi( strtok( iS, ",\0" ) );
|
||||
for ( hr = 1; hr < 85; hr++ ) m5??(hr??) = atoi(S);
|
||||
for ( hr = 0; hr < 32; hr++ )
|
||||
m1??( hr ??) = strtoul( S, NULL, 10 );
|
||||
for ( hr = 0; hr < NB_MSGS; hr++ )
|
||||
for ( n = 0; n < 11; n++ )
|
||||
m??(hr??)??(n??) = (unsigned char)atoi( S );
|
||||
fclose( info );
|
||||
hr = atoi( strtok( tms, ":\0" ) );
|
||||
n = atoi( strtok( NULL, ":\0" ) );
|
||||
C( mA, 0 )
|
||||
C( out, 40 )
|
||||
s = setjmp( sT??( sI++ ??) );
|
||||
if ( s ) {
|
||||
s = setjmp( sT??( sI++ ??) );
|
||||
if ( s ); else goto doHr;
|
||||
} else goto doMin;
|
||||
} else {
|
||||
P "%s", tms );
|
||||
goto eoj;
|
||||
doMin:
|
||||
z = 22;
|
||||
C( doIt, 0 )
|
||||
bck
|
||||
doHr:
|
||||
hr = ( n >= 36 ) ? hr+1 : hr;
|
||||
if ( hr == 24 ) hr=0;
|
||||
if (hr&&hr!=12)(hr<12)?(P "%d ",hr)):(P "%d ",hr-12));
|
||||
n = hr + 61;
|
||||
q = 0;
|
||||
r = 1;
|
||||
z = 16;
|
||||
C( doIt, 0 )
|
||||
P "\n" );
|
||||
bck
|
||||
doIt:
|
||||
if ( r & m1??( m5??(n??) ??) ) {
|
||||
if (z == 22) q = q << 1;
|
||||
C( out, q )
|
||||
if (z == 22) q = q >> 1;
|
||||
}
|
||||
r = r << 1;
|
||||
q++;
|
||||
if ( q < z ) goto doIt;
|
||||
bck
|
||||
out:
|
||||
mI = 0;
|
||||
mNb += c1;
|
||||
while ( m??( mNb ??)??( mI ??) )
|
||||
P "%c", m??( mNb ??)??( mI++ ??) );
|
||||
bck
|
||||
mA:
|
||||
129<=m I ? 137>=m I ? m K=m I-32
|
||||
: 145<=m I ? 153>=m I ? m K=m I-39
|
||||
: 162<=m I ? 169>=m I ? m K=m I -47
|
||||
: j : j : j : 125==m I ? m K=39
|
||||
: 64==m I ? m K=32 : j;
|
||||
j++;
|
||||
if (m I) goto mA;
|
||||
i+=2;
|
||||
j = 0;
|
||||
if ( i < NB_MSGS ) goto mA;
|
||||
bck
|
||||
}
|
||||
|
||||
eoj: exit( 0 );
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,93 @@
|
||||
|
||||
int
|
||||
X=320 ,Y=200,
|
||||
n=0,m, x,y, j=1024;
|
||||
double T=44.0 /7,P[
|
||||
333333 ],C[5] ={ 0,3,
|
||||
0,0,8} ,p=1, B=11.0
|
||||
/630, f=0,r = 3,g
|
||||
=7,b =13,*q=P, D,*J;
|
||||
unsigned char
|
||||
U[66666],*v=U,*h,l[5555]
|
||||
,c=0,*e,*a,*z;
|
||||
|
||||
#include <math.h>
|
||||
#define R1(t) t=(int)(t\
|
||||
*123456789 )%j; t/=j;
|
||||
#define Rl(C,t)\
|
||||
n++[C] = t*n/12;
|
||||
#define RI(C) B=-B; R1\
|
||||
(r)R1(g )R1(b )for(n\
|
||||
=0; n<j; ){ Rl(C ,r)Rl\
|
||||
(C,g)Rl(C ,b)++n; }
|
||||
|
||||
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#include <sys/movedata.h>
|
||||
#include <dpmi.h>
|
||||
#include <pc.h>
|
||||
#define Q(u,v) u##portb(0x3##v
|
||||
#define W ; Q(out,C9),*h++/4)
|
||||
void F(int i){ __dpmi_regs r
|
||||
; if(i){ for(; i>=0; i-=8)while(
|
||||
~Q(in,DA)
|
||||
)&8^i); for(m=0,z
|
||||
=h+j; h <z; m ++){ Q(
|
||||
out,C8),m )W W W; ++h; } dosmemput
|
||||
(v,X*Y,0xA0000 ); } else{ r.x.ax=
|
||||
0x13; __dpmi_int( 0x10,&r); } }
|
||||
#elif defined(SDL)
|
||||
#include "SDL/SDL.h"
|
||||
SDL_Surface *s; void
|
||||
F(int i){ if (i){ SDL_SetColors(
|
||||
s,h,0,256); SDL_UpdateRect
|
||||
(s,0,0,0, 0); } else { SDL_Init(
|
||||
SDL_INIT_VIDEO); s=SDL_SetVideoMode
|
||||
(X,Y,8,0); v=s->pixels; } }
|
||||
#else
|
||||
#include "curses.h"
|
||||
void F(i){ if(i){ for(y=0;
|
||||
y<X*Y ; y++)
|
||||
{ move (y/X,y%X); addch
|
||||
((*(v +y)/ 32) [" ."
|
||||
",:+" "=@#" ]); } ; refresh
|
||||
(); } else{ initscr
|
||||
(),x= COLS&~1,X=x<X?x:X,y=
|
||||
LINES &~1,Y=y<Y?y:Y; } }
|
||||
#endif
|
||||
|
||||
main()
|
||||
{
|
||||
F(0);
|
||||
|
||||
for (x=-X/2,y=-Y/2;y<Y/2;++x>=X/2?x=-X/2,y++:4)
|
||||
{*q++ = sqrt(x*x+y*y);
|
||||
|
||||
*q++ = atan2(x,y);
|
||||
|
||||
}for (;n<j*2;l[n++]=0);
|
||||
for(;;)
|
||||
{
|
||||
a=l;z=l+j;e=l+j*2;
|
||||
if ((p+=B)>1){p=2-p;RI(l+j)}
|
||||
else if (p<0){p=-p;RI(l)}
|
||||
|
||||
while(a<l+j) D=p**a+++(1-p)**z++,*e++=D;
|
||||
h=l+j*2;
|
||||
|
||||
for (J=P,z=v; z<v+X*Y;){
|
||||
D = *J++;
|
||||
*z++=fabs(sin((*J+++C[1])*1.5+D*C[0]+C[2]*sin(C[3]+D/C[4]))*255);
|
||||
}F(8);
|
||||
|
||||
C[2]+=B; f+=T/360; C[3]+=f;
|
||||
|
||||
if (f>T)
|
||||
{C[1] += (f-T)/8;
|
||||
|
||||
if (f>T*2)
|
||||
C[0]=sin(f)+sin(f*2)/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
Most Portable Output:
|
||||
|
||||
Thaddaeus Frogley
|
||||
Creature Labs
|
||||
164 Hornbeams,
|
||||
Harlow, Essex,
|
||||
UK
|
||||
|
||||
Gavin Buttimore
|
||||
Creature Labs
|
||||
9 Elizabeth Way,
|
||||
Cambridge,
|
||||
UK, CB4 1DE
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make thadgavin
|
||||
|
||||
To run:
|
||||
|
||||
./thadgavin
|
||||
|
||||
This entry is a nice play by the rules. It can use curses, if the
|
||||
SDL graphic library is not present, and is quite good at that,
|
||||
but the colors used in graphic mode (16 bit depth) are unfortunately
|
||||
less than dazzling. We could not test this entry in DOS mode.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
To run under DOS:
|
||||
|
||||
Compile using DJGPP as follows:
|
||||
|
||||
gcc thadgavin.c -o thadgavin.exe -Wall -lm -O6 -mpentium -fomit-frame-pointer
|
||||
-ffast-math
|
||||
|
||||
To run under Windows, X-Windows or MacOS using the
|
||||
Simple DirectMedia Layer:
|
||||
|
||||
For example:
|
||||
|
||||
gcc -O6 -lpthread -g -o thadgavin thadgavin.c -lSDL -DSDL -lm
|
||||
|
||||
|
||||
In gcc you may get the following warning:
|
||||
|
||||
prog.c:46: warning: passing arg 2 of `SDL_SetColors' from incompatible
|
||||
pointer type
|
||||
|
||||
In Microsoft Visual Studio you may get warnings as follows:
|
||||
|
||||
prog.c(46) : warning C4133: 'function' : incompatible types - from 'unsigned
|
||||
char *' to 'struct SDL_Color *'
|
||||
prog.c(63) : warning C4026: function declared with formal parameter list
|
||||
prog.c(77) : warning C4244: '=' : conversion from 'double ' to 'unsigned
|
||||
char ', possible loss of data
|
||||
|
||||
|
||||
But don't worry, this is completely normal.
|
||||
|
||||
Recommended dosage:
|
||||
|
||||
At least 3 minutes taken 3 times a day when tired.
|
||||
|
||||
Do not exceed 3 times recommended dose. May cause
|
||||
sickness, dizziness, nausea.
|
||||
@@ -0,0 +1,101 @@
|
||||
// Initially you will be calm and serene:
|
||||
|
||||
int
|
||||
X=320 ,Y=200,
|
||||
n=0,m, x,y, j=1024;
|
||||
double T=44.0 /7,P[
|
||||
333333 ],C[5] ={ 0,3,
|
||||
0,0,8} ,p=1, B=11.0
|
||||
/630, f=0,r = 3,g
|
||||
=7,b =13,*q=P, D,*J;
|
||||
unsigned char
|
||||
U[66666],*v=U,*h,l[5555]
|
||||
,c=0,*e,*a,*z;
|
||||
|
||||
#include <math.h>
|
||||
#define R1(t) t=(int)(t\
|
||||
*123456789 )%j; t/=j;
|
||||
#define Rl(C,t)\
|
||||
n++[C] = t*n/12;
|
||||
#define RI(C) B=-B; R1\
|
||||
(r)R1(g )R1(b )for(n\
|
||||
=0; n<j; ){ Rl(C ,r)Rl\
|
||||
(C,g)Rl(C ,b)++n; }
|
||||
|
||||
|
||||
// Later your brain will look more like this:
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#include <sys/movedata.h>
|
||||
#include <dpmi.h>
|
||||
#include <pc.h>
|
||||
#define Q(u,v) u##portb(0x3##v
|
||||
#define W ; Q(out,C9),*h++/4)
|
||||
void F(int i){ __dpmi_regs r
|
||||
; if(i){ for(; i>=0; i-=8)while(
|
||||
~Q(in,DA)
|
||||
)&8^i); for(m=0,z
|
||||
=h+j; h <z; m ++){ Q(
|
||||
out,C8),m )W W W; ++h; } dosmemput
|
||||
(v,X*Y,0xA0000 ); } else{ r.x.ax=
|
||||
0x13; __dpmi_int( 0x10,&r); } }
|
||||
#elif defined(SDL)
|
||||
#include "SDL/SDL.h"
|
||||
SDL_Surface *s; void
|
||||
F(int i){ if (i){ SDL_SetColors(
|
||||
s,h,0,256); SDL_UpdateRect
|
||||
(s,0,0,0, 0); } else { SDL_Init(
|
||||
SDL_INIT_VIDEO); s=SDL_SetVideoMode
|
||||
(X,Y,8,0); v=s->pixels; } }
|
||||
#else
|
||||
#include "curses.h"
|
||||
void F(i){ if(i){ for(y=0;
|
||||
y<X*Y ; y++)
|
||||
{ move (y/X,y%X); addch
|
||||
((*(v +y)/ 32) [" ."
|
||||
",:+" "=@#" ]); } ; refresh
|
||||
(); } else{ initscr
|
||||
(),x= COLS&~1,X=x<X?x:X,y=
|
||||
LINES &~1,Y=y<Y?y:Y; } }
|
||||
#endif
|
||||
|
||||
main()
|
||||
{
|
||||
F(0);
|
||||
|
||||
for (x=-X/2,y=-Y/2;y<Y/2;++x>=X/2?x=-X/2,y++:4)
|
||||
{*q++ = sqrt(x*x+y*y);
|
||||
|
||||
// store result of atan2 of x and y in *q++
|
||||
*q++ = atan2(x,y);
|
||||
|
||||
}for (;n<j*2;l[n++]=0);
|
||||
for(;;)
|
||||
{
|
||||
a=l;z=l+j;e=l+j*2;
|
||||
if ((p+=B)>1){p=2-p;RI(l+j)}
|
||||
else if (p<0){p=-p;RI(l)}
|
||||
|
||||
// will the maintenance programmer get this?
|
||||
while(a<l+j) D=p**a+++(1-p)**z++,*e++=D;
|
||||
h=l+j*2;
|
||||
|
||||
// best way?
|
||||
for (J=P,z=v; z<v+X*Y;){
|
||||
D = *J++;
|
||||
*z++=fabs(sin((*J+++C[1])*1.5+D*C[0]+C[2]*sin(C[3]+D/C[4]))*255);
|
||||
}F(8);
|
||||
|
||||
// tidy up later
|
||||
C[2]+=B; f+=T/360; C[3]+=f;
|
||||
|
||||
// just in case
|
||||
if (f>T)
|
||||
{C[1] += (f-T)/8;
|
||||
|
||||
// sorry
|
||||
if (f>T*2)
|
||||
C[0]=sin(f)+sin(f*2)/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#define true
|
||||
|
||||
true /*:all
|
||||
|
||||
CC=cc
|
||||
PROG=tomx
|
||||
|
||||
false :
|
||||
make -f $0 $1
|
||||
exit 0
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
%:%.c
|
||||
$(CC) $< -o $@
|
||||
|
||||
clean:
|
||||
rm $(PROG)
|
||||
|
||||
.PHONY: /* true clean */
|
||||
int main() {return!printf("Hello, world\n");}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
Most Complete Program:
|
||||
|
||||
Thomas P John
|
||||
Mishybi Plamoottil
|
||||
Parottukonam
|
||||
Nalanchira P.O, Trivandrum-695015
|
||||
India
|
||||
|
||||
http://tomx.tripod.com/
|
||||
|
||||
|
||||
Judges' Comments:
|
||||
|
||||
To build:
|
||||
|
||||
make tomx
|
||||
|
||||
Try:
|
||||
|
||||
rm -f ./tomx
|
||||
sh tomx.c
|
||||
./tomx
|
||||
|
||||
If sh is your shell:
|
||||
|
||||
rm -f ./tomx
|
||||
chmod +x ./tomx.c
|
||||
./tomx.c
|
||||
./tomx
|
||||
|
||||
Also try:
|
||||
|
||||
rm -f ./tomx
|
||||
make -f tomx.c
|
||||
./tomx
|
||||
|
||||
Polyglots have come and gone, but this was the first one we'd seen
|
||||
where one language *used* another to perform its tasks. An interesting
|
||||
approach. Admittedly, it's not all that obfuscated - but there's more
|
||||
to it than you might think, since you have to make sure that your
|
||||
changes don't change the shell code or the makefile.
|
||||
|
||||
|
||||
Selected Author's Comments:
|
||||
|
||||
Summary
|
||||
-------
|
||||
This program works as a C source file, a Makefile and also as a
|
||||
Shell (/bin/sh) script. But unlike some other multi-language prog-
|
||||
rams, this one is NOT meant to print "Hello, world" in all 3 cases
|
||||
(At least in the true sense ;-)). The C, make and shell code build
|
||||
upon each other to create a C program (?) which when executed as a
|
||||
shell script will compile itself through the C compiler using a
|
||||
makefile! - Pretty useful, Eh?.
|
||||
|
||||
Probably, this is the first entry ever to fully satisfy Rule #1
|
||||
("Your entry must be a complete program") in the strictest sense;-)
|
||||
|
||||
Top 5 reasons (IMHO) why this code is an entry for IOCCC
|
||||
--------------------------------------------------------
|
||||
1. A glance at the source itself will tell U that most of the
|
||||
Obfuscation is NOT in the C code per se, but in the comments
|
||||
to the C code. (But sadly, I could not find an "International
|
||||
Obfuscated C COMMENT contest". So I HAD to sent this entry
|
||||
here to the IOCCC itself).
|
||||
|
||||
2. Of the 3 languages in the source, the least obfuscated is
|
||||
C (But again, there was NO obfuscated make/shscript contest)
|
||||
(Does this hint for a rule in IOCCC-2001 that the major
|
||||
obfuscation should be in C and not elsewhere???. Mmmmm...)
|
||||
|
||||
3. Extending Argument #2... Obfuscation done in the C code
|
||||
(comments?) create obfuscated code for the other 2 languages.
|
||||
This opens new possibilities to be explored in depth in future
|
||||
IOCCCs
|
||||
|
||||
4. LOOKS like a makefile, WORKS like a shell script and COMPILES
|
||||
like a C program
|
||||
|
||||
5. Does something useful (See Notes #1, #2)
|
||||
|
||||
Notes
|
||||
-----
|
||||
1. The program could have been something other than the simple
|
||||
"Hello, world" program that it is. It is possible to do
|
||||
#include "prog2.c" in the place of the main(), leaving the
|
||||
complexities of the C file elsewhere and making this source
|
||||
still acceptable to "make" and "sh". The following modif-
|
||||
ication to the last few lines will compile IOCCCs famous
|
||||
"mkentry.c"
|
||||
|
||||
.PHONY: /* true clean */
|
||||
#undef true
|
||||
#include "mkentry.c"
|
||||
|
||||
Ain't that useful?
|
||||
|
||||
2. By extending this program's idea, It is possible to do some
|
||||
very interesting things like generating C code on execution
|
||||
by adding additional code in make/sh (open up a loop????).
|
||||
This opens the possibilities of generating & compiling some
|
||||
[obfuscated?] C code.(Maybe should try this if this program
|
||||
fails at IOCCC 2000)
|
||||
|
||||
3. Changing the "%:%.c" dependency to a "$(PROG):$(PROG).c" form
|
||||
can compile this program with some other make-s (I got it to
|
||||
work in Windows using nmake and Gnuwin32's sh ;-)
|
||||
|
||||
4. Interesting things to do: try "$ ./tomx.c clean". This will
|
||||
do the same as "make clean" :-)). Also: "$ ./tomx.c all"
|
||||
|
||||
5. Be careful about the Tabs in the source code. Removing them
|
||||
or converting Tabs to spaces can be disasterous
|
||||
|
||||
Reference in new issue
Block a user