Add preview of 1984-2019

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

One will find HTML commented out with:

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

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

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

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

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

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

No files matched your search

BIN
View File
Binary file not shown.
+146
View File
@@ -0,0 +1,146 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# ANSI compiler
#
# Set CC to the name of your ANSI compiler.
#
CC= cc
###############
# IOCCC winners
###############
#
WINNERS= birken cable1 cable2 cable3 dlowe endoh1 endoh2 endoh3 endoh4 \
hou mills misaka morgan1 morgan2 robison
###################
# build all entries
###################
#
all:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) X11_LIBDIR=${X11_LIBDIR} X11_INCDIR=${X11_INCDIR} $@)"; \
(cd $$i && $(MAKE) "X11_LIBDIR=${X11_LIBDIR}" "X11_INCDIR=${X11_INCDIR}" $@); \
done
# alternative executable
#
alt:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) X11_LIBDIR=${X11_LIBDIR} X11_INCDIR=${X11_INCDIR} $@)"; \
(cd $$i && $(MAKE) "X11_LIBDIR=${X11_LIBDIR}" "X11_INCDIR=${X11_INCDIR}" $@); \
done
###############
# utility rules
###############
#
everything: all alt
clean:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
clobber:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
nuke: clobber
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
install:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
haste:
$(MAKE) waste
waste:
@echo 'waste'
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall be disallowed from not being unable to partly misunderstand this partocular final echo.
@${TRUE}
# These rules are written in the sytle of "I Am the Walrus"
# and in particular John Lennon's take on deep analysis of art. :-)
#
# See also the sub-directory Makefiles for non-propaganda.
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v3; \
else \
echo "You are not expected to understand this"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 1c2c85c7a02c55d1add91967eca491d53c101dc1 --FNV1a_hash 256-bit -R ."; \
else \
echo "Understand different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 256-bit -R ."; \
else \
echo "These aren't the droids you're looking for Mr. Spock!"; \
fi
@${TRUE}
+130
View File
@@ -0,0 +1,130 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="hint.css">
<title>README</title>
</head>
<body>
<h1>2013 marked the &ldquo;The Twenty Second International Obfuscated C Code Contest&rdquo;</h1>
<p>Copyright &copy; 2013, Landon Curt Noll, Simon Cooper, and Leonid A.
Broukhis. 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.</p>
<h2>Standard IOCCC stuff</h2>
<p>The IOCCC has a web site and now has a number of international mirrors.
The primary site can be found at,</p>
<blockquote><p> <a href="http://www.ioccc.org/">http://www.ioccc.org/</a></p></blockquote>
<p>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.</p>
<p>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 submitter.</p>
<p>Read over the makefile for compile/build issues. Your system may require
certain changes (add or remove a library, add or remove a #define).</p>
<p>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.</p>
<h2>Remarks on some of the entries</h2>
<p>We believe you will again be impressed with this year&rsquo;s winners.</p>
<p>This year, several 8 people won 9 people won 15 awards. For the
first time in the history of the contest, one person, Yusuke Endoh,
won 4 times while Adrian Cable won 3 times! It is also worth noting
that Chris Mills previous win was in 1993. Welcome back Chris!</p>
<p>We, the judges, were very surprised by this as many of the multiple
winners submitted very different styles of entries.</p>
<p>This year was the first time the IOCCC size tool was used. Entries
had to print a value 2053 or less when the -i flag was used.</p>
<p>Several people discovered an undocumented feature in that
certain comments such as:</p>
<pre><code>///*
</code></pre>
<p>or:</p>
<pre><code>*\
/
</code></pre>
<p>were not correctly parsed by the tool. The guidelines stated:</p>
<pre><code>In cases where the above summary and the algorithm implemented by
the IOCCC size tool source code conflict, the algorithm implemented
by the IOCCC size tool source code is preferred by the judges.
</code></pre>
<p>so this abuse was allowed (and encouraged). The judges hope that
the IOCCC size tool author will patch the tool to block this kind
of size abuse in future contests.</p>
<p>There were some outstanding entries that did not win. Unfortunately
some very good entries lost because they:</p>
<ul>
<li><p>were way way oversize and didn&rsquo;t even attempt to justify their
excess by a clever abuse of the rules</p></li>
<li><p>depend on a single obfuscation trick</p></li>
<li><p>could only be run on a particular vendor&rsquo;s platform</p></li>
<li><p>were very similar to previous winners</p></li>
<li><p>didn&rsquo;t work as documented</p></li>
</ul>
<p>We hope the authors of some of those entries will fix and re-submit
them for the next IOCCC.</p>
<p>There is a risk in submitting an entry that is similar to a well
used theme by previous winners. Previous winners set a very high
bar. A new winner must not only compete against other submissions
from the current year, they must also excel over similar winners
in some particularly impressive way.</p>
<h2>Final Comments</h2>
<p>Please feel free to send us comments and suggestions about the
competition, this README or anything else that you would like to see in
future contests.</p>
<p>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.</p>
<p>If you have problems with any of the entries, AND YOU HAVE A FIX, please
send us the fix (patch file or the entire changed file).</p>
<p>For the latest information on how to contact the IOCCC Judges please visit</p>
<blockquote><p> <a href="http://www.ioccc.org/contact.html">http://www.ioccc.org/contact.html</a></p></blockquote>
<p>For news of the next contest watch:</p>
<blockquote><p> <a href="http://www.ioccc.org/">http://www.ioccc.org/</a></p></blockquote>
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2013,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+123
View File
@@ -0,0 +1,123 @@
2013 marked the "The Twenty Second International Obfuscated C Code Contest"
===========================================================================
Copyright (C) 2013, Landon Curt Noll, Simon Cooper, and Leonid A.
Broukhis. 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
--------------------
The IOCCC has a web site and now has a number of international mirrors.
The primary site can be found at,
> <http://www.ioccc.org/>
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 submitter.
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.
Remarks on some of the entries
------------------------------
We believe you will again be impressed with this year's winners.
This year, several 8 people won 9 people won 15 awards. For the
first time in the history of the contest, one person, Yusuke Endoh,
won 4 times while Adrian Cable won 3 times! It is also worth noting
that Chris Mills previous win was in 1993. Welcome back Chris!
We, the judges, were very surprised by this as many of the multiple
winners submitted very different styles of entries.
This year was the first time the IOCCC size tool was used. Entries
had to print a value 2053 or less when the -i flag was used.
Several people discovered an undocumented feature in that
certain comments such as:
///*
or:
*\
/
were not correctly parsed by the tool. The guidelines stated:
In cases where the above summary and the algorithm implemented by
the IOCCC size tool source code conflict, the algorithm implemented
by the IOCCC size tool source code is preferred by the judges.
so this abuse was allowed (and encouraged). The judges hope that
the IOCCC size tool author will patch the tool to block this kind
of size abuse in future contests.
There were some outstanding entries that did not win. Unfortunately
some very good entries lost because they:
+ were way way oversize and didn't even attempt to justify their
excess by a clever abuse of the rules
+ depend on a single obfuscation trick
+ could only be run on a particular vendor's platform
+ were very similar to previous winners
+ didn't work as documented
We hope the authors of some of those entries will fix and re-submit
them for the next IOCCC.
There is a risk in submitting an entry that is similar to a well
used theme by previous winners. Previous winners set a very high
bar. A new winner must not only compete against other submissions
from the current year, they must also excel over similar winners
in some particularly impressive way.
Final Comments
--------------
Please feel free to send us comments and suggestions about the
competition, this README or anything else that you would like to see in
future contests.
If you use, distribute or publish these entries in some way, please drop
us a line. We enjoy seeing who, where and how the contest is used.
If you have problems with any of the entries, AND YOU HAVE A FIX, please
send us the fix (patch file or the entire changed file).
For the latest information on how to contact the IOCCC Judges please visit
> <http://www.ioccc.org/contact.html>
For news of the next contest watch:
> <http://www.ioccc.org/>
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2013, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+212
View File
@@ -0,0 +1,212 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall -W
CWARN= -Wall -pedantic -Wno-newline-eof
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT} ${LIBS}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= birken
DATA= examples.tbz2 images.tbz2
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} data
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
${RM} -rf examples
@echo extracting examples
${TAR} -jxf examples.tbz2
${RM} -rf images
@echo extracting images
${TAR} -jxf images.tbz2
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
${RM} -rf examples
@-if [ ! -e .keep_ioccc_2013 ]; then \
echo ${RM} -rf images; \
${RM} -rf images; \
fi
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
+49
View File
@@ -0,0 +1,49 @@
char*_ = "'""/*";
#include <stdio.h>
#define m 21
#define o(l, k) for(l=0; l<k; l++)
#define n(k) o(T, k)
int E,L,O,R,G[42][m],h[2][42][m],g[3][8],c
[42][42][2],f[42]; char d[42]; void v( int
b,int a,int j){ printf("\33[%d;%df\33[4%d"
"m ",a,b,j); } void u(){ int T,e; n(42)o(
e,m)if(h[0][T][e]-h[1][T][e]){ v(e+4+e,T+2
,h[0][T][e]+1?h[0][T][e]:0); h[1][T][e]=h[
0][T][e]; } fflush(stdout); } void q(int l
,int k,int p){
int T,e,a; L=0
; O=1; while(O
){ n(4&&L){ e=
k+c[l] [T][0];
h[0][L-1+c[l][
T][1]][p?20-e:
e]=-1; } n(4){ e=k+c[l][T][0]; a=L+c[l][T][
1]+1; if(a==42 || h[0][a][p?20-e:e]+1){ O=0
; } } n(4){ e= k+c[l][T][0]; h[0][L + c[l][
T][1]][p?20-e: e]=g[1][f[p?19+l:l]]; } L++;
u(); } n(42) { o(e,m)if(h[0][T][e]<0)break;
o(a, m&&e==m){ for(L=T; L; L--) { h[0][L][a
]=h[0][L-1] [a ]; } h[0][0][a]=-1; } } u();
}int main(){ int T,e,t,r,i,s ,D,V,K; printf("\33[2J\33[?25l"); n(8)g[i=
1][T]=7-T; R--; n(42) o(e,m) G[T][e]--; while(fgets(d,42,stdin)) { r=++
R; n(17){ e=d[T]-48; d[T]=0; if ((e&7)==e) { g[0][e] ++; G[R][T+2]=e; }
} } n(8)if(g[0][7-T]){ t=g[i ][O]; g[i][O++]=g[i][T]; g[i][T]=t; } n(8)
g[2][g[i][T]]=T; n(R+i)o(e,m )if(G[T][e]+i) G[T][e]=g[2][G[T][e]]; n(19
)o(t,2){ f[T+t+T]=(T["+%#,4" "5>GP9$5-,#C?NX"]-35)>>t*3&7; o(e,4){ c[T]
[e][t]=("5'<$=$8)Ih$=h9i8'9" "t=)83)l4(99(g9>##>4(" [T+t+T]-35)>>e*2&3;
} } n(15) { s=T>9?m:(T&3)-3?15:36;o(e,s)o(t,2)c[T+19][e][t]="6*6,8*6.608.6264826668\
865::(+;0(6+6-6/8,61638065678469.;88))()3(6,8*6.608.6264826668865:+;4)-*6-6/616365,\
-6715690.5;,89,81+,(023096/:40(8-7751)2)65;695(855(+*8)+;4**+4(((6.608.626482666886\
5:+;4+4)0(8)6/61638065678469.;88)-4,4*8+4(((60(/6264826668865:+;4-616365676993-9:54\
+-14).;./347.+18*):1;-*0-975/)936.+:4*,80987(887(0(*)4.*""/4,4*8+4(((6264826668865:\
+;4/4-4+8-4)0(8)6365678469.;88)1/(6*6,6.60626466686:8)8-8*818.8582/9863(+;/""*6,6.6\
0626466686:4(8)8-8*818.8582/9863(+;/,6.60626466686:8-818.8582/9864*4+4(0())+;/.6062\
6466686:8/8380/7844,4-4*4+4(0())69+;/0626466686:818582/9864.4/4,4-4*4+4(0())+;" [e+E
+e+t]-40; E+=s+s; } n(45){ if(T>i) { v(2,T,7); v(46,T,7); } v(2+T,44,7); } T=0; o(e,
42)o(t,m)h[T][e][t]--; while(R+i) { s = D=0; if (r-R) { n(19) if (G[R+i][T]+i) V=T/2
; else if(G[R][T]+i) s++; if(s) { if(V>4){ V=9-V; D++; } V+=29; n(20) q(c[V][T][0],c
[V][T][i],D); } } n(19) if((L=G[R][T])+i) { O=T-L; e=O>9; t=e?18-O :O; o(K,((t&3)-3?
16:37)){ if(K){ L=c[t+19][K-i][0]; O=c[t+19][K-i][i] ; } q(L,O,K && e); } } if(s) q(
c[V][20][0], c[V][20][i], D); R--; } printf("\33[47;1f\33[?25h\33[40m"); return 0; }
Binary file not shown.
+295
View File
@@ -0,0 +1,295 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Best painting tool</title>
</head>
<body>
<h1>Best painting tool</h1>
<p>Michael Birken<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#111;&#95;&#95;&#x31;&#64;&#x68;&#x6f;&#116;&#109;&#97;&#x69;&#108;&#x2e;&#x63;&#x6f;&#x6d;">&#x6f;&#95;&#x5f;&#49;&#64;&#x68;&#111;&#x74;&#109;&#97;&#x69;&#108;&#46;&#99;&#x6f;&#109;</a><br>
<a href="http://www.meatfighter.com/">http://www.meatfighter.com/</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make birken
</code></pre>
<h3>To run:</h3>
<pre><code>./birken &lt; 17_columns_wide_paint_by_numbers_file
</code></pre>
<h3>Try:</h3>
<pre><code>./birken &lt; examples/ioccc.txt
perl -e 'map{map{print int(rand()*8);}(0..16);print chr(10);}(0..30);' | tr '[0-4]' ' '| ./birken
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This program also wins the &ldquo;Most amusing abuse of the iocccsize tool&rdquo; award; although not the
absolute best: it is possible to achieve 0 by writing</p>
<pre><code>/* *\
/....
</code></pre>
<p>The game of Tetris had been used in many endeavors, from studying <a href="http://arxiv.org/abs/cs/0210020">algorithmic complexity</a> to <a href="http://www.livescience.com/19894-tetris-treat-ptsd-flashbacks.html">treating PTSD</a>.
Using it for painting by numbers looks like a novel idea.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>About This Document</h3>
<p>This document is best viewed as an HTML file in a browser that supports animated gifs. Extract <code>examples.tbz2</code> for the sample input files.</p>
<pre><code>tar -xjvf examples.tbz2
</code></pre>
<h3>Abstract</h3>
<p>By rotating, positioning and dropping a predetermined sequence of pieces, this program exploits the mechanics of Tetris to generate arbitrary images.</p>
<h3>Algorithm Overview</h3>
<p>The algorithm converts pixels from a source image into squares in the Tetris playfield, one row at a time from the bottom up. To generate an individual square, the algorithm assembles a structure consisting of a rectangular region fully supported by a single square protruding from the bottom. When the rectangular region is completed, its rows are cleared, leaving behind the protruding square. Three examples of the process appear below.</p>
<p><img src="pen0.gif" alt="" /></p>
<p><img src="pen1.gif" alt="" /></p>
<p><img src="pen2.gif" alt="" /></p>
<p>During construction of a row, all of the squares produced by this method must be supported. In the images above, the generated squares are supported by the floor of the playfield. However, if an arbitrary row contains holes, it may not provide the support necessary for the construction of the row above it. The algorithm solves this problem by constructing a flat platform on top of the row with holes. In the animation below, a platform is built above a row comprising of a single red square. The platform is a temporary structure and inserting the final piece removes it.</p>
<p><img src="platform0.gif" alt="" /></p>
<p>Below, a row containing 5 red squares is deposited above a row containing 3 red squares. This is accomplished by building a flat platform on top of the lower row. The platform provides the support necessary to generate the 5 red squares. Finally, the platform is removed by inserting its final piece and the new row drops into place. Note, if the algorithm needed to generate the rows in the opposite order (a row of 3 red squares above a row of 5 red squares), a platform would not be necessary.</p>
<p><img src="platform1.gif" alt="" /></p>
<h3>Single Square Emitters</h3>
<p>For reference, the names of the 7 Tetriminos (the game pieces) appear in the table below.</p>
<p><img src="names.png" alt="" /></p>
<p>This algorithm was tailored specifically to render sprites from early video games. Those games packed graphics into 8&times;8 tiles where 2 bits were dedicated to each pixel. Consequentially, sprites usually contained only 3 colors plus transparent regions and they were typically sized either 16&times;16 or 16&times;32 pixels.</p>
<p>The animation below depicts all the patterns used to emit single squares. J, T and L Tetriminos are used interchangeably within each pattern to produce the protruding square at the bottom. The algorithm assigns those Tetriminos to the 3 colors present in the sprite. The remaining Tetriminos are assigned arbitrary colors. And, all the colors remain constant during gameplay.</p>
<p><img src="pen4.gif" alt="" /></p>
<p>It is not possible to emit a square of all 3 colors in the first 2 and the last 2 columns due to the shapes of the 3 Tetriminos. As a result, the minimal width of a playfield to accommodate a 16 pixel wide sprite is 2 + 16 + 2 = 20 squares. However, it turns out that 20 is too small.</p>
<p>As illustrated below, the region above the protruding square cannot exclusively consist of a single row because the only pieces that could fit, the I Tetriminos, are unsupported.</p>
<p><img src="pen5.gif" alt="" /></p>
<p>With 2 rows, the only means of spanning the full playfield width in a way that remains supported is to use S and Z Tetriminos. But, that will always leave holes in the upper row.</p>
<p><img src="pen6.gif" alt="" /></p>
<p>The minimal number of rows required above the protruding square is 3 and as shown repeatedly above, such patterns do exist. 20 squares is the minimal width required to fit a 16 pixel wide sprite. But, 20 &times; 3 + 1 = 61, which is not divisible by 4 and hence not constructible out of Tetriminos. However, a width of 21 yields 21 &times; 3 + 1 = 64, which can be built with 16 Tetriminos. That width actually enables the algorithm to render sprites up to 17 pixels wide.</p>
<p>The original Tetris playfield is 10&times;20 squares, a 1:2 ratio. The program maintains that ratio by using a playfield of 21&times;42 squares.</p>
<p>Since J, T and L Tetriminos are used interchangeably to produce the emitted square and 3 squares of those Tetriminos contribute to the row above it, there are 21 &#8722; 3 + 1 = 19 single square emitting patterns. However, due to mirror symmetry, there are really only 10 patterns. Clearing 3 rows works for the majority of them. But, an exhaustive computer search revealed that 2 of the patterns require more. The next possible option is 7 rows since 21 &times; 7 + 1 = 148, requiring 37 Tetriminos. As the images below show, those patterns do exist.</p>
<p><img src="pen7.gif" alt="" /></p>
<p><img src="pen8.gif" alt="" /></p>
<h3>Platforms</h3>
<p>Before a row is constructed, the algorithm inspects the row below it. If the row below fails to provide support for all of the squares to be deposited above it, then a temporary platform is required. When that platform is removed, the new row will drop, leaving some of the squares apparently floating above empty space due to the way that gravity works in the original Tetris.</p>
<p>The illustration below depicts the 10 platform patterns (really only 5 considering mirror symmetry). The construction of a platform begins by dropping a T Tetrimino on top one of the squares of the last generated row. The remaining Tetriminos support each other down to that first T. Meaning, as long as the previously generated row contains at least 1 square, like the red square below, then it is possible to construct a flat platform above it for the generation of the next row.</p>
<p><img src="platform2.gif" alt="" /></p>
<p>In the middle of platform construction, the bottom row gets completed and cleared, leaving 3 rows above it. The final J or L Tetrimino that will remove those rows is not inserted until the square emitters are done generating the next row of the sprite on top of the platform. That final piece precludes square emission in the first and last 2 columns. But, as discussed above, the square emitters are limited to the 17 inner columns due to the geometry of the J, T and L Tetriminos used in the process.</p>
<p>Also, of the 19 possible ways to start constructing a platform on top of a T Tetrimino, only the 10 patterns shown above exist.</p>
<h3>Program Input</h3>
<p>The input sprite is represented textually. Digit characters <code>0</code> to <code>7</code> correspond to pixels with colors from the palette below.</p>
<p><img src="palette.png" alt="ANSI color palette" /></p>
<p>As discussed above, sprites are limited to a maximum of 3 colors from this palette.</p>
<p>All other characters are interpreted as transparent pixels.</p>
<p>The maximum permissible size of the input text is 32 rows by 17 columns. Row length can vary as long as no single row exceeds 17 characters.</p>
<p>Every row must contain at least one palette digit character.</p>
<p>The <code>examples</code> directory contains several sprites in this textual format that can be fed into standard input. Several examples take advantage of the Tetris playfield background color. Instead of using character <code>0</code>, internal regions marked as transparent are effectively rendered as black.</p>
<h3>Program Output</h3>
<p>The program conceptually uses Tetris as an output device similar to a line printer. It restricts itself to those operations that can be performed on the Tetris playfield: spawning, rotating, positioning and dropping Tetriminos. This process is visually represented using ANSI escape sequences.</p>
<h3>ANSImation</h3>
<p>The rate at which the program plays Tetris is completely determined by the rate in which the terminal application receives and displays the ANSI escape sequences.</p>
<p>To slowdown the output programmatically, introduce a delay immediately after the call to <code>fflush</code>.</p>
<h3>IOCCC Size Tool Bug</h3>
<p>This program demonstrates how to exploit a bug in IOCCC size tool version 2013-07-30-v17. The first line of the program is reproduced below.</p>
<pre><code>char*_ = "'""/*";
</code></pre>
<p>If that line is added to the top of any program, the tool will report a size of 8.</p>
<pre><code>./iocccsize -i &lt; prog.c
8
</code></pre>
<p>When that line is deleted from this program, the tool properly reports the secondary size limit of the program as 2048.</p>
<pre><code>./iocccsize -i &lt; prog.c
2048
</code></pre>
<p>Although this bug provides an easy means of circumventing contest rule 2, as demonstrated from the size value, this entry is not necessarily striving for a &lsquo;worst abuse of the rules&rsquo; award.</p>
<h3>Obfuscations</h3>
<p>This program is almost, but not quite, entirely unlike a demonstration of good programming practices. Contrary to other programs, an inspection of this one will certainly reveal that it possesses tea, not to mention an affinity for the constant 42.</p>
<p>Variables are named and ordered to spell out, &ldquo;Tetris&rdquo;, &ldquo;ELORG&rdquo;, &ldquo;DVK&rdquo; and the aforementioned &ldquo;Tea&rdquo;. ELORG is the abbreviation for Elektronorgtechnica, the former Soviet state owned computer organization that handled the worldwide Tetris intellectual property rights. DVK is the line of Soviet PDP-11-compatible personal computers capable of running Alexey Pajitnov&rsquo;s original 1984 Tetris prototype.</p>
<p>Carefully selected variable names also yielded wonderful expressions like <code>l=0</code>, <code>O=0</code>, <code>O=1</code> and <code>while(O)</code>. &ldquo;Tetris&rdquo; also makes a second appearance of sorts:</p>
<pre><code>[T][e][t]--; while(R+i) { s
</code></pre>
<p>The source is formatted to resemble the Tetris playfield midgame. It is also an homage to all the past IOCCC entries formatted as a compact block of text; the T, orientated appropriately to reflect its name and the first letter in the title of the game, is just a moment away from producing such a text block.</p>
<p>Three tables are encoded as separate strings within the program:</p>
<p>The first string stores the coordinates of the squares of the 19 distinct rotations of Tetriminos (see below). Since a Tetrimino is a chain of 4 squares, all Tetriminos fit within a 4&times;4 matrix. To determine the coordinates of the squares, the Tetrimino is pushed to the upper-left of the matrix. Each coordinate value requires 2 bits of storage. Consequentially, the four x-coordinates and the four y-coordinates were packed into separate octets. To convert the octets into valid ASCII characters, the squares were sorted such that the least significant bits stored the largest coordinate values. The results were offset by 35, the <code>#</code> character, which is 1 beyond the ASCII value of <code>"</code>, making it easier to pack into a string. None of the resultant values are beyond ASCII 127. The coordinates for all 19 rotations fit in a string of length 38.</p>
<p><img src="rotations.png" alt="" /></p>
<p>The second string stores the single square emitter patterns and the platform patterns. Each pattern is a sequence of pairs, { Tetrimino index, drop x-coordinate }. As mentioned, there are 19 distinct rotations, requiring 5 bits of storage for the Tetrimino index. Another 5 bits is required for the drop x-coordinate since there are 21 columns in the playfield. Necessarily, the pair is stored as 2 separate characters. By offsetting them by 40, the <code>(</code> character, the resultant string almost resembles a long and complex mathematical expression. The program takes advantage of mirror symmetry by only storing 10 single square emitter patterns and 5 platform patterns. The pattern lengths are not encoded within the string. Rather, they are embedded within the string decoding logic.</p>
<p>The third string conceptually stores the default colors of the 19 rotations. A 3-bit value is assigned to each, covering the 7 possible colors. In addition, when a mirrored pattern is executed, J exchanges with L and S exchanges with Z, necessitating a second list of 3-bit color values. Pairs of color values (6 bits) fit comfortably into a character that is offset by <code>#</code>. The result is a string of length 19.</p>
<p>The program is full of subtle obfuscations:</p>
<ul>
<li><p>The unary decrement operator is used in conjunction with global variable automatic zero initialization to set variables to <code>-1</code>.</p></li>
<li><p>The boolean expression of the form, <code>x + 1</code>, is used multiple times to determine if a value is not <code>-1</code>. Similarly, expressions of the form <code>x - y</code> are used to determine if <code>x != y</code>.</p></li>
<li><p>Several arrays store unrelated data in segments throughout the array to reduce named variables.</p></li>
<li><p>The <code>x["..."]</code> trick appears once.</p></li>
<li><p>Variable <code>i</code> is less than necessary.</p></li>
<li><p>A cursorily glance at the expressions <code>4&amp;&amp;L</code> and <code>m&amp;&amp;e==m</code> suggests that they always evaluate to true.</p></li>
<li><p>The varying single square emitter pattern lengths are resolved during string decoding using the clever expression, <code>(i &amp; 3) - 3</code>, which identifies pattern 3 and 7 as longer.</p></li>
<li><p>The file size of <code>prog.c</code> is a prime number. Deleting the first line also produces a prime-sized program. These properties do not qualify the program as a prime number generator.</p></li>
</ul>
<h3>Beyond Obfuscation</h3>
<p>Due to the contest code size constraint, some optimizations reluctantly had to be omitted. For example, multi-square emitters are possible:</p>
<p><img src="multi2.gif" alt="" /></p>
<p><img src="multi3.gif" alt="" /></p>
<p><img src="multi4.gif" alt="" /></p>
<p><img src="multi5.gif" alt="" /></p>
<p>In fact, using dynamic programming and creative heuristics, real-time search is possible, enabling patterns like this:</p>
<p><img src="triple0.gif" alt="" /></p>
<p>And, even this:</p>
<p><img src="triple1.gif" alt="" /></p>
<p>In addition, it is possible to extend the algorithm to 6 colors instead of just 3. This is achieved using I, S and Z to produce the protruding square. A series of rectangular regions are constructed above those Tetriminos to erode them down to a single emitted square.</p>
<p>The details of these enhancements are left as an exercise to the reader.</p>
<h3>Example Files</h3>
<p>The following example files were created by the program author. They can be freely used and distributed.</p>
<ul>
<li><code>format.txt</code> - The layout of the program</li>
<li><code>helloworld.txt</code> - Hello World, Tetris-style</li>
<li><code>hilbert.txt</code> - A graphic based on the Hilbert curve</li>
<li><code>ioccc.txt</code> - IOCCC</li>
<li><code>landon.txt</code> - Portrait of a man with glasses</li>
<li><code>leo.txt</code> - Portrait of a man without glasses</li>
<li><code>rhino.txt</code> - A purple rhinoceros</li>
<li><code>simon.txt</code> - Portrait of a man without hair</li>
</ul>
<p>The following files are based on graphics from non-free, copyrighted video games. The use of a limited number of textual representations of the graphics for the demonstration of this program qualifies as fair use as such files do not significantly impede the right of the copyright holder to sell the copyrighted material and it is not being used to generate profit in this context. The origin of each file is detailed below (character, game, company, year).</p>
<ul>
<li><code>belmont.txt</code> - Simon Belmont, Castlevania, Konami, 1986</li>
<li><code>bloober.txt</code> - Bloober, Super Mario Brothers, Nintendo, 1985</li>
<li><code>bomberman.txt</code> - Bomberman, Bomberman, Hudson, 1983</li>
<li><code>boo.txt</code> - Boo, Super Mario Brothers 3, Nintendo, 1988</li>
<li><code>bub.txt</code> - Bub, Bubble Bobble, Taito, 1986</li>
<li><code>cheepcheep.txt</code> - Cheep Cheep, Super Mario Brothers, Nintendo, 1985</li>
<li><code>gurin.txt</code> - Gurin, Binary Land, Hudson, 1983</li>
<li><code>koopaparatroopa.txt</code> - Koopa Paratroopa, Super Mario Brothers, Nintendo, 1985</li>
<li><code>lakitu.txt</code> - Lakitu, Super Mario Brothers, Nintendo, 1985</li>
<li><code>mario.txt</code> - Fire Mario, Super Mario Brothers, Nintendo, 1985</li>
<li><code>mspacman.txt</code> - Ms. Pac-Man and Ghost, Ms. Pac-Man, Midway, 1982</li>
<li><code>paranaplant.txt</code> - Piranha Plant, Super Mario Brothers, Nintendo, 1985</li>
<li><code>samus.txt</code> - Samus Aran, Metroid, Nintendo/Intelligent Systems, 1986</li>
<li><code>toad.txt</code> - Toad, Super Mario Brothers 2, Nintendo, 1987</li>
</ul>
<p>The origin of the remaining files are described below:</p>
<ul>
<li><code>happyface.txt</code> - Based on a smiley; rights unknown</li>
<li><code>snoo.txt</code> - 8-bit version of Snoo, Reddit&rsquo;s alien mascot</li>
</ul>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+261
View File
@@ -0,0 +1,261 @@
# Best painting tool
Michael Birken
<o__1@hotmail.com>
<http://www.meatfighter.com/>
## Judges' comments:
### To build:
make birken
### To run:
./birken < 17_columns_wide_paint_by_numbers_file
### Try:
./birken < examples/ioccc.txt
perl -e 'map{map{print int(rand()*8);}(0..16);print chr(10);}(0..30);' | tr '[0-4]' ' '| ./birken
### Selected Judges Remarks:
This program also wins the "Most amusing abuse of the iocccsize tool" award; although not the
absolute best: it is possible to achieve 0 by writing
/* *\
/....
The game of Tetris had been used in many endeavors, from studying [algorithmic complexity](http://arxiv.org/abs/cs/0210020) to [treating PTSD](http://www.livescience.com/19894-tetris-treat-ptsd-flashbacks.html).
Using it for painting by numbers looks like a novel idea.
## Author's comments:
### About This Document
This document is best viewed as an HTML file in a browser that supports animated gifs. Extract `examples.tbz2` for the sample input files.
tar -xjvf examples.tbz2
### Abstract
By rotating, positioning and dropping a predetermined sequence of pieces, this program exploits the mechanics of Tetris to generate arbitrary images.
### Algorithm Overview
The algorithm converts pixels from a source image into squares in the Tetris playfield, one row at a time from the bottom up. To generate an individual square, the algorithm assembles a structure consisting of a rectangular region fully supported by a single square protruding from the bottom. When the rectangular region is completed, its rows are cleared, leaving behind the protruding square. Three examples of the process appear below.
![](pen0.gif)
![](pen1.gif)
![](pen2.gif)
During construction of a row, all of the squares produced by this method must be supported. In the images above, the generated squares are supported by the floor of the playfield. However, if an arbitrary row contains holes, it may not provide the support necessary for the construction of the row above it. The algorithm solves this problem by constructing a flat platform on top of the row with holes. In the animation below, a platform is built above a row comprising of a single red square. The platform is a temporary structure and inserting the final piece removes it.
![](platform0.gif)
Below, a row containing 5 red squares is deposited above a row containing 3 red squares. This is accomplished by building a flat platform on top of the lower row. The platform provides the support necessary to generate the 5 red squares. Finally, the platform is removed by inserting its final piece and the new row drops into place. Note, if the algorithm needed to generate the rows in the opposite order (a row of 3 red squares above a row of 5 red squares), a platform would not be necessary.
![](platform1.gif)
### Single Square Emitters
For reference, the names of the 7 Tetriminos (the game pieces) appear in the table below.
![](names.png)
This algorithm was tailored specifically to render sprites from early video games. Those games packed graphics into 8&times;8 tiles where 2 bits were dedicated to each pixel. Consequentially, sprites usually contained only 3 colors plus transparent regions and they were typically sized either 16&times;16 or 16&times;32 pixels.
The animation below depicts all the patterns used to emit single squares. J, T and L Tetriminos are used interchangeably within each pattern to produce the protruding square at the bottom. The algorithm assigns those Tetriminos to the 3 colors present in the sprite. The remaining Tetriminos are assigned arbitrary colors. And, all the colors remain constant during gameplay.
![](pen4.gif)
It is not possible to emit a square of all 3 colors in the first 2 and the last 2 columns due to the shapes of the 3 Tetriminos. As a result, the minimal width of a playfield to accommodate a 16 pixel wide sprite is 2 + 16 + 2 = 20 squares. However, it turns out that 20 is too small.
As illustrated below, the region above the protruding square cannot exclusively consist of a single row because the only pieces that could fit, the I Tetriminos, are unsupported.
![](pen5.gif)
With 2 rows, the only means of spanning the full playfield width in a way that remains supported is to use S and Z Tetriminos. But, that will always leave holes in the upper row.
![](pen6.gif)
The minimal number of rows required above the protruding square is 3 and as shown repeatedly above, such patterns do exist. 20 squares is the minimal width required to fit a 16 pixel wide sprite. But, 20 &times; 3 + 1 = 61, which is not divisible by 4 and hence not constructible out of Tetriminos. However, a width of 21 yields 21 &times; 3 + 1 = 64, which can be built with 16 Tetriminos. That width actually enables the algorithm to render sprites up to 17 pixels wide.
The original Tetris playfield is 10&times;20 squares, a 1:2 ratio. The program maintains that ratio by using a playfield of 21&times;42 squares.
Since J, T and L Tetriminos are used interchangeably to produce the emitted square and 3 squares of those Tetriminos contribute to the row above it, there are 21 &#8722; 3 + 1 = 19 single square emitting patterns. However, due to mirror symmetry, there are really only 10 patterns. Clearing 3 rows works for the majority of them. But, an exhaustive computer search revealed that 2 of the patterns require more. The next possible option is 7 rows since 21 &times; 7 + 1 = 148, requiring 37 Tetriminos. As the images below show, those patterns do exist.
![](pen7.gif)
![](pen8.gif)
### Platforms
Before a row is constructed, the algorithm inspects the row below it. If the row below fails to provide support for all of the squares to be deposited above it, then a temporary platform is required. When that platform is removed, the new row will drop, leaving some of the squares apparently floating above empty space due to the way that gravity works in the original Tetris.
The illustration below depicts the 10 platform patterns (really only 5 considering mirror symmetry). The construction of a platform begins by dropping a T Tetrimino on top one of the squares of the last generated row. The remaining Tetriminos support each other down to that first T. Meaning, as long as the previously generated row contains at least 1 square, like the red square below, then it is possible to construct a flat platform above it for the generation of the next row.
![](platform2.gif)
In the middle of platform construction, the bottom row gets completed and cleared, leaving 3 rows above it. The final J or L Tetrimino that will remove those rows is not inserted until the square emitters are done generating the next row of the sprite on top of the platform. That final piece precludes square emission in the first and last 2 columns. But, as discussed above, the square emitters are limited to the 17 inner columns due to the geometry of the J, T and L Tetriminos used in the process.
Also, of the 19 possible ways to start constructing a platform on top of a T Tetrimino, only the 10 patterns shown above exist.
### Program Input
The input sprite is represented textually. Digit characters `0` to `7` correspond to pixels with colors from the palette below.
![ANSI color palette](palette.png)
As discussed above, sprites are limited to a maximum of 3 colors from this palette.
All other characters are interpreted as transparent pixels.
The maximum permissible size of the input text is 32 rows by 17 columns. Row length can vary as long as no single row exceeds 17 characters.
Every row must contain at least one palette digit character.
The `examples` directory contains several sprites in this textual format that can be fed into standard input. Several examples take advantage of the Tetris playfield background color. Instead of using character `0`, internal regions marked as transparent are effectively rendered as black.
###Program Output
The program conceptually uses Tetris as an output device similar to a line printer. It restricts itself to those operations that can be performed on the Tetris playfield: spawning, rotating, positioning and dropping Tetriminos. This process is visually represented using ANSI escape sequences.
### ANSImation
The rate at which the program plays Tetris is completely determined by the rate in which the terminal application receives and displays the ANSI escape sequences.
To slowdown the output programmatically, introduce a delay immediately after the call to `fflush`.
### IOCCC Size Tool Bug
This program demonstrates how to exploit a bug in IOCCC size tool version 2013-07-30-v17. The first line of the program is reproduced below.
char*_ = "'""/*";
If that line is added to the top of any program, the tool will report a size of 8.
./iocccsize -i < prog.c
8
When that line is deleted from this program, the tool properly reports the secondary size limit of the program as 2048.
./iocccsize -i < prog.c
2048
Although this bug provides an easy means of circumventing contest rule 2, as demonstrated from the size value, this entry is not necessarily striving for a 'worst abuse of the rules' award.
###Obfuscations
This program is almost, but not quite, entirely unlike a demonstration of good programming practices. Contrary to other programs, an inspection of this one will certainly reveal that it possesses tea, not to mention an affinity for the constant 42.
Variables are named and ordered to spell out, "Tetris", "ELORG", "DVK" and the aforementioned "Tea". ELORG is the abbreviation for Elektronorgtechnica, the former Soviet state owned computer organization that handled the worldwide Tetris intellectual property rights. DVK is the line of Soviet PDP-11-compatible personal computers capable of running Alexey Pajitnov's original 1984 Tetris prototype.
Carefully selected variable names also yielded wonderful expressions like `l=0`, `O=0`, `O=1` and `while(O)`. "Tetris" also makes a second appearance of sorts:
[T][e][t]--; while(R+i) { s
The source is formatted to resemble the Tetris playfield midgame. It is also an homage to all the past IOCCC entries formatted as a compact block of text; the T, orientated appropriately to reflect its name and the first letter in the title of the game, is just a moment away from producing such a text block.
Three tables are encoded as separate strings within the program:
The first string stores the coordinates of the squares of the 19 distinct rotations of Tetriminos (see below). Since a Tetrimino is a chain of 4 squares, all Tetriminos fit within a 4&times;4 matrix. To determine the coordinates of the squares, the Tetrimino is pushed to the upper-left of the matrix. Each coordinate value requires 2 bits of storage. Consequentially, the four x-coordinates and the four y-coordinates were packed into separate octets. To convert the octets into valid ASCII characters, the squares were sorted such that the least significant bits stored the largest coordinate values. The results were offset by 35, the `#` character, which is 1 beyond the ASCII value of `"`, making it easier to pack into a string. None of the resultant values are beyond ASCII 127. The coordinates for all 19 rotations fit in a string of length 38.
![](rotations.png)
The second string stores the single square emitter patterns and the platform patterns. Each pattern is a sequence of pairs, { Tetrimino index, drop x-coordinate }. As mentioned, there are 19 distinct rotations, requiring 5 bits of storage for the Tetrimino index. Another 5 bits is required for the drop x-coordinate since there are 21 columns in the playfield. Necessarily, the pair is stored as 2 separate characters. By offsetting them by 40, the `(` character, the resultant string almost resembles a long and complex mathematical expression. The program takes advantage of mirror symmetry by only storing 10 single square emitter patterns and 5 platform patterns. The pattern lengths are not encoded within the string. Rather, they are embedded within the string decoding logic.
The third string conceptually stores the default colors of the 19 rotations. A 3-bit value is assigned to each, covering the 7 possible colors. In addition, when a mirrored pattern is executed, J exchanges with L and S exchanges with Z, necessitating a second list of 3-bit color values. Pairs of color values (6 bits) fit comfortably into a character that is offset by `#`. The result is a string of length 19.
The program is full of subtle obfuscations:
* The unary decrement operator is used in conjunction with global variable automatic zero initialization to set variables to `-1`.
* The boolean expression of the form, `x + 1`, is used multiple times to determine if a value is not `-1`. Similarly, expressions of the form `x - y` are used to determine if `x != y`.
* Several arrays store unrelated data in segments throughout the array to reduce named variables.
* The `x["..."]` trick appears once.
* Variable `i` is less than necessary.
* A cursorily glance at the expressions `4&&L` and `m&&e==m` suggests that they always evaluate to true.
* The varying single square emitter pattern lengths are resolved during string decoding using the clever expression, `(i & 3) - 3`, which identifies pattern 3 and 7 as longer.
* The file size of `prog.c` is a prime number. Deleting the first line also produces a prime-sized program. These properties do not qualify the program as a prime number generator.
### Beyond Obfuscation
Due to the contest code size constraint, some optimizations reluctantly had to be omitted. For example, multi-square emitters are possible:
![](multi2.gif)
![](multi3.gif)
![](multi4.gif)
![](multi5.gif)
In fact, using dynamic programming and creative heuristics, real-time search is possible, enabling patterns like this:
![](triple0.gif)
And, even this:
![](triple1.gif)
In addition, it is possible to extend the algorithm to 6 colors instead of just 3. This is achieved using I, S and Z to produce the protruding square. A series of rectangular regions are constructed above those Tetriminos to erode them down to a single emitted square.
The details of these enhancements are left as an exercise to the reader.
### Example Files
The following example files were created by the program author. They can be freely used and distributed.
* `format.txt` - The layout of the program
* `helloworld.txt` - Hello World, Tetris-style
* `hilbert.txt` - A graphic based on the Hilbert curve
* `ioccc.txt` - IOCCC
* `landon.txt` - Portrait of a man with glasses
* `leo.txt` - Portrait of a man without glasses
* `rhino.txt` - A purple rhinoceros
* `simon.txt` - Portrait of a man without hair
The following files are based on graphics from non-free, copyrighted video games. The use of a limited number of textual representations of the graphics for the demonstration of this program qualifies as fair use as such files do not significantly impede the right of the copyright holder to sell the copyrighted material and it is not being used to generate profit in this context. The origin of each file is detailed below (character, game, company, year).
* `belmont.txt` - Simon Belmont, Castlevania, Konami, 1986
* `bloober.txt` - Bloober, Super Mario Brothers, Nintendo, 1985
* `bomberman.txt` - Bomberman, Bomberman, Hudson, 1983
* `boo.txt` - Boo, Super Mario Brothers 3, Nintendo, 1988
* `bub.txt` - Bub, Bubble Bobble, Taito, 1986
* `cheepcheep.txt` - Cheep Cheep, Super Mario Brothers, Nintendo, 1985
* `gurin.txt` - Gurin, Binary Land, Hudson, 1983
* `koopaparatroopa.txt` - Koopa Paratroopa, Super Mario Brothers, Nintendo, 1985
* `lakitu.txt` - Lakitu, Super Mario Brothers, Nintendo, 1985
* `mario.txt` - Fire Mario, Super Mario Brothers, Nintendo, 1985
* `mspacman.txt` - Ms. Pac-Man and Ghost, Ms. Pac-Man, Midway, 1982
* `paranaplant.txt` - Piranha Plant, Super Mario Brothers, Nintendo, 1985
* `samus.txt` - Samus Aran, Metroid, Nintendo/Intelligent Systems, 1986
* `toad.txt` - Toad, Super Mario Brothers 2, Nintendo, 1987
The origin of the remaining files are described below:
* `happyface.txt` - Based on a smiley; rights unknown
* `snoo.txt` - 8-bit version of Snoo, Reddit's alien mascot
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

+202
View File
@@ -0,0 +1,202 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall -W -Wno-implicit-int -Wno-implicit-function-declaration
#CWARN= -Wall -W -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT} ${LIBS}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= cable1
DATA=
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} ${DATA}
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
+1
View File
@@ -0,0 +1 @@
main(int riguing,char**acters){puts(1[acters-~!(*(int*)1[acters]%4796%275%riguing)]);}
+129
View File
@@ -0,0 +1,129 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Most partisan 1-liner</title>
</head>
<body>
<h1>Most partisan 1-liner</h1>
<p>Adrian Cable<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#114;&#x69;&#97;&#x6e;&#x2e;&#99;&#97;&#98;&#x6c;&#101;&#x40;&#x67;&#x6d;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#x6d;">&#97;&#x64;&#114;&#105;&#x61;&#110;&#46;&#99;&#x61;&#98;&#x6c;&#x65;&#x40;&#x67;&#109;&#97;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make cable1
</code></pre>
<h3>To run:</h3>
<pre><code>./cable1 name group1 group2
</code></pre>
<h3>Try:</h3>
<pre><code>./cable1 obama republican democrat
./cable1 nixon republican democrat
./cable1 bush republican democrat
./cable1 kennedy republican democrat
./cable1 lincoln republican democrat
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Partisan may be defined as a strong supporter of a cause, party or person.
We need not limit ourselves to the two major political parties in the US today.</p>
<p>Let us consider:</p>
<pre><code>./cable1 Cooper Mac PC
</code></pre>
<p>Simon works for Apple, so would would expect Mac. :-)
Landon is a long time Mac user:</p>
<pre><code>./cable1 Noll Mac PC
</code></pre>
<p>That works too!. Now Leo brings PCs to the IOCCC judging for cross-platform
testing:</p>
<pre><code>./cable1 Broukhis Mac PC
</code></pre>
<p>We can test other people. The late Steve Jobs:</p>
<pre><code>./cable1 Jobs Mac PC
</code></pre>
<p>That works! How about Bill?</p>
<pre><code>./cable1 Gates Mac PC
</code></pre>
<p>A PC guy as expected. What about that other Steve?</p>
<pre><code>./cable1 Ballmer Mac PC
</code></pre>
<p>Humm .. maybe there is a hidden reason he is leaving the late Micro$oft? :-)
Why late? See <a href="https://twitter.com/landonnoll/status/401582967123742720">this tweet</a>.</p>
<p>So how does a one line C source know so much? Hint: it doesn&rsquo;t.</p>
<h2>Author&rsquo;s comments:</h2>
<h1>Presidents of the United States of America!</h1>
<p>Politics is full of memorable one-liners. Without wishing to misunderestimate the taste of the judges, nor prejudge the past, the author hopes you enjoy this contribution to the genre.</p>
<p>This one-line C program accepts as a first command-line argument the last name of any of the last 31 US Presidents (from Franklin Pierce onwards), in lower case, and prints out their political affiliation.</p>
<p>Use &ldquo;republican&rdquo; as the 2nd command-line argument, and &ldquo;democrat&rdquo; as the 3rd (or equivalent strings of your choice).</p>
<h2>Why is this entry obfuscated/interesting?</h2>
<ul>
<li>The program looks up the name supplied on the command line against a list of Presidents' names, and matches names to political affiliations using a look-up table. But where in the source is the list of names, and where is the look-up table?</li>
</ul>
<h2>Notes</h2>
<ul>
<li>For Theodore Roosevelt, use: ./cable1 roosevelt republican democrat</li>
<li>But, for Franklin D Roosevelt, use: ./cable1 fdr republican democrat</li>
<li>This program needs a little endian CPU to work properly.</li>
</ul>
<h2>Compiler warnings</h2>
<p>clang warns about a missing type specifier for main, and that implicit function declarations are invalid in C99 (but still accepts them).</p>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+94
View File
@@ -0,0 +1,94 @@
# Most partisan 1-liner
Adrian Cable
<adrian.cable@gmail.com>
## Judges' comments:
### To build:
make cable1
### To run:
./cable1 name group1 group2
### Try:
./cable1 obama republican democrat
./cable1 nixon republican democrat
./cable1 bush republican democrat
./cable1 kennedy republican democrat
./cable1 lincoln republican democrat
### Selected Judges Remarks:
Partisan may be defined as a strong supporter of a cause, party or person.
We need not limit ourselves to the two major political parties in the US today.
Let us consider:
./cable1 Cooper Mac PC
Simon works for Apple, so would would expect Mac. :-)
Landon is a long time Mac user:
./cable1 Noll Mac PC
That works too!. Now Leo brings PCs to the IOCCC judging for cross-platform
testing:
./cable1 Broukhis Mac PC
We can test other people. The late Steve Jobs:
./cable1 Jobs Mac PC
That works! How about Bill?
./cable1 Gates Mac PC
A PC guy as expected. What about that other Steve?
./cable1 Ballmer Mac PC
Humm .. maybe there is a hidden reason he is leaving the late Micro$oft? :-)
Why late? See [this tweet](https://twitter.com/landonnoll/status/401582967123742720).
So how does a one line C source know so much? Hint: it doesn't.
## Author's comments:
Presidents of the United States of America!
===========================================
Politics is full of memorable one-liners. Without wishing to misunderestimate the taste of the judges, nor prejudge the past, the author hopes you enjoy this contribution to the genre.
This one-line C program accepts as a first command-line argument the last name of any of the last 31 US Presidents (from Franklin Pierce onwards), in lower case, and prints out their political affiliation.
Use "republican" as the 2nd command-line argument, and "democrat" as the 3rd (or equivalent strings of your choice).
Why is this entry obfuscated/interesting?
-----------------------------------------
- The program looks up the name supplied on the command line against a list of Presidents' names, and matches names to political affiliations using a look-up table. But where in the source is the list of names, and where is the look-up table?
Notes
-----
- For Theodore Roosevelt, use: ./cable1 roosevelt republican democrat
- But, for Franklin D Roosevelt, use: ./cable1 fdr republican democrat
- This program needs a little endian CPU to work properly.
Compiler warnings
-----------------
clang warns about a missing type specifier for main, and that implicit function declarations are invalid in C99 (but still accepts them).
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+208
View File
@@ -0,0 +1,208 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall -Wno-bitwise-op-parentheses -Wno-unsequenced \
-Wno-incompatible-pointer-types -Wno-shift-op-parentheses \
-Wno-empty-body -Wno-parentheses -Wno-int-conversion \
-Wno-implicit-int
#CWARN= -Wall -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= cable2
DATA= example-images.tbz2
BUILT_DATA= ascii.bmp bonus.bmp hello_world.bmp mixed_sizes.bmp multi_color.bmp typeset.bmp
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} data
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@echo extracting sample bmp files
${TAR} -jxvf ${DATA}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
${RM} -f ${BUILT_DATA}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
+77
View File
@@ -0,0 +1,77 @@
#include\
<stdio.h>//
#define Y(\
_)_##char
#define \
_ [9<<9],
#define j\
L;fread(&\
L,4,1,f);u
#define P\
&4**(int*\
)" ")% \
3901%31///
#define q\
Z[F++]=*E
#define $\
for("IOCCC"
#include\
<stdlib.h>
int *Q,u,i,c,k,B,r=0,w,n,F=0,x,J,u,m,p,s=0,v,e,r,L,a,z,y,D,o,g; Y( )*
Z= "Vn"
"-S" "xR9Q" "[$s"
"Zd&o+" "pf^cM" "cbac\
J_VHMF_" "BkaEg^" "x`i_i\
us%d]oWG:" "r`IZ.6_]H3ec]_\
bWW_^Ej2i[r" "ZZnJjW[bK`hZakb\
_l]gL3X]d_#$eK" "[G3 d[Xe][:V`4Z]Z" "VfX^]V:X%b]N,ma-j"
"^m57c!`O.qP8lTc^" "gm,Um;m`m^^`5n_nci<Wf[h<t+e$%" "]Lha&=l Umc>m#_mdp"
"h/codZ#i`,''mbb(fh" ")h)(^uV9b7dcZq`^d`/*3`#ko`lj;^idad/]0ffxP*]??bff$h`@(Zgtcn"
"k10t<A6mYZNh!g&a2^j" "!^hOZb!&]bd(]TuqI]#iepZc/XdX(Z X4a!dgpc>0q;]^7p`q*AtqC1j,'#_on tp"
"on e !1+tA6`db`qciq`'=?ui]'`_`dk`!kx_%]bu]cZX8u_)Z=8@ghg$mlp`a>D_o2_eb)sb)sa0g@f-h"
"1bl_DeblFsa&Dt^t4*X *mCC^5Y",M _ A _ G _ I _ C _ K[]="',b}q}a9\"],)'(cDDJr4"
"Ab,:sdtd/E*#2eXkZ7cPthkq`(stnhct!a:>A;A+jA9>A;A+js",*E=I;FILE*f;main
(int d,Y()**t){$;!t;s=c=-D){$,t=v=D?k:J;v++-d;){$,o=L=z=0,s=D?J:k;s+++d
-B-F;)(o&&(e=m),y=*Q!=(m=Q[u*i+(D?v-u*s:s-u*v)]))^o&&(G[z++]=s-L>20,L=s,o=y);$,
s=z,o=0;s--;o+=G[s]^s[A]);$;z^w||o;z=w){$,o=1;o&&!--o*D-~-~-w|1[A]|v-a>28&&w^4|1[A]|
3[A]|!2[A ]|v-a>5;)$;I[g[I]=2,++g]=-1,-s<w;I[~-g]=A[-s--]);$,a=v,w=z;z--;A[z]=z[G]);
}}$,v=a =o;(Z=C+!D*734)[z=a] ^3;d=0){$;!~I[v];a=z,v=o=0)$,M[L
++]+= Z[z]^4?-42:o; Z[z++]^4;); $;~z&&2>(s=I
[v ])&4<Z[z] |Z[z]==s ;)++z,s^2?
d++,++ v:v&&(o +=d,a=z,
z=-1 );$;v++[ I]^2;) ;}}$;d
;d =c){$,p=*Z;F++ [I]= *++
Z%p,*Z;);$,Z=C;x=F ,F=
r,s=2,p---7;Q=E,E=Z
,Z=Q)$;s%x;p^(c=s++[E
])?q*0+c:(q++, q--));$;K[F];K[F++]-=p
);c=fseek((f=fopen(*++t,"rb"))?f:(exit(1)
,f),10,r);j;n=j=j=j;i=j;F=a=fseek(f,n,c);
Q=calloc(z=i--*u,4);$;a^z;fread(a+++Q,L>>
19,1,f));$;F++<i;r=n){$,n=0,B=u;B;n|=*Q^Q
[u*(i-F)+--B]);$,n&&Y(!r&&(D=F-J,J=F);
!n&&r;r=x=!put)(10))$;B^u;B++,c=p){$,p=
0,s=J;s^F;p|=*Q^Q[B+u*(i-s++)]);$;p&&!c;
)$;++Y (c*F-J<<1<5*((k=B)-x);put)(32
),++c); $;!p&&c;x=B){$,F-J<<1<Y(D&&
put)( 10),D=95;D--;D[M]=0);$;main(
++D?B: F,w=a=g=0),!D;);$;x=K[o++]-
27;M [x]*M[K[o++] -27]>0&&(M
[x]=s));$; ++c^L;M[c]
>s&&(s=M[ x=c]));$;
3^d||printf (K+--o,(
*Q P,(e P), D*!(c+~x);
w++)$,o= '~';-~o;)$
[w]Y(^-- o||put)(D=
o);0;);c =Y(~o&&!
put)(*K+ x);}}}}}
Binary file not shown.
+153
View File
@@ -0,0 +1,153 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Best of show</title>
</head>
<body>
<h1>Best of show</h1>
<p>Adrian Cable<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#114;&#x69;&#97;&#x6e;&#x2e;&#99;&#97;&#98;&#x6c;&#101;&#x40;&#x67;&#x6d;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#x6d;">&#97;&#x64;&#114;&#105;&#x61;&#110;&#46;&#99;&#x61;&#98;&#x6c;&#x65;&#x40;&#x67;&#109;&#97;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make cable2
</code></pre>
<h3>To run:</h3>
<pre><code>./cable2 file.bmp [color]
</code></pre>
<h3>Try:</h3>
<p>Extract example-images.tbz2:</p>
<pre><code>make data
</code></pre>
<p>Here is an OCR example that shows all 94 supported ASCII characters:</p>
<pre><code>./cable2 ascii.bmp
</code></pre>
<p>Here is an example of colored ASCII:</p>
<pre><code>./cable2 multi_color.bmp color
</code></pre>
<p>Here is an example using different character sizes and different
positions in the same file:</p>
<pre><code>./cable2 mixed_sizes.bmp
</code></pre>
<p>How about about hand-written C code:</p>
<pre><code>./cable2 hello_world.bmp | gcc -xc -o hello -
./hello
</code></pre>
<p>Sometimes typeset text will work, if the typeset has characters that
are enough to the supported handwritten shapes. For example,
Menlo, 160 pt:</p>
<pre><code>./cable2 typeset.bmp
</code></pre>
<p>And as an added IOCCC bonus: :-)</p>
<pre><code>./cable2 bonus.bmp
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>We can confirm that this is the first time the IOCCC has been used
to peer-review a new research. We had quite a bit of fun with a sharpie and a
scanner.</p>
<h2>Author&rsquo;s comments:</h2>
<h1>OCR - Obfuscated Character Recognition of Handwritten Text</h1>
<p>This entry takes a BMP image file of hand-drawn (mouse-drawn?) text, specified as the first command-line parameter, and converts it to an ASCII text document. Magic!</p>
<p>BMP files created by most paint programs should work. The author recommends Paint.NET.</p>
<h2>Features</h2>
<ul>
<li>Every printable ASCII character is recognized (94 characters plus space), plus a special bonus character.</li>
<li>Input images can be any size (limited only by memory), containing any number of lines of text.</li>
<li>BMP is really a mess of different formats, but the program supports most of them from Windows 3.1 and later.</li>
<li>Hand-drawn characters in the input image can be variably spaced and positioned and be of any width or height, but the bigger the better for accurate recognition (300 pixels tall or more is recommended). Characters must be drawn with a stroke width of around 9 pixels, and separated from adjacent characters. (In Paint.NET a brush of width 9 works well, with anti-aliasing turned off.)</li>
<li>You can use any colors you like for the text and background, even different colors for different text characters.</li>
<li>If &ldquo;color&rdquo; is specified as the second command line parameter, the program&rsquo;s output will also be in color, on ANSI/VTxxx terminals.</li>
</ul>
<h2>Why is this entry obfuscated/interesting?</h2>
<ul>
<li>The source is presented as a beautiful moonlit scene, in which a quick brown fox jumps over a lazy dog. Far too often in software development is aesthetic nuance lost in the name of serious-sounding conventions like &ldquo;GNU style&rdquo;, but not here.</li>
<li>Newcomers to C find it hard to learn all those different ways to control flow: for, while, if, do, goto, continue, break and heaven knows what else! So, in this program we only use for, so absolute beginners can get into the code straight away.</li>
<li>To teach newcomers all the important features of C, we demonstrate the importance of the liberal use of short circuits, sequence points, the ternary operator, using x<sup>y</sup> or x-y instead of x!=y, using ~x in place of x!=-1 for conciseness, mixing x[y] and y[x] for variety, educational #define&rsquo;s, and so on.</li>
<li>main is the most useful function in all of C - so it is a mystery to the author why most programs use it only once. Here we use it over and over for maximum benefit.</li>
<li>The number 42 is featured in the source to provide an answer to the judges' deeper questions.</li>
<li>How are character colors converted from RGB in the input image to ANSI escape sequences? Clue: the weird macro P does the interesting part of it, but how?</li>
<li>The program prints a string when the bonus character is detected. How does it do this? Clue: the string to print is defined in the macro $, but how can a string defined in that way ever get printed?</li>
</ul>
<h2>Other notes</h2>
<ul>
<li>The novel character recognition algorithm used has not been previously published and was developed by the author specifically for the contest. Should this entry win the IOCCC, it will be the first time (to the author&rsquo;s knowledge) that the IOCCC has been used for peer review/publication of original research.</li>
<li>OCR in general is a hard problem. Here, we only recognise one possible form for each character. You can see what the supported character shapes look like by looking at the examples in ascii.bmp. If you copy the shape of the character forms you find in there, recognition accuracy should be very good (95%+). A more &ldquo;useful&rdquo; version would extend the character stroke table to support multiple different commonly-used forms for each character.</li>
<li>Despite being the largest possible IOCCC entry at 4096 bytes, it is also probably the smallest general-purpose OCR program ever written (including the character stroke data), maybe by several orders of magnitude.</li>
<li>The author used an interesting compression algorithm (suggested by Gareth McCaughan - thank you!) to squeeze the character stroke table (containing around 2000 strokes for the whole ASCII character set) into a string constant of just 472 characters.</li>
</ul>
<h2>Bugs/features</h2>
<ul>
<li>The width of input images must be a multiple of 4.</li>
<li>Input images can be 8-bit grayscale, 24-bit color or 32-bit color only. 8-bit color and 16-bit color are not supported. If you use the &ldquo;color&rdquo; command-line feature, do not use a grayscale input file!</li>
<li>Normal Windows BMP files are stored &ldquo;upside-down&rdquo;, i.e. the bottom line in the image is written first. Some (old) graphics programs actually write BMP files &ldquo;top-to-bottom&rdquo; and the program does not support such files.</li>
<li>Using antialiased brush strokes to draw your letters is fine, however, antialiasing interferes with color detection in &ldquo;color&rdquo; mode.</li>
<li>Only runs on little endian machines (since the BMP format is little endian, and endianness conversion would make the source too large for IOCCC rule 2).</li>
</ul>
<h2>Compiler warnings</h2>
<p>clang warns about unused expression results, missing type specifiers, and incompatible pointer conversions - all just a fun consequence of the obfuscations.</p>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+114
View File
@@ -0,0 +1,114 @@
# Best of show
Adrian Cable
<adrian.cable@gmail.com>
## Judges' comments:
### To build:
make cable2
### To run:
./cable2 file.bmp [color]
### Try:
Extract example-images.tbz2:
make data
Here is an OCR example that shows all 94 supported ASCII characters:
./cable2 ascii.bmp
Here is an example of colored ASCII:
./cable2 multi_color.bmp color
Here is an example using different character sizes and different
positions in the same file:
./cable2 mixed_sizes.bmp
How about about hand-written C code:
./cable2 hello_world.bmp | gcc -xc -o hello -
./hello
Sometimes typeset text will work, if the typeset has characters that
are enough to the supported handwritten shapes. For example,
Menlo, 160 pt:
./cable2 typeset.bmp
And as an added IOCCC bonus: :-)
./cable2 bonus.bmp
### Selected Judges Remarks:
We can confirm that this is the first time the IOCCC has been used
to peer-review a new research. We had quite a bit of fun with a sharpie and a
scanner.
## Author's comments:
OCR - Obfuscated Character Recognition of Handwritten Text
==========================================================
This entry takes a BMP image file of hand-drawn (mouse-drawn?) text, specified as the first command-line parameter, and converts it to an ASCII text document. Magic!
BMP files created by most paint programs should work. The author recommends Paint.NET.
Features
--------
- Every printable ASCII character is recognized (94 characters plus space), plus a special bonus character.
- Input images can be any size (limited only by memory), containing any number of lines of text.
- BMP is really a mess of different formats, but the program supports most of them from Windows 3.1 and later.
- Hand-drawn characters in the input image can be variably spaced and positioned and be of any width or height, but the bigger the better for accurate recognition (300 pixels tall or more is recommended). Characters must be drawn with a stroke width of around 9 pixels, and separated from adjacent characters. (In Paint.NET a brush of width 9 works well, with anti-aliasing turned off.)
- You can use any colors you like for the text and background, even different colors for different text characters.
- If "color" is specified as the second command line parameter, the program's output will also be in color, on ANSI/VTxxx terminals.
Why is this entry obfuscated/interesting?
-----------------------------------------
- The source is presented as a beautiful moonlit scene, in which a quick brown fox jumps over a lazy dog. Far too often in software development is aesthetic nuance lost in the name of serious-sounding conventions like "GNU style", but not here.
- Newcomers to C find it hard to learn all those different ways to control flow: for, while, if, do, goto, continue, break and heaven knows what else! So, in this program we only use for, so absolute beginners can get into the code straight away.
- To teach newcomers all the important features of C, we demonstrate the importance of the liberal use of short circuits, sequence points, the ternary operator, using x^y or x-y instead of x!=y, using ~x in place of x!=-1 for conciseness, mixing x[y] and y[x] for variety, educational #define's, and so on.
- main is the most useful function in all of C - so it is a mystery to the author why most programs use it only once. Here we use it over and over for maximum benefit.
- The number 42 is featured in the source to provide an answer to the judges' deeper questions.
- How are character colors converted from RGB in the input image to ANSI escape sequences? Clue: the weird macro P does the interesting part of it, but how?
- The program prints a string when the bonus character is detected. How does it do this? Clue: the string to print is defined in the macro $, but how can a string defined in that way ever get printed?
Other notes
-----------
- The novel character recognition algorithm used has not been previously published and was developed by the author specifically for the contest. Should this entry win the IOCCC, it will be the first time (to the author's knowledge) that the IOCCC has been used for peer review/publication of original research.
- OCR in general is a hard problem. Here, we only recognise one possible form for each character. You can see what the supported character shapes look like by looking at the examples in ascii.bmp. If you copy the shape of the character forms you find in there, recognition accuracy should be very good (95%+). A more "useful" version would extend the character stroke table to support multiple different commonly-used forms for each character.
- Despite being the largest possible IOCCC entry at 4096 bytes, it is also probably the smallest general-purpose OCR program ever written (including the character stroke data), maybe by several orders of magnitude.
- The author used an interesting compression algorithm (suggested by Gareth McCaughan - thank you!) to squeeze the character stroke table (containing around 2000 strokes for the whole ASCII character set) into a string constant of just 472 characters.
Bugs/features
-------------
- The width of input images must be a multiple of 4.
- Input images can be 8-bit grayscale, 24-bit color or 32-bit color only. 8-bit color and 16-bit color are not supported. If you use the "color" command-line feature, do not use a grayscale input file!
- Normal Windows BMP files are stored "upside-down", i.e. the bottom line in the image is written first. Some (old) graphics programs actually write BMP files "top-to-bottom" and the program does not support such files.
- Using antialiased brush strokes to draw your letters is fine, however, antialiasing interferes with color detection in "color" mode.
- Only runs on little endian machines (since the BMP format is little endian, and endianness conversion would make the source too large for IOCCC rule 2).
Compiler warnings
-----------------
clang warns about unused expression results, missing type specifiers, and incompatible pointer conversions - all just a fun consequence of the obfuscations.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+208
View File
@@ -0,0 +1,208 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall -Wno-implicit-int -Wno-implicit-function-declaration \
-Wno-return-type -Wno-unsequenced -Wno-shift-op-parentheses \
-Wno-conditional-type-mismatch -Wno-parentheses \
-Wno-incompatible-pointer-types
#CWARN= -Wall -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3 -fsigned-char
# Libraries needed to build
#
LIBS=`sdl-config --cflags --libs`
# Defines
DEFS=-DKB='(kb=read(H(8),r+1190,1))&&H(7)'
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT} ${DEFS}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= cable3
DATA=
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} ${DATA}
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
BIN
View File
Binary file not shown.
+28
View File
@@ -0,0 +1,28 @@
#include "SDL.h"
#define $ for(O=9
#define CX M+=(T%3+2*!(!T*t-6))
#define x ,A=4*!T,O=t,W=h=T<3?u(Q?p:D(A+3),D(A),D(A+1)[i]+D(A+2)*g+):K(t),U=V=K(a),o?U=h,W=V:V,
#define C 8*-~L
#define Z short
#define y a(Z)Y[++O]
#define B ),a--||(
#define _ ),e--||(
#define V(I,D,E)(O=a(I)h[r])&&!(A=(D)(V=(1[E+L]<<16)+*i)/O,A-(I)A)?1[E+L]=V-O*(*E=A):H(0)
#define i(B,M)B(o){return M;}
#define R(O,M,_)(S=L?a(I Z)O:O,N=L?a(I Z)O M(f=a(I Z)_):(O M(f=a(I n)_)))
#define T(_)R(r[u(10,L=4,--)],=,_)
#define u(a,r,T)16*i[a]+(I Z)(T i[r])
#define a(_)*(_*)&
#define L(_)M(W,_,U)
#define M(S,F,T)R(r[S],F,r[T])
#define A(_)(i[L=4]+=2,R(_,=,r[u(10,4,-2+)]))
#define c(R,T)(1[u=19,L+T]=(N=a(R)h[r]*(R)*T)>>16,*i=N,G(F(N-(R)N)))
#define h(_)(1&(L?a(Z)_:_)>>C-1)
#define I unsigned
#define n char
#define e(_)v(F(40[L(_##=40[E]+),E]&N==S|_ N<_(int)S))
I n t,e,l[80186],*E,m,u,L,a,T,o,r[1<<21],X,*Y,b,Q,R;I Z*i,M,p,q=3;I*localtime(),f,S,kb,h,W,U,c,g,d,V,A;N,O,P=983040,j[5];SDL_Surface*k;i(F,40[E]=!!o)i(z,42[E]=!!o)i(D,r[a(I)E[259+4*o]+O])i(w,i[o]+=~(-2*47[E])*~L)i(v,G(N-S&&1&(40[z((f^=S^N)&16),E]^f>>C-1)))J(){V=61442;$;O--;)V+=40[E+O]<<D(25);}i(H,(46[u=76,J(),T(V),T(9[i]),T(M),M(P+18,=,4*o+2),R(M,=,r[4*o]),E]=0))s(o){$;O--;)40[E+O]=1&&1<<D(25)&o;}i(BP,(*i+=262*o*z(F((*E&15)>9|42[E])),*E&=15))i(SP,(w(7),R&&--1[i]&&o?R++,Q&&Q++,M--:0))DX(){$,O*=27840;O--;)O[(I*)k->pixels]=-!!(1<<7-O%8&r[O/2880*90+O%720/8+(88+952[l]/128*4+O/720%4<<13)]);SDL_Flip(k);}main(BX,nE)n**nE;{9[i=E=r+P]=P>>4;$;q;)j[--q]=*++nE?open(*nE,32898):0;read(2[a(I)*i=*j?lseek(*j,0,2)>>9:0,j],E+(M=256),P);$;Y=r+16*9[i]+M,Y-r;Q|R||kb&46[E]&&KB)--64[T=1[O=32[L=(X=*Y&7)&1,o=X/2&1,l]=0,t=(c=y)&7,a=c/8&7,Y]>>6,g=~-T?y:(n)y,d=BX=y,l],!T*t-6&&T-2?T-1?d=g:0:(d=y),Q&&Q--,R&&R--x(O=*Y,O=u=D(51),e=D(8),m=D(14)_ O=*Y/2&7,M+=(n)c*(L^(D(m)[E]|D(22)[E]|D(23)[E]^D(24)[E]))_ L=*Y&8,R(K(X)[r],=,c)_ L=e+=3,o=0,a=X x a=m _ T(X[i])_ A(X[i])_ a<2?M(U,+=1-2*a+,P+24),v(f=1),G(S+1-a==1<<C-1),u=u&4?19:57:a-6?CX+2,a-3||T(9[i]),a&2&&T(M),a&1&&M(P+18,=,U+2),R(M,=,U[r]),u=67:T(h[r])_(W=U B u=m,M-=~L,R(W[r],&,d)B 0 B L(=~)B L(=-),S=0,u=22,F(N>S)B L?c(I Z,i):c(I n,E)B/**/L?c(Z,i):c(n,E)B L?V(I Z,I,i):V(I n,I Z,E)B L?V(Z,int,i):V(n,Z,E))_++e,h=P,d=c,T=3,a=m,M--_++e,13[W=h,i]=(o|=!L)?(n)d:d,U=P+26,M-=~!o,u=17+(m=a)_(a=m B L(+=),F(N<S)B L(|=)B e(+)B e(-)B L(&=)B L(-=),F(N>S)B L(^=)B L(-),F(N>S)B L(=))_!L?L=a+=8 x L(=):!o?Q=1,R(r[p=m x V],=,h):A(h[r])_ T=a=0,t=6,g=c x M(U,=,W)_(A=h(h[r]),V=m?++M,(n)g:o?31&2[E]:1)&&(a<4?V%=a/2+C,R(A,=,h[r]):0,a&1?R(h[r],>>=,V):R(h[r],<<=,V),a>3?u=19:0,a<5?0:F(S>>V-1&1)B R(h[r],+=,A>>C-V),G(h(N)^F(N&1))B A&=(1<<V)-1,R(h[r],+=,A<<C-V),G(h(N*2)^F(h(N)))B R(h[r],+=(40[E]<<V-1)+,A>>1+C-V),G(h(N)^F(A&1<<C-V))B R(h[r],+=(40[E]<<C-V)+,A<<1+C-V),F(A&1<<V-1),G(h(N)^h(N*2))B G(h(N)^F(h(S<<V-1)))B G(h(S))B 0 B V<C||F(A),G(0),R(h[r],+=,A*=~((1<<C)-1>>V)))_(V=!!--1[a=X,i]B V&=!m[E]B V&=m[E]B 0 B V=!++1[i]),M+=V*(n)c _ M+=3-o,L?0:o?9[M=0,i]=BX:T(M),M+=o*L?(n)c:c _ M(U,&,W)_ L=e+=8,W=P,U=K(X)_!R||1[i]?M(m<2?u(8,7,):P,=,m&1?P:u(Q?p:11,6,)),m&1||w(6),m&2||SP(1):0 _!R||1[i]?M(m?P:u(Q?p:11,6,),-,u(8,7,)),43[u=92,E]=!N,F(N>S),m||w(6),SP(!N==b):0 _ o=L,A(M),m&&A(9[i]),m&2?s(A(V)):o||(4[i]+=c)_ R(U[r],=,d)_ 986[l]^=9,R(*E,=,l[m?2[i]:(n)c])_ R(l[m?2[i]:(n)c],=,*E)_ R=2,b=L,Q&&Q++_ W-U?L(^=),M(U,^=,W),L(^=):0 _ T(m[i])_ A(m[i])_ Q=2,p=m,R&&R++_ L=0,O=*E,F(D(m+=3*42[E]+6*40[E])),z(D(1+m)),N=*E=D(m-1)_ N=BP(m-1)_ 1[E]=-h(*E)_ 2[i]=-h(*i)_ 9[T(9[i]),T(M+5),i]=BX,M=c _ J(),T(V)_ s(A(V))_ J(),s((V&~m)+1[E])_ J(),1[E]=V _ L=o=1 x L(=),M(P+m,=,h+2)_++M,H(3)_ M+=2,H(c&m)_++M,m[E]&&H(4)_(c&=m)?1[E]=*E/c,N=*E%=c:H(0)_*i=N=m&E[L=0]+c*1[E]_*E=-m[E]_*E=r[u(Q?p:m,3,*E+)]_ m[E]^=1 _ E[m/2]=m&1 _ R(*E,&,c)_(a=c B write(1,E,1)B time(j+3),memcpy(r+u(8,3,),localtime(j+3),m)),a<2?*E=~lseek(O=4[E][j],a(I)5[i]<<9,0)?((I(*)())(a?write:read))(O,r+u(8,3,),*i):0:0),O=u,D(16)?v(0):D(17)&&G(F(0)),CX*D(20)+D(18)-D(19)*~!!L,D(15)?O=m=N,41[43[44[E]=h(N),E]=!N,E]=D(50):0,!++q?kb=1,*l?SDL_PumpEvents(),k=k?k:SDL_SetVideoMode(720,348,32,0),DX():k?SDL_Quit(),k=0:0:0;}i(G,48[E]=o)i(K,P+(L?2*o:2*o+o/4&7))
Binary file not shown.
+272
View File
@@ -0,0 +1,272 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Largest small system emulator</title>
</head>
<body>
<h1>Largest small system emulator</h1>
<p>Adrian Cable<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#97;&#100;&#114;&#x69;&#97;&#x6e;&#x2e;&#99;&#97;&#98;&#x6c;&#101;&#x40;&#x67;&#x6d;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#x6d;">&#97;&#x64;&#114;&#105;&#x61;&#110;&#46;&#99;&#x61;&#98;&#x6c;&#x65;&#x40;&#x67;&#109;&#97;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make cable3
</code></pre>
<h3>To run:</h3>
<pre><code>./cable3 bios-image-file floppy-image-file [harddisk-image-file]
</code></pre>
<h3>Try:</h3>
<pre><code>./runme
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This entry weighs in at a magical 4043 bytes (8086 nibbles, 28,301
bits). It manages to implement most of the hardware in a 1980&rsquo;s era
IBM-PC using a few hundred fewer bits than the total number of
transistors used to implement the original 8086 CPU.</p>
<p>If you are using OS X, the included sc-ioccc.terminal configuration file will
correctly display console applications that use ANSI graphics.</p>
<p>Update: This entry now has its own web page <a href="http://www.megalith.co.uk/8086tiny">http://www.megalith.co.uk/8086tiny</a></p>
<h2>Author&rsquo;s comments:</h2>
<h1>A tiny but highly functional PC emulator/virtual machine</h1>
<p>The author hereby presents, for the delectation (?) of the judges, a portable PC emulator/VM written specifically for the IOCCC which runs DOS, Windows 3.0, Excel, MS Flight Simulator, AutoCAD, Lotus 1-2-3 &hellip;</p>
<p>In just 4043 bytes of C source, you get a complete mid-late 1980s-era IBM-compatible PC, consisting of:</p>
<ul>
<li>Intel 8086/186 CPU</li>
<li>1MB RAM</li>
<li>8072A 3.5" floppy disk controller (1.44MB/720KB)</li>
<li>Fixed disk controller (supports a single hard drive up to 528MB)</li>
<li>Hercules graphics card with 720x348 2-color graphics (64KB video RAM), and CGA 80x25 16-color text mode support</li>
<li>8253 programmable interval timer (PIT)</li>
<li>8259 programmable interrupt controller (PIC)</li>
<li>8042 keyboard controller with 83-key XT-style keyboard</li>
<li>MC146818 real-time clock</li>
<li>PC speaker</li>
</ul>
<p>The emulator uses the SDL graphics library for portability, and compiles for Windows, Mac OS X, Linux and probably most other 32-bit/64-bit systems too.</p>
<p>If you like living on the edge you can try building the emulator on a big endian machine, and you will get an emulation of a big endian 8086, a rather bizarre and somewhat useless beast. For everyone else, please run the emulator on a little endian machine.</p>
<p><em>RULE 2 ABUSE DISCLAIMER</em></p>
<ul>
<li>cable3.c is 4043 bytes in length (half an 8086)</li>
<li>iocccsize -i &lt; cable3.c returns 1977 (the year the 4.77 MHz 8086 CPU was announced)</li>
<li>Therefore, any suspicions the judges may have regarding rule 2 non-compliance may be well-intentioned but are groundless.</li>
<li>Nonetheless, the author would like to apologise to the judges for the one-big-block-of-code nature of this entry, which turned out to be unavoidable. Hopefully the joys of this entry will make up for its shortcomings.</li>
</ul>
<p><em>/RULE 2 ABUSE DISCLAIMER</em></p>
<h2>Why is this entry obfuscated/interesting?</h2>
<ul>
<li>First of all the 8086 is a nightmare processor to emulate. Instruction codings are complex and irregular in size and structure, with multiple addressing modes and no consistent memory placement for operands, very often multiple possible encodings for the same instruction, and the bizarre segment:offset memory model. In addition, the 8086 has a number of bugs (e.g. PUSH SP), undocumented behaviours and instructions (e.g. AAM/AAD + imm8, SALC, flag behaviour for MUL/DIV, etc. etc.), and archaic features (e.g. parity/auxiliary flags) which all need to be emulated properly. Here we emulate every feature of the CPU pretty exactly (in fact better than most commercial clones of the processor e.g. the NEC V30), with the exception of the trap flag which no real software uses except for debuggers (although support for the TF can be added if deemed important, without exceeding the IOCCC size limit).</li>
<li>In addition to the CPU we also emulate all the standard PC peripheral hardware. Parts of it are somewhat complete, much is rather dysfunctional (like the 8253/8259) but enough to support most real software.</li>
<li>Nonetheless the source, while large for the IOCCC, is rather tiny for a functional PC emulator - around 2% of the size of the source of other open-source 8086 PC emulators with comparable functionality.</li>
<li>In fact, this entry is just like happy hour - at 4043 bytes long, you pay for half the 8086, but you get served the whole one.</li>
<li>Getting the code down to &lt;= 4096 characters to meet the IOCCC rule 2 overall size limit required a good deal of effort (and appreciable risk of divorce), with obfuscation being a pretty unavoidable consequence in most places &hellip; for the rest, I use short circuit operators whenever possible, mix x[y] and y[x], don&rsquo;t use any flow control keywords except for for, use K&amp;R-style declarations to honor the C language&rsquo;s rich cultural heritage (plus it saves a byte), and occasionally go overboard with nasty nested indexes to give things like this: &ndash;64[T=1[O=32[L=(X=*Y&amp;7)&amp;1,o=X/2&amp;1,l]=0,t=(c=y)&amp;7,a=c/8&amp;7,Y]>>6,g=~-T?y:(n)y,d=BX=y,l]</li>
<li>This entry highlights the importance of comments in C.</li>
<li>This entry might result in an adjustment to the IOCCC size tool for the 2014 competition (see above).</li>
</ul>
<h2>Compiling on different platforms</h2>
<p>This entry has been tested on Windows (compiled with MS Visual Studio 2010 and 2013), Mac OS X (clang and gcc), and Linux (clang and gcc). The Makefile supplied is good for Mac OS X, Linux and probably other UNIXes. I have received reports that the emulator works on Raspberry Pi/Android/ARM (you will need to compile with -fsigned-char) and iOS. You will need to adjust the Makefile if your system lacks sdl-config to correctly point to the SDL libraries and header files.</p>
<p>On UNIX-based systems we can get raw keystrokes using stty. However Windows has no stty. Therefore the Makefile includes a -D entry to define a &ldquo;keyboard driver&rdquo; KB which as it stands is suitable for UNIXes, but maybe not non-UNIX platforms. For example, for Windows/MS Visual Studio, instead of the Makefile definition of KB, use something slightly different - add the following entry to the Preprocessor Definitions list in the Project Properties page:</p>
<pre><code>KB=(kb=H(8),kbhit())&amp;&amp;(r[1190]=getch(),H(7))
</code></pre>
<h2>POSIX portability note</h2>
<p>The code as supplied uses implicit function declarations for POSIX file I/O and in doing so assumes that file offsets are the same bit width as your architecture. For some systems (e.g. 32-bit Mac OS X, which uses 64-bit file offsets) this is not the case, and to run successfully on these systems, you will need to explicitly declare these functions by adding the appropriate include to the top of the source:</p>
<pre><code>#include &lt;unistd.h&gt;
</code></pre>
<h2>Usage</h2>
<pre><code>./cable3 bios-image-file floppy-image-file [harddisk-image-file]
</code></pre>
<p>PLEASE NOTE that under UNIXes the keyboard must be in raw mode for the emulator to work properly. Therefore the emulator is best run from a shell script that looks something like:</p>
<pre><code>stty cbreak raw -echo min 0
./cable3 bios floppy.img harddisk.img
stty cooked echo
</code></pre>
<h2>To run the emulator - floppy mode only</h2>
<p>The simplest use of the emulator is with a single floppy boot disk image, like the fd.img provided, which is a FreeDOS boot disk.</p>
<p>Before running the emulator on a Unix-type system, stty needs to be used to put the keyboard into raw mode (and afterwards it needs to be put back to cooked). So, run the emulator using something like this script (provided as &ldquo;runme&rdquo;):</p>
<pre><code>stty cbreak raw -echo min 0
./cable3 bios fd.img
stty cooked echo
</code></pre>
<h2>To run the emulator - floppy + HD mode</h2>
<p>Easiest to start with is to try a ready-made 40MB hard disk image containing a whole bunch of software:</p>
<p><a href="http://bitly.com/1bU8URK">http://bitly.com/1bU8URK</a></p>
<p>For the more adventurous, you can start off with (for example) a blank 40MB image file called hd.img made using e.g. mkfile. Then use:</p>
<pre><code>stty cbreak raw -echo min 0
./cable3 bios fd.img hd.img
stty cooked echo
</code></pre>
<p>Preparing the hard disk for use in the emulator is done just like a real PC. Boot the emulator, and use FDISK to partition the hard disk. When it&rsquo;s done FDISK will reboot the emulator. Then you can use FORMAT C: and you are done. The resulting disk image is in the right format to be mounted on a real Windows PC using e.g. OSFMount, on a Mac using hdiutil, or on Linux using mount, providing an easy way to copy files and programs to and from the disk image. Or, you can install programs from regular floppy disk images (see &ldquo;Floppy disk support&rdquo; below).</p>
<h2>Keyboard emulation</h2>
<p>The emulator simulates an XT-style keyboard controlled by an Intel 8042 chip on I/O port 0x60, generating IRQ1 and then interrupt 9 on each keypress. This is harder than it sounds because a real 8042 returns scan codes rather than the ASCII characters which the C standard I/O functions return. Rather than make the emulator less portable and use ioctl or platform-dependent equivalents to obtain real scan codes from the keyboard, the emulator BIOS does the reverse of a real PC BIOS and converts ASCII characters to scancodes, simulating press/release of the modifier keys (e.g. shift) as necessary to work like a &ldquo;real&rdquo; keyboard. The OS (DOS/Windows) then converts them back to ASCII characters and normally this process works seamlessly (although don&rsquo;t be surprised if there are issues, for example, with non-QWERTY e.g. international keyboards).</p>
<p>Most of the time you can just type normally, but there are special sequences to get Alt+xxx and Fxxx.</p>
<p>To send an Alt+XXX key combination, press Ctrl+A then the key, so for example to type Alt+F, press Ctrl+A then F.</p>
<p>To send an Fxx key, press Ctrl+F then a number key. For example, to get the F4 key, press Ctrl+F then 4. To get F10, press Ctrl+F then 0.</p>
<p>To send a Page Down key, press Ctrl+F then O. To send a Page Up key, press Ctrl+F then E. Other key combinations are left for the discovery of the user.</p>
<h2>Text mode support</h2>
<p>The emulator supports both text output via the standard BIOS interrupt 0x10 interface, and also direct video memory access (one page, 4KB video RAM at segment B800) in 80x25 CGA 16-color text mode.</p>
<p>BIOS text output calls are converted to simple writes to stdout. Direct video memory accesses for the 80x25 CGA color text mode are converted to ANSI terminal escape sequences. If you are using a terminal which does not support ANSI (e.g. you are compiling the emulator with MS VC++ and running in a Windows console window) then PC applications that directly write to video memory in text mode may be unusable.</p>
<p>Most CGA I/O ports are not supported except for the CGA refresh register at 0x3DA, which some applications use for timing or synchronisation.</p>
<p>The regular PC character code page (437) includes various extended ASCII characters for things like line drawing. You might want to set the font in your terminal program to something that includes these (e.g. on Mac OS X there is a freeware font called Perfect DOS VGA 437 which does the trick).</p>
<p>Occasionally a DOS application on exit will leave the video hardware in an odd state which confuses the emulator, resulting in subsequent text output being invisible. If this happens, just use the DOS CLS command to clear the screen and all will be well again.</p>
<h2>Graphics mode support</h2>
<p>Hercules 720x348 monochrome graphics mode emulation is implemented using SDL. Most Hercules features are supported via the normal I/O interface on ports 0x3B8 and 0x3BA including video memory bank switching (segments B000/B800), which some games use for double-buffered graphics. CGA graphics modes are not supported.</p>
<p>When an application enters graphics mode, the emulator will open an SDL window (which will be closed when the application goes back to text mode). Including code to redirect keystrokes from the SDL window to the main terminal window would have busted the IOCCC size limits, so you need to keep the main emulator terminal window in focus at all times even when you are doing graphics (sounds a little odd but you will get used to it).</p>
<p>On UNIXes, SDL will automatically output graphics via X11 if the DISPLAY environment variable is set up.</p>
<h2>Dual graphics card support</h2>
<p>Some applications (e.g. AutoCAD) support a PC configuration with a CGA card and a Hercules card, for simultaneous text and graphics output on different displays. The emulator simulates this configuration, too, using separate windows for the (terminal) text and (SDL) graphics displays.</p>
<h2>BIOS</h2>
<p>Like a real PC, the emulator needs a BIOS to do anything useful. Here we use a custom BIOS, written from scratch specifically for the emulator. Source code for the BIOS (written in 8086 assembly language) which compiles with the freely-available NASM x86 assembler is available from the author on request.</p>
<p>The BIOS implements the standard interrupt interfaces for video, disk, timer, clock and so on, much as a &ldquo;real&rdquo; PC BIOS does, and also a small timer-controlled video driver to convert video memory formatting into ANSI escape sequences when the emulator is in text mode.</p>
<h2>CPU and memory emulation</h2>
<p>Memory map is largely as per a real PC, with interrupt vector table at 0:0, BIOS data area including keyboard buffer at 40:0, CGA text video memory at B800:0, Hercules dual-bank graphics memory at B000/B800:0, and BIOS at F000:100. Unlike a real PC, in the emulator the CPU registers are memory-mapped (at F000:0), which enables considerable optimisation of the emulator&rsquo;s instruction execution unit by permitting the unification of memory and register operations, while remaining invisible to the running software.</p>
<p>CPU supports the full 8086/186 instruction set. Due to the complexities of the 8086&rsquo;s arbitrary-length instruction decoding and flags, 8086 instructions are first converted to a simpler intermediate format before being executed. This conversion, along with instruction lengths and how each instruction modifies the flags, is assisted by some lookup tables which form part of the BIOS binary.</p>
<p>The CPU also implements some &ldquo;special&rdquo; two-byte opcodes to help the emulator talk with the outside world. These are:</p>
<pre><code>0F 00 - output character in register AL to terminal
0F 01 - write real-time clock data (as returned by localtime) to memory location ES:BX
0F 02 - read AX bytes from disk at offset 512*(16*SI+BP) into memory location ES:BX. Disk is specified in DL (0 = hard disk, 1 = floppy disk)
0F 03 - write AX bytes at memory location ES:BX to disk at offset 512*(16*SI+BP). Disk is specified in DL as per 0F 02
</code></pre>
<p>Emulator exit is triggered if CS:IP == 0:0 (which would be nonsensical in real software since this is where the interrupt vector table lives). The supplied Dos6.22.img disk includes a small program QUITEMU.COM which contains a single JMP 0:0 instruction, to allow the user to easily quit the emulator without shutting down the terminal.</p>
<h2>Floppy disk support</h2>
<p>Emulates a 3.5" high-density floppy drive. Can read, write and format 1.44MB disks (18 sectors per track, 2 heads) and 720KB disks (9 sectors per track, 2 heads).</p>
<p>If you want to install your own software from floppy images (downloaded from e.g. Vetusware), the easiest way to &ldquo;change disks&rdquo; is to copy each disk image in turn over the floppy image file you specify on the command line. Don&rsquo;t forget to put your original boot disk back at the end!</p>
<h2>Hard disk support</h2>
<p>Supports up to 1023 cylinders, 63 sectors per track, 63 heads for disks up to 528MB.</p>
<p>Disk image format used is a subset of the standard &ldquo;raw&rdquo; format used by most disk image mount tools. In general, disk images prepared by the emulator will work with disk image tools and other emulators, but not the other way around.</p>
<p>The emulator uses a particularly dumb algorithm to derive a simulated cylinder/sector/head geometry from the disk image file&rsquo;s size. This algorithm often results in not all the space in the image file being available for disk partitions. For example, creating a 40,000,000 byte image file results in DOS FDISK seeing only 31.9MB as the volume size.</p>
<p>Note that unlike a real PC, the emulator cannot boot from a hard disk (image). Therefore, you will always need to use a bootable floppy image, even if after boot everything runs from the HD.</p>
<h2>Mouse</h2>
<p>No mouse is emulated.</p>
<h2>Real-time clock</h2>
<p>Reading the RTC (both time and date) is emulated via the standard BIOS clock interface, pulling the time/date from the host computer. Setting the time or date is not supported.</p>
<h2>Timers</h2>
<p>A countdown timer on I/O port 0x40 is simulated in a broken way which is good enough for most software. On a real PC this has a default period of 55ms and is programmable. No programmability is supported in the emulator and the period may be about right or completely wrong depending on the actual speed of your computer.</p>
<p>On a real PC, IRQ0 and interrupt 8 are fired every 55ms. The emulator tries to do the same but again, the delay period is uncalibrated so you get what you get.</p>
<h2>PC speaker</h2>
<p>Beeps only, through the console.</p>
<h2>Software supported</h2>
<p>The emulator will run practically any software a real PC (of the spec listed at the top of this file) can. The author has tested a number of OSes/GUIs (MS-DOS 6.22, FreeDOS 0.82pl3, Windows 3.0, DESQview 2.8), professional software (Lotus 1-2-3 2.4 and AsEasyAs 5.7 for DOS, Excel 2.1 for Windows, AutoCAD 2.5, WordStar 4), programming languages (QBASIC, GWBASIC, Turbo C++), games (Carrier Command, Police Quest, and a bunch of freeware Windows games), and diagnostic/benchmark software (Manifest, Microsoft MSD, InfoSpot, CheckIt) and all of them run well.</p>
<p>Screenshots of some of these applications running (on Mac OS X) are provided for the impatient.</p>
<h2>Compiler warnings</h2>
<p>A lot of compiler warnings are produced by clang. Missing type specifiers, control reaching the end of functions without returning values, incompatible pointer type assignments, and some precedence warnings, all necessary to keep the source size down. Other compilers are likely to produce similar warnings.</p>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+251
View File
@@ -0,0 +1,251 @@
# Largest small system emulator
Adrian Cable
<adrian.cable@gmail.com>
## Judges' comments:
### To build:
make cable3
### To run:
./cable3 bios-image-file floppy-image-file [harddisk-image-file]
### Try:
./runme
### Selected Judges Remarks:
This entry weighs in at a magical 4043 bytes (8086 nibbles, 28,301
bits). It manages to implement most of the hardware in a 1980's era
IBM-PC using a few hundred fewer bits than the total number of
transistors used to implement the original 8086 CPU.
If you are using OS X, the included sc-ioccc.terminal configuration file will
correctly display console applications that use ANSI graphics.
Update: This entry now has its own web page <http://www.megalith.co.uk/8086tiny>
## Author's comments:
A tiny but highly functional PC emulator/virtual machine
========================================================
The author hereby presents, for the delectation (?) of the judges, a portable PC emulator/VM written specifically for the IOCCC which runs DOS, Windows 3.0, Excel, MS Flight Simulator, AutoCAD, Lotus 1-2-3 ...
In just 4043 bytes of C source, you get a complete mid-late 1980s-era IBM-compatible PC, consisting of:
- Intel 8086/186 CPU
- 1MB RAM
- 8072A 3.5" floppy disk controller (1.44MB/720KB)
- Fixed disk controller (supports a single hard drive up to 528MB)
- Hercules graphics card with 720x348 2-color graphics (64KB video RAM), and CGA 80x25 16-color text mode support
- 8253 programmable interval timer (PIT)
- 8259 programmable interrupt controller (PIC)
- 8042 keyboard controller with 83-key XT-style keyboard
- MC146818 real-time clock
- PC speaker
The emulator uses the SDL graphics library for portability, and compiles for Windows, Mac OS X, Linux and probably most other 32-bit/64-bit systems too.
If you like living on the edge you can try building the emulator on a big endian machine, and you will get an emulation of a big endian 8086, a rather bizarre and somewhat useless beast. For everyone else, please run the emulator on a little endian machine.
*RULE 2 ABUSE DISCLAIMER*
- cable3.c is 4043 bytes in length (half an 8086)
- iocccsize -i < cable3.c returns 1977 (the year the 4.77 MHz 8086 CPU was announced)
- Therefore, any suspicions the judges may have regarding rule 2 non-compliance may be well-intentioned but are groundless.
- Nonetheless, the author would like to apologise to the judges for the one-big-block-of-code nature of this entry, which turned out to be unavoidable. Hopefully the joys of this entry will make up for its shortcomings.
*/RULE 2 ABUSE DISCLAIMER*
Why is this entry obfuscated/interesting?
-----------------------------------------
- First of all the 8086 is a nightmare processor to emulate. Instruction codings are complex and irregular in size and structure, with multiple addressing modes and no consistent memory placement for operands, very often multiple possible encodings for the same instruction, and the bizarre segment:offset memory model. In addition, the 8086 has a number of bugs (e.g. PUSH SP), undocumented behaviours and instructions (e.g. AAM/AAD + imm8, SALC, flag behaviour for MUL/DIV, etc. etc.), and archaic features (e.g. parity/auxiliary flags) which all need to be emulated properly. Here we emulate every feature of the CPU pretty exactly (in fact better than most commercial clones of the processor e.g. the NEC V30), with the exception of the trap flag which no real software uses except for debuggers (although support for the TF can be added if deemed important, without exceeding the IOCCC size limit).
- In addition to the CPU we also emulate all the standard PC peripheral hardware. Parts of it are somewhat complete, much is rather dysfunctional (like the 8253/8259) but enough to support most real software.
- Nonetheless the source, while large for the IOCCC, is rather tiny for a functional PC emulator - around 2% of the size of the source of other open-source 8086 PC emulators with comparable functionality.
- In fact, this entry is just like happy hour - at 4043 bytes long, you pay for half the 8086, but you get served the whole one.
- Getting the code down to <= 4096 characters to meet the IOCCC rule 2 overall size limit required a good deal of effort (and appreciable risk of divorce), with obfuscation being a pretty unavoidable consequence in most places ... for the rest, I use short circuit operators whenever possible, mix x[y] and y[x], don't use any flow control keywords except for for, use K&R-style declarations to honor the C language's rich cultural heritage (plus it saves a byte), and occasionally go overboard with nasty nested indexes to give things like this: --64[T=1[O=32[L=(X=*Y&7)&1,o=X/2&1,l]=0,t=(c=y)&7,a=c/8&7,Y]>>6,g=~-T?y:(n)y,d=BX=y,l]
- This entry highlights the importance of comments in C.
- This entry might result in an adjustment to the IOCCC size tool for the 2014 competition (see above).
Compiling on different platforms
--------------------------------
This entry has been tested on Windows (compiled with MS Visual Studio 2010 and 2013), Mac OS X (clang and gcc), and Linux (clang and gcc). The Makefile supplied is good for Mac OS X, Linux and probably other UNIXes. I have received reports that the emulator works on Raspberry Pi/Android/ARM (you will need to compile with -fsigned-char) and iOS. You will need to adjust the Makefile if your system lacks sdl-config to correctly point to the SDL libraries and header files.
On UNIX-based systems we can get raw keystrokes using stty. However Windows has no stty. Therefore the Makefile includes a -D entry to define a "keyboard driver" KB which as it stands is suitable for UNIXes, but maybe not non-UNIX platforms. For example, for Windows/MS Visual Studio, instead of the Makefile definition of KB, use something slightly different - add the following entry to the Preprocessor Definitions list in the Project Properties page:
KB=(kb=H(8),kbhit())&&(r[1190]=getch(),H(7))
POSIX portability note
----------------------
The code as supplied uses implicit function declarations for POSIX file I/O and in doing so assumes that file offsets are the same bit width as your architecture. For some systems (e.g. 32-bit Mac OS X, which uses 64-bit file offsets) this is not the case, and to run successfully on these systems, you will need to explicitly declare these functions by adding the appropriate include to the top of the source:
#include <unistd.h>
Usage
-----
./cable3 bios-image-file floppy-image-file [harddisk-image-file]
PLEASE NOTE that under UNIXes the keyboard must be in raw mode for the emulator to work properly. Therefore the emulator is best run from a shell script that looks something like:
stty cbreak raw -echo min 0
./cable3 bios floppy.img harddisk.img
stty cooked echo
To run the emulator - floppy mode only
--------------------------------------
The simplest use of the emulator is with a single floppy boot disk image, like the fd.img provided, which is a FreeDOS boot disk.
Before running the emulator on a Unix-type system, stty needs to be used to put the keyboard into raw mode (and afterwards it needs to be put back to cooked). So, run the emulator using something like this script (provided as "runme"):
stty cbreak raw -echo min 0
./cable3 bios fd.img
stty cooked echo
To run the emulator - floppy + HD mode
--------------------------------------
Easiest to start with is to try a ready-made 40MB hard disk image containing a whole bunch of software:
<http://bitly.com/1bU8URK>
For the more adventurous, you can start off with (for example) a blank 40MB image file called hd.img made using e.g. mkfile. Then use:
stty cbreak raw -echo min 0
./cable3 bios fd.img hd.img
stty cooked echo
Preparing the hard disk for use in the emulator is done just like a real PC. Boot the emulator, and use FDISK to partition the hard disk. When it's done FDISK will reboot the emulator. Then you can use FORMAT C: and you are done. The resulting disk image is in the right format to be mounted on a real Windows PC using e.g. OSFMount, on a Mac using hdiutil, or on Linux using mount, providing an easy way to copy files and programs to and from the disk image. Or, you can install programs from regular floppy disk images (see "Floppy disk support" below).
Keyboard emulation
------------------
The emulator simulates an XT-style keyboard controlled by an Intel 8042 chip on I/O port 0x60, generating IRQ1 and then interrupt 9 on each keypress. This is harder than it sounds because a real 8042 returns scan codes rather than the ASCII characters which the C standard I/O functions return. Rather than make the emulator less portable and use ioctl or platform-dependent equivalents to obtain real scan codes from the keyboard, the emulator BIOS does the reverse of a real PC BIOS and converts ASCII characters to scancodes, simulating press/release of the modifier keys (e.g. shift) as necessary to work like a "real" keyboard. The OS (DOS/Windows) then converts them back to ASCII characters and normally this process works seamlessly (although don't be surprised if there are issues, for example, with non-QWERTY e.g. international keyboards).
Most of the time you can just type normally, but there are special sequences to get Alt+xxx and Fxxx.
To send an Alt+XXX key combination, press Ctrl+A then the key, so for example to type Alt+F, press Ctrl+A then F.
To send an Fxx key, press Ctrl+F then a number key. For example, to get the F4 key, press Ctrl+F then 4. To get F10, press Ctrl+F then 0.
To send a Page Down key, press Ctrl+F then O. To send a Page Up key, press Ctrl+F then E. Other key combinations are left for the discovery of the user.
Text mode support
-----------------
The emulator supports both text output via the standard BIOS interrupt 0x10 interface, and also direct video memory access (one page, 4KB video RAM at segment B800) in 80x25 CGA 16-color text mode.
BIOS text output calls are converted to simple writes to stdout. Direct video memory accesses for the 80x25 CGA color text mode are converted to ANSI terminal escape sequences. If you are using a terminal which does not support ANSI (e.g. you are compiling the emulator with MS VC++ and running in a Windows console window) then PC applications that directly write to video memory in text mode may be unusable.
Most CGA I/O ports are not supported except for the CGA refresh register at 0x3DA, which some applications use for timing or synchronisation.
The regular PC character code page (437) includes various extended ASCII characters for things like line drawing. You might want to set the font in your terminal program to something that includes these (e.g. on Mac OS X there is a freeware font called Perfect DOS VGA 437 which does the trick).
Occasionally a DOS application on exit will leave the video hardware in an odd state which confuses the emulator, resulting in subsequent text output being invisible. If this happens, just use the DOS CLS command to clear the screen and all will be well again.
Graphics mode support
---------------------
Hercules 720x348 monochrome graphics mode emulation is implemented using SDL. Most Hercules features are supported via the normal I/O interface on ports 0x3B8 and 0x3BA including video memory bank switching (segments B000/B800), which some games use for double-buffered graphics. CGA graphics modes are not supported.
When an application enters graphics mode, the emulator will open an SDL window (which will be closed when the application goes back to text mode). Including code to redirect keystrokes from the SDL window to the main terminal window would have busted the IOCCC size limits, so you need to keep the main emulator terminal window in focus at all times even when you are doing graphics (sounds a little odd but you will get used to it).
On UNIXes, SDL will automatically output graphics via X11 if the DISPLAY environment variable is set up.
Dual graphics card support
--------------------------
Some applications (e.g. AutoCAD) support a PC configuration with a CGA card and a Hercules card, for simultaneous text and graphics output on different displays. The emulator simulates this configuration, too, using separate windows for the (terminal) text and (SDL) graphics displays.
BIOS
----
Like a real PC, the emulator needs a BIOS to do anything useful. Here we use a custom BIOS, written from scratch specifically for the emulator. Source code for the BIOS (written in 8086 assembly language) which compiles with the freely-available NASM x86 assembler is available from the author on request.
The BIOS implements the standard interrupt interfaces for video, disk, timer, clock and so on, much as a "real" PC BIOS does, and also a small timer-controlled video driver to convert video memory formatting into ANSI escape sequences when the emulator is in text mode.
CPU and memory emulation
------------------------
Memory map is largely as per a real PC, with interrupt vector table at 0:0, BIOS data area including keyboard buffer at 40:0, CGA text video memory at B800:0, Hercules dual-bank graphics memory at B000/B800:0, and BIOS at F000:100. Unlike a real PC, in the emulator the CPU registers are memory-mapped (at F000:0), which enables considerable optimisation of the emulator's instruction execution unit by permitting the unification of memory and register operations, while remaining invisible to the running software.
CPU supports the full 8086/186 instruction set. Due to the complexities of the 8086's arbitrary-length instruction decoding and flags, 8086 instructions are first converted to a simpler intermediate format before being executed. This conversion, along with instruction lengths and how each instruction modifies the flags, is assisted by some lookup tables which form part of the BIOS binary.
The CPU also implements some "special" two-byte opcodes to help the emulator talk with the outside world. These are:
0F 00 - output character in register AL to terminal
0F 01 - write real-time clock data (as returned by localtime) to memory location ES:BX
0F 02 - read AX bytes from disk at offset 512*(16*SI+BP) into memory location ES:BX. Disk is specified in DL (0 = hard disk, 1 = floppy disk)
0F 03 - write AX bytes at memory location ES:BX to disk at offset 512*(16*SI+BP). Disk is specified in DL as per 0F 02
Emulator exit is triggered if CS:IP == 0:0 (which would be nonsensical in real software since this is where the interrupt vector table lives). The supplied Dos6.22.img disk includes a small program QUITEMU.COM which contains a single JMP 0:0 instruction, to allow the user to easily quit the emulator without shutting down the terminal.
Floppy disk support
-------------------
Emulates a 3.5" high-density floppy drive. Can read, write and format 1.44MB disks (18 sectors per track, 2 heads) and 720KB disks (9 sectors per track, 2 heads).
If you want to install your own software from floppy images (downloaded from e.g. Vetusware), the easiest way to "change disks" is to copy each disk image in turn over the floppy image file you specify on the command line. Don't forget to put your original boot disk back at the end!
Hard disk support
-----------------
Supports up to 1023 cylinders, 63 sectors per track, 63 heads for disks up to 528MB.
Disk image format used is a subset of the standard "raw" format used by most disk image mount tools. In general, disk images prepared by the emulator will work with disk image tools and other emulators, but not the other way around.
The emulator uses a particularly dumb algorithm to derive a simulated cylinder/sector/head geometry from the disk image file's size. This algorithm often results in not all the space in the image file being available for disk partitions. For example, creating a 40,000,000 byte image file results in DOS FDISK seeing only 31.9MB as the volume size.
Note that unlike a real PC, the emulator cannot boot from a hard disk (image). Therefore, you will always need to use a bootable floppy image, even if after boot everything runs from the HD.
Mouse
-----
No mouse is emulated.
Real-time clock
---------------
Reading the RTC (both time and date) is emulated via the standard BIOS clock interface, pulling the time/date from the host computer. Setting the time or date is not supported.
Timers
------
A countdown timer on I/O port 0x40 is simulated in a broken way which is good enough for most software. On a real PC this has a default period of 55ms and is programmable. No programmability is supported in the emulator and the period may be about right or completely wrong depending on the actual speed of your computer.
On a real PC, IRQ0 and interrupt 8 are fired every 55ms. The emulator tries to do the same but again, the delay period is uncalibrated so you get what you get.
PC speaker
----------
Beeps only, through the console.
Software supported
------------------
The emulator will run practically any software a real PC (of the spec listed at the top of this file) can. The author has tested a number of OSes/GUIs (MS-DOS 6.22, FreeDOS 0.82pl3, Windows 3.0, DESQview 2.8), professional software (Lotus 1-2-3 2.4 and AsEasyAs 5.7 for DOS, Excel 2.1 for Windows, AutoCAD 2.5, WordStar 4), programming languages (QBASIC, GWBASIC, Turbo C++), games (Carrier Command, Police Quest, and a bunch of freeware Windows games), and diagnostic/benchmark software (Manifest, Microsoft MSD, InfoSpot, CheckIt) and all of them run well.
Screenshots of some of these applications running (on Mac OS X) are provided for the impatient.
Compiler warnings
-----------------
A lot of compiler warnings are produced by clang. Missing type specifiers, control reaching the end of functions without returning values, incompatible pointer type assignments, and some precedence warnings, all necessary to keep the source size down. Other compilers are likely to produce similar warnings.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+10
View File
@@ -0,0 +1,10 @@
#!/bin/sh
clear
stty cbreak raw -echo min 0
if [ -f hd.img ]
then
./cable3 bios fd.img hd.img
else
./cable3 bios fd.img
fi
stty cooked echo
+80
View File
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BackgroundColor</key>
<data>
YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKMHCA9VJG51bGzTCQoLDA0OV05TV2hpdGVcTlNDb2xvclNwYWNlViRjbGFzc00w
IDAuODk5OTk5OTgAEAOAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqIS
FFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FIUF1k
cnR2e4aPl5qjtbi9AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAAL8=
</data>
<key>CharacterEncoding</key>
<integer>2147484699</integer>
<key>CursorBlink</key>
<true/>
<key>CursorColor</key>
<data>
YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECEw
LjIxOTYwNzg2IDAuOTk2MDc4NDkgMC4xNTI5NDExOAAQAoAC0hAREhNaJGNsYXNzbmFt
ZVgkY2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcY
VHJvb3SAAQgRGiMtMjc7QUhOW2KGiIqPmqOrrrfJzNEAAAAAAAABAQAAAAAAAAAZAAAA
AAAAAAAAAAAAAAAA0w==
</data>
<key>CursorType</key>
<integer>0</integer>
<key>Font</key>
<data>
YnBsaXN0MDDUAQIDBAUGGBlYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKQHCBESVSRudWxs1AkKCwwNDg8QVk5TU2l6ZVhOU2ZGbGFnc1ZOU05hbWVWJGNs
YXNzI0A4AAAAAAAAEBCAAoADXlBUTW9uby1SZWd1bGFy0hMUFRZaJGNsYXNzbmFtZVgk
Y2xhc3Nlc1ZOU0ZvbnSiFRdYTlNPYmplY3RfEA9OU0tleWVkQXJjaGl2ZXLRGhtUcm9v
dIABCBEaIy0yNzxCS1JbYmlydHZ4h4yXoKeqs8XIzQAAAAAAAAEBAAAAAAAAABwAAAAA
AAAAAAAAAAAAAADP
</data>
<key>FontAntialias</key>
<false/>
<key>FontHeightSpacing</key>
<real>0.87752016129032251</real>
<key>FontWidthSpacing</key>
<real>0.92313508064516125</real>
<key>Linewrap</key>
<true/>
<key>ProfileCurrentVersion</key>
<real>2.02</real>
<key>SelectionColor</key>
<data>
YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPEB4w
LjAzNDU3ODM5NSAwIDAuOTEzMjY1MzEgMC42NQAQAYAC0hAREhNaJGNsYXNzbmFtZVgk
Y2xhc3Nlc1dOU0NvbG9yohIUWE5TT2JqZWN0XxAPTlNLZXllZEFyY2hpdmVy0RcYVHJv
b3SAAQgRGiMtMjc7QUhOW2KDhYeMl6Coq7TGyc4AAAAAAAABAQAAAAAAAAAZAAAAAAAA
AAAAAAAAAAAA0A==
</data>
<key>TextBoldColor</key>
<data>
YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NGMCAx
IDAAEAGAAtIQERITWiRjbGFzc25hbWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVj
dF8QD05TS2V5ZWRBcmNoaXZlctEXGFRyb290gAEIERojLTI3O0FITltiaWttcn2GjpGa
rK+0AAAAAAAAAQEAAAAAAAAAGQAAAAAAAAAAAAAAAAAAALY=
</data>
<key>TextColor</key>
<data>
YnBsaXN0MDDUAQIDBAUGFRZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3AS
AAGGoKMHCA9VJG51bGzTCQoLDA0OVU5TUkdCXE5TQ29sb3JTcGFjZVYkY2xhc3NPECIw
LjE1Njg2Mjc1IDAuOTk2MDc4NDkgMC4wNzg0MzEzNzUAEAKAAtIQERITWiRjbGFzc25h
bWVYJGNsYXNzZXNXTlNDb2xvcqISFFhOU09iamVjdF8QD05TS2V5ZWRBcmNoaXZlctEX
GFRyb290gAEIERojLTI3O0FITltih4mLkJukrK+4ys3SAAAAAAAAAQEAAAAAAAAAGQAA
AAAAAAAAAAAAAAAAANQ=
</data>
<key>name</key>
<string>sc-ioccc</string>
<key>rowCount</key>
<integer>25</integer>
<key>type</key>
<string>Window Settings</string>
</dict>
</plist>
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

+204
View File
@@ -0,0 +1,204 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall -Wno-implicit-int
#CWARN= -Wall -W -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT} ${LIBS} -include stdio.h -include stdlib.h -D'_(x)=strtof(b[x],0)'
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= dlowe
DATA=
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} ${DATA}
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
dlowe: dlowe.c
+2
View File
@@ -0,0 +1,2 @@
main(a,b)char**b;{int c=1,d=c,e=a-d;for(;e;e--)_(e)<_(c)?c=e:_(e)>_(d)?d=e:7;
while(++e<a)printf("\xe2\x96%c",129+(**b=8*(_(e)-_(c))/(_(d)-_(c))));}
+148
View File
@@ -0,0 +1,148 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Best sparkling utility</title>
</head>
<body>
<h1>Best sparkling utility</h1>
<ol type="a">
<li>David Lowe<br>
434 Tenney Drive<br>
Rogue River, OR<br>
97537<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#106;&#46;&#100;&#x61;&#118;&#x69;&#x64;&#46;&#108;&#111;&#x77;&#101;&#x40;&#x67;&#x6d;&#x61;&#x69;&#108;&#x2e;&#99;&#111;&#x6d;">&#106;&#x2e;&#100;&#97;&#x76;&#105;&#100;&#46;&#x6c;&#111;&#x77;&#x65;&#x40;&#x67;&#109;&#97;&#x69;&#108;&#x2e;&#99;&#111;&#109;</a><br>
<a href="http://www.pootpoot.net/">http://www.pootpoot.net/</a></li>
</ol>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make dlowe
</code></pre>
<h3>To run:</h3>
<pre><code>./dlowe [numbers...]
</code></pre>
<h3>Try:</h3>
<pre><code>./dlowe 0 1 2 3 4 5 6 7
./dlowe 16 32 64 128
echo sparkline of file sizes: `wc -c * | awk '{print $1}' | xargs ./dlowe`
./dlowe 0
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>We liked how this entry used Unicode, specifically UTF-8, in a somewhat obfuscated way.</p>
<p>Also, why doesn&rsquo;t it crash, and produces a correct output when called with one argument
or when all arguments are equal?</p>
<p>For extra fun, compile and run</p>
<pre><code>#include &lt;stdio.h&gt;
int main() {
printf("%d %d %d\n", (int)(-1.0/0.0), (int)(0.0/0.0), (int)(1.0/0.0));
}
</code></pre>
<p>with gcc and clang.</p>
<p>With GCC (4.7.2), we get</p>
<pre><code>-2147483648 -2147483648 -2147483648
</code></pre>
<p>and with clang (3.3), we get</p>
<pre><code>-2147483648 0 2147483647
</code></pre>
<p>Which one is correct? :)</p>
<h2>Author&rsquo;s comments:</h2>
<h1>sparkl</h1>
<p>A tiny implementation of command-line &lsquo;sparkline&rsquo; data visualization.</p>
<h2>Synopsis</h2>
<pre><code>$ sparkl 0 1 2 3 4 5 6 7
▁▂▃▄▅▆▇▉
$ echo sparkline of file lengths: `wc -c * | awk '{print $1}' | xargs sparkl`
sparkline of file sizes: ▁▁▁▃▃▂▁▂▁▁▉
</code></pre>
<h2>Description</h2>
<p>This is a handy little tool for visualizing numeric series from the
command-line, using &lsquo;sparklines&rsquo;. Pass it a numeric series as arguments, and
sparkl will display a sparkline graph, which you can use to very quickly get a
sense of the shape of your data.</p>
<h2>Limitations</h2>
<ul>
<li>Crashes with 0 arguments. It&rsquo;d be trivial to fix, but adds a few bytes to the
code.</li>
<li>Produces bogus graphs when given > about 5000 arguments.</li>
<li>Only works if your terminal is utf-8 and your font supports the 8 glyphs
used.</li>
<li>Produces a few harmless compiler warnings.</li>
</ul>
<h2>Obfuscation</h2>
<p>The code is very terse. I was torn between submitting this version, and a
one-line version compressed using a couple more -D flags.</p>
<p>Hand-rolled utf-8 sequence, magic numbers (what&rsquo;s that 7 for?), meaningless
variable names, reused variables, and so on.</p>
<h2>Acknowledgements</h2>
<p>Edward Tufte invented sparklines (among other things.) Brilliant.</p>
<p>Zach Holman&rsquo;s <a href="https://github.com/holman/spark">&lsquo;spark&rsquo; utility</a> was absolutely
an inspiration.</p>
<p>As I was writing up this description, I discovered I&rsquo;m not the first person to
write an obfuscated C sparkline utility! Vicent Martí created
<a href="https://gist.github.com/vmg/1368661">this one</a> years (!) ago. (My
implementation is completely independent.)</p>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+113
View File
@@ -0,0 +1,113 @@
# Best sparkling utility
J. David Lowe
434 Tenney Drive
Rogue River, OR
97537
<j.david.lowe@gmail.com>
<http://www.pootpoot.net/>
## Judges' comments:
### To build:
make dlowe
### To run:
./dlowe [numbers...]
### Try:
./dlowe 0 1 2 3 4 5 6 7
./dlowe 16 32 64 128
echo sparkline of file sizes: `wc -c * | awk '{print $1}' | xargs ./dlowe`
./dlowe 0
### Selected Judges Remarks:
We liked how this entry used Unicode, specifically UTF-8, in a somewhat obfuscated way.
Also, why doesn't it crash, and produces a correct output when called with one argument
or when all arguments are equal?
For extra fun, compile and run
#include <stdio.h>
int main() {
printf("%d %d %d\n", (int)(-1.0/0.0), (int)(0.0/0.0), (int)(1.0/0.0));
}
with gcc and clang.
With GCC (4.7.2), we get
-2147483648 -2147483648 -2147483648
and with clang (3.3), we get
-2147483648 0 2147483647
Which one is correct? :)
## Author's comments:
# sparkl
A tiny implementation of command-line 'sparkline' data visualization.
## Synopsis
$ sparkl 0 1 2 3 4 5 6 7
▁▂▃▄▅▆▇▉
$ echo sparkline of file lengths: `wc -c * | awk '{print $1}' | xargs sparkl`
sparkline of file sizes: ▁▁▁▃▃▂▁▂▁▁▉
## Description
This is a handy little tool for visualizing numeric series from the
command-line, using 'sparklines'. Pass it a numeric series as arguments, and
sparkl will display a sparkline graph, which you can use to very quickly get a
sense of the shape of your data.
## Limitations
* Crashes with 0 arguments. It'd be trivial to fix, but adds a few bytes to the
code.
* Produces bogus graphs when given > about 5000 arguments.
* Only works if your terminal is utf-8 and your font supports the 8 glyphs
used.
* Produces a few harmless compiler warnings.
## Obfuscation
The code is very terse. I was torn between submitting this version, and a
one-line version compressed using a couple more -D flags.
Hand-rolled utf-8 sequence, magic numbers (what's that 7 for?), meaningless
variable names, reused variables, and so on.
## Acknowledgements
Edward Tufte invented sparklines (among other things.) Brilliant.
Zach Holman's ['spark' utility](https://github.com/holman/spark) was absolutely
an inspiration.
As I was writing up this description, I discovered I'm not the first person to
write an obfuscated C sparkline utility! Vicent Martí created
[this one](https://gist.github.com/vmg/1368661) years (!) ago. (My
implementation is completely independent.)
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+210
View File
@@ -0,0 +1,210 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall -W
#CWARN= -Wall -W -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT} ${LIBS}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= endoh1
DATA=
ALT_OBJ=
ALT_ENTRY=hello echo tac
#################
# build the entry
#################
#
all: ${ENTRY} ${ALT_ENTRY}
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@
@$(MAKE) ${ALT_ENTRY}
# alternative executable
#
hello: hello.lazy ${ENTRY}.c
${CC} ${CFLAGS} -xc hello.lazy -o $@
echo: echo.lazy ${ENTRY}.c
${CC} ${CFLAGS} -xc echo.lazy -o $@
tac: tac.lazy ${ENTRY}.c
${CC} ${CFLAGS} -xc tac.lazy -o $@
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
+5
View File
@@ -0,0 +1,5 @@
#include "endoh1.c"
I
#include "endoh1.c"
+87
View File
@@ -0,0 +1,87 @@
#ifndef SKI
#define A(x)B(x##0)B(x##1)B(x##2)B(x##3)B(x##4)B(x##5)
#define B(x)C(x##0)C(x##1)C(x##2)C(x##3)C(x##4)C(x##5)
#define C(x)D(x##0)D(x##1)D(x##2)D(x##3)D(x##4)D(x##5)
#define D(x)Z(x##0)Z(x##1)Z(x##2)Z(x##3)Z(x##4)Z(x##5)
#define p(x)(*(*(*(*(*(*x)())())())())())()
#include <stdio.h>
#include <stdlib.h>
#define S (Y(s+6))
#define K (Y(s+4))
#define I (Y(s+2))
#define Z(x)\
f x;f Y(v);g\
j;f \
x##z( f\
y){y =y?! x?x= y:Y( m(*( w)&\
x,(( g)y) (0)) ):x;return y; /*ab c*/}
/**/ typedef void *v ;int
n=0; typedef v* w;typed\
ef v(*g)();v s[]= {0,0, s+6, s+2,
s+4,s,s+3,s+ 5,s+ 1};w m( v l ,v
r){w e=ma\
lloc (siz\
eof( v)*3
);*e =r;e [1
]=l;return (e[2 ]=s, e);} /*de fghi jk*/ typ\
edef v(p( p(p( p(p( p(p( p(p( p(p(f)))) ))) )))) );A(
x)w u(){ return n --?m (j(0 ),u( )):s+3;}
w z( w e) {w a,b , c,d;for (d =e=m(e,0
);n= (w)d[ 2]-s ,n?* (n>1? n<4? b:a:
c)?n <2?c[ 1]=m (*a, *c), *c=m (*b,
*c):
n>5?
#undef Z
#define Z(x\
) &x ##z,
a[1]= m(
*a,!*d? d[1] =c=m (0,0 ),n= getchar(),n= n<0?
256:n,c [2]= s+6, *d=u ():* d),*a=d[1]: n<5?n<3?n=z(*
a)-s, putchar( 255< +n?( exit (n-4
*64) ,0):n ),fflush (stdout) ,c[1 ]=
*b:((n-3?b:c )[1] =*a) :(2[* a=z(*a)+1,a
]=s+5),d =e:0 :e;d =d[1 ])c=b,b=a,a=
d;a=
*(w*
)e [1
]; ;;
/*lm no*/ return a;}f( *h [])( )={A (x)0};f Y(v x)
{g y =(g) h[n++] ;y(! y? exit( puts ("out of c" ""
"losure" )),x :x );return(f )y/* pq
r*/;}int main () {z(((g )(S S(
j=(g )S(S (K S)K))(K( S I I)) (S(K(S I))( S(
K K) (S(K (S(S(K(Y(s+1 )) )(S( S S(K I)) (K (Y
(s +5)) ))
)) )K)) )(
#endif
#if (!defined(__INCLUDE_LEVEL__) || !__INCLUDE_LEVEL__) && !defined(SKI)
K(I(I(I(S I I(S(K(S(S(K S)(S(S S S(K(S(K S)))(S(S S S(K(S(K S)))(S(K(S(S(K S)(S(S(K S)K)(K(S(S(K S)(S(K(S(S(S I(K K))(K K))))(S(K K)(S(S(K S)(S(K(S(S I(K K))))(S(K K)(S(S(K K))(K(S(S(S(S(K S)K)))I(S(S(K S)K)I)))))))(S(K K)(S(S(K K))(K(S(K(S(S(K S)K)I))(S(S(K S)K)(S I I(S(S(K S)K)I)))))))))))(S(K K)(S(K K)(S(S(K K))(K(S(K(S(S(K S)K)I))(S(S I I)I(S(S(K S)K)I)))))))))))))(S(K K)(S(K K)(S(K(S(S I(K(S(S I(K(K I)))(K S))))))K)))))(K(K(K K)))))(K(K(K(K I))))))))(S(K(S(K K)))(S(S(K S)(S(K K)(S(K S)(S(S(K K))I))))(K(S(K(S(S(K S)(S(K(S I))K))))(S(K K)K))))))(S(S I(K(S I I(S I I(S(S(K S)K)I)))))(K(K K)))S K K K I I I K K K I I I K K K I I I K K K I I K K K K K S K I I I K I K I I I K I K)I I I K I K I I I K I I I K I I S K I I I I I K I I I I I K I K I I I K I I I K I I S K I I)I K I K I I I K I K I I I K I K I I I K I I I K I I S K K K I I I K K K I I I K K K I I I K K K I I K K K K K S S K I I I K S)K I I K S K K K S K I I K S K I I I K S S K K K K K S K I I I I S K K K K K S K S K K K K K(K K))
#define SKI
#endif
#ifdef SKI
(Y(s)))))(0));return 0;}
#else
#define SKI
#endif
+5
View File
@@ -0,0 +1,5 @@
#include "endoh1.c"
K(S(S I(K(S(K(S I I(S(S(K S)K)I)))(S(S(K S)K)(S(S(K S)K)(S(S I I)I(S(S(K S)K)I)))))))(K(S(S I(K(S(S(K S)K)(S(S(K S)K)I(S(K(S(S(K S)K)I))(S(S(K S)K)(S I I(S(S(K S)K)I))))))))(K(S(S(K S)(S(K(S I))K))(S(K K)(S(S(K S)(S(K(S I))K))(S(K K)(S(S(K S)(S(K(S I))(S(K K)(S(S I(K(S(S(K S)K))))(K(S(S(K S)K)(S(S(K S)K)I)))))))(K(K(S(S I(K(S(S(K S)K)(S(S I I)I(S(S(K S)K)I))(S(S(K S)K))(S I I(S(S(K S)K)(S(S(K S)K)I))))))(K(S(S I(K(S(K(S(S(K S)K)I))(S(S I I)I(S(S(K S)K)I)))))(K(S(S I(K(S(S(K S)K)(S(K(S I I(S(S(K S)K)I)))(S(S(K S)K)(S(S(K S)K)(S(S I I)I(S(S(K S)K)I))))))))(K(S(S I(K(S(S(K S)K)(S(K(S(S(K S)K)(S(S(K S)K)I)))(S(S(K S)K)(S(S(K S)K)I(S(S(K S)K)(S I I(S(S(K S)K)I)))))))))(K(S(S(K S)(S(K(S I))K))(S(K K)(S(S(K S)(S(K(S I))K))(S(K K)(S(S(K S)(S(K(S I))K))(K(K(S(S I(K(S(S(K S)K)(S(K(S(S(K S)K)I))(S(S I I)I(S(S(K S)K)I))))))(K(S(S I(K(S(K(S(S(K S)K)I))(S(S(K S)K)(S I I(S(S(K S)K)I))))))(K(S(S I(K(S I I(S I I(S(S(K S)K)I)))))(K S))))))))))))(S(S(K S)K)(S(S(K S)K)(S(S(K S)K)(S(S(S(K S)K))(S I I)(S(S(K S)K)I))))))))))))))))))))(S(K(S I I(S(S(K S)K)I)))(S I I(S(S(K S)K)(S(S(K S)K)I)))))))))
#include "endoh1.c"
+254
View File
@@ -0,0 +1,254 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Most lazy SKIer</title>
</head>
<body>
<h1>Most lazy SKIer</h1>
<p>Yusuke Endoh<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#109;&#97;&#109;&#x65;&#64;&#x72;&#x75;&#98;&#121;&#45;&#x6c;&#97;&#x6e;&#x67;&#x2e;&#x6f;&#x72;&#103;">&#x6d;&#97;&#109;&#x65;&#64;&#x72;&#117;&#98;&#x79;&#45;&#108;&#97;&#x6e;&#103;&#x2e;&#x6f;&#x72;&#x67;</a><br>
<a href="https://github.com/mame/">https://github.com/mame/</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make
</code></pre>
<p>This builds endoh1, echo, hello, and tac.</p>
<h3>To run:</h3>
<pre><code>./endoh1 [file.lazy]
</code></pre>
<h3>Try:</h3>
<pre><code>./endoh1 hello.lazy
./hello
echo Hello | ./echo
./tac &lt; endoh1.c
</code></pre>
<p>Be patient with the last one.</p>
<h3>Selected Judges Remarks:</h3>
<p>We liked this entry because it can serve as a standalone program as well as an include file; and, as usual,
because its input data is at least as obfuscated as the program itself.</p>
<p>This entry can be considered an abuse of the GCC&rsquo;s optimizer; it takes GCC about 4x longer to compile it
with -O3 than without, compared to clang&rsquo;s 2x.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Remarks</h3>
<pre><code>$ less prog.c
$ gcc -o prog prog.c
$ ./prog
</code></pre>
<p>&hellip; Isn&rsquo;t there any more to it?</p>
<p>Yes, of course.</p>
<p>This is a tool <em>for C programmers</em> to play the <a href="http://en.wikipedia.org/wiki/SKI_combinator_calculus">SKI combinator calculus</a>,
especially, <a href="redacted">Lazy K</a>.</p>
<p>This program will shine when it is used as a library.
For example, <code>hello.lazy</code> is a &ldquo;Hello world&rdquo; program written in Lazy K.</p>
<pre><code>$ lazy hello.lazy
Hello, world!
</code></pre>
<p>where <code>lazy</code> is <a href="redacted">a reference implementation of Lazy K</a>.
At the same time, <code>hello.lazy</code> is <em>a valid C program</em> that uses <code>prog.c</code> as a library.</p>
<pre><code>$ gcc -o hello -xc hello.lazy
$ ./hello
Hello, world!
</code></pre>
<p>In other words, this program is a kind of <a href="http://en.wikipedia.org/wiki/Polyglot_%28computing%29">polyglot</a>.</p>
<p>The usage is simple:
you just have to wrap Lazy K program with <code>#include "prog.c"</code>.
Note that <code>#</code> is a comment in Lazy K.</p>
<h3>Obfuscation</h3>
<p>&hellip; is inherent in SKI combinator calculus :-)</p>
<p>In addition, it uses various hacks to parse SKI code as C,
and to satisfy IOCCC&rsquo;s size rule.</p>
<ul>
<li>Abuse of function pointers</li>
<li>Code duplication by macros</li>
<li>Short coding</li>
</ul>
<p>These led to the good obfuscation.
See Spoiler section in detail, if you need.</p>
<h3>Limitation</h3>
<p>This program supports only &ldquo;Combinator-calculus style notation&rdquo; of Lazy K.
&ldquo;Unlambda style&rdquo; and &ldquo;Iota and Jot&rdquo; style are not supported.
Also, it requires a space between identifiers.
In short, use <code>(S K)</code> instead of <code>(SK)</code>, &ldquo;`sk&rdquo;, <code>**i*i*i*ii*i*i*ii</code>,
or <code>11111100011100</code>.</p>
<p>Huge memory may be required to compile the program
(about 300 MB on my machine).</p>
<p>In addition, there are some limitations (and workarounds)
mentioned in Spoiler section.
But I think it wouldn&rsquo;t matter only when you run the attached programs.</p>
<h3>Portability</h3>
<p>I confirmed that the program successfully worked
with the following compilers.</p>
<ul>
<li>gcc 4.6.3 [Linux, Mac OS X]</li>
<li>clang 3.0 [Linux, Mac OS X]</li>
<li>tcc 0.9.26 [Linux]
<ul>
<li>N.B. tcc 0.9.25 seems to have a bug and fails to run it.</li>
</ul>
</li>
</ul>
<p>Recent compilers with <code>-Wall -W -Wextra -pedantic</code> say nothing.</p>
<pre><code>gcc -Wall -W -Wextra -pedantic prog.c
clang -Wall -W -Wextra -pedantic prog.c
tcc -Wall -W -Wextra -pedantic prog.c
</code></pre>
<p>I think it will work on almost all platforms. I confirmed:</p>
<ul>
<li>Ubuntu Linux</li>
<li>Mac OS X</li>
<li>Raspberry PI</li>
</ul>
<p>To check whether the program is specified on the command line
or included from another source file,
the program uses a predefined macro <code>__INCLUDE_LEVEL__</code>.
It is a gcc extention, and also supported by clang.
If your compiler does not support it,
you cannot use the program as a library.
But you can compile and run it as a standalone program, at least.
In fact, tcc does not support the macro, but does work.</p>
<h3>Spoiler (rot13)</h3>
<p>Gur jubyr cebtenz vf vagrecergrq ol znpeb rkcnafvba.
Sbe rknzcyr, <code>F (X V)</code> vf genafyngrq gb n abezny P pbqr, <code>(f)((x)(v))</code>,
be fvzcyl <code>f(x(v))</code>.
Guvf rkcerffvba ergheaf na nofgenpg flagnk gerr,
naq <code>cebt.p</code> rinyhngrf vg.
Guvf cebtenz hfrf irel fvzcyr &ldquo;grez erjevgvat&rdquo; nccebnpu
sbe rinyhngvat FXV pbzovangbe pnyphyhf.
Gur erjevgvat ehyrf ner fubja va gur funcr bs gur pbqr.</p>
<h4>Nohfr bs shapgvba cbvagref</h4>
<p>Pbafvqre n frdhrapr bs shapgvba nccyvpngvbaf va P:</p>
<pre><code>f(k)(k)(k)(k)...
</code></pre>
<p>Jung glcr fubhyq <code>f</code> unir?
Hasbeghangryl, P qbrf <em>abg</em> cebivqr n &ldquo;erphefvir glcr&rdquo;,
fhpu nf <code>glcrqrs s (*s)();</code>.
Fb, V hfrq n urniyl arfgrq shapgvba cbvagre glcr:</p>
<pre><code>glcrqrs ibvq *(*(*(*...(*(s))()...)())())
</code></pre>
<p>Guvf yvzvgf ubj znal nethzragf bar shapgvba pna or pbafrphgviryl nccyvrq gb.
Ohg lbh pna vapernfr gur ahzore ol gjrnxvat gur qrsvavgvba bs znpeb <code>c</code>.</p>
<h4>Pbqr qhcyvpngvba ol znpebf</h4>
<p>Arkg, jr arrq gb rapbqr &ldquo;pybfherf&rdquo;.
N pybfher vf n shapgvba gbtrgure jvgu na raivebazrag
juvpu vf n ersrerapr gb aba-ybpny inevnoyr.</p>
<p>Va guvf pnfr, jr arrq fbzrguvat gung:</p>
<ul>
<li>vf pnyynoyr vgfrys,</li>
<li>vagreanyyl cbffrffrf n ersrerapr gb nabgure pybfher nf n aba-ybpny inevnoyr, naq</li>
<li>nccyvrf gur vagreany pybfher gb na nethzrag jura vg vf pnyyrq.</li>
</ul>
<p>Ubjrire, ab glcr va P vf pnyynoyr naq unf n ersrerapr ng gur fnzr gvzr.
(Vg vf srnfvoyr ol qlanzvp pbqr trarengvba, ohg vg vf sne sebz cbegnoyr.)</p>
<p>Fb, V nqqerffrq guvf vffhr ol trarengvat znal shapgvba qrsvavgvbaf
fgngvpnyyl ol (no)hfvat znpebf:</p>
<pre><code>ibvq *k1; ibvq s1(ibvq *l) { erghea nccyl(k1, l); }
ibvq *k2; ibvq s2(ibvq *l) { erghea nccyl(k2, l); }
ibvq *k3; ibvq s3(ibvq *l) { erghea nccyl(k3, l); }
...
ibvq *(u[]) = { s1, s2, s3, ... }
</code></pre>
<p>naq ol nyybgvat rnpu bs gurz jura n pybfher vf arrqrq.</p>
<p>Guvf yrnqf gb nabgure yvzvgngvba:
gur ahzore bs cer-qrsvarq pybfherf yvzvgf
ubj znal vaqragvsvref (<code>F</code> <code>X</code> <code>V</code>) bar cebtenz pna hfr.
Ohg lbh pna vapernfr guvf ahzore
ol gjrnxvat gur qrsvavgvba bs znpeb <code>N</code> <code>O</code> <code>P</code> naq <code>Q</code>.
(Abgr gung pybfherf ner nyybggrq bayl jura cnefvat;
nsgre gur rinyhngvba fgnegf, &ldquo;bhg bs pybfher&rdquo; pnaabg bpphe.)</p>
<h4>Fubeg pbeqvat</h4>
<p>Guvf znetva vf gbb aneebj gb pbagnva n qrgnvyrq rkcynangvba.
Vafgrnq, V whfg nfx lbh bar dhrfgvba.
Pna lbh gryy jung <code>i f[]={0,0,f+6,f+2,f+4,f,f+3,f+5,f+1};</code> vf?
V sbhaq guvf ol hfvat FZG fbyire.</p>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+216
View File
@@ -0,0 +1,216 @@
# Most lazy SKIer
Yusuke Endoh
<mame@ruby-lang.org>
<https://github.com/mame/>
## Judges' comments:
### To build:
make
This builds endoh1, echo, hello, and tac.
### To run:
./endoh1 [file.lazy]
### Try:
./endoh1 hello.lazy
./hello
echo Hello | ./echo
./tac < endoh1.c
Be patient with the last one.
### Selected Judges Remarks:
We liked this entry because it can serve as a standalone program as well as an include file; and, as usual,
because its input data is at least as obfuscated as the program itself.
This entry can be considered an abuse of the GCC's optimizer; it takes GCC about 4x longer to compile it
with -O3 than without, compared to clang's 2x.
## Author's comments:
### Remarks
$ less prog.c
$ gcc -o prog prog.c
$ ./prog
... Isn't there any more to it?
Yes, of course.
This is a tool *for C programmers* to play the [SKI combinator calculus][1],
especially, [Lazy K][2].
This program will shine when it is used as a library.
For example, `hello.lazy` is a "Hello world" program written in Lazy K.
$ lazy hello.lazy
Hello, world!
where `lazy` is [a reference implementation of Lazy K][3].
At the same time, `hello.lazy` is *a valid C program* that uses `prog.c` as a library.
$ gcc -o hello -xc hello.lazy
$ ./hello
Hello, world!
In other words, this program is a kind of [polyglot][4].
The usage is simple:
you just have to wrap Lazy K program with `#include "prog.c"`.
Note that `#` is a comment in Lazy K.
[1]: http://en.wikipedia.org/wiki/SKI_combinator_calculus
[2]: redacted
[3]: redacted
[4]: http://en.wikipedia.org/wiki/Polyglot_%28computing%29
### Obfuscation
... is inherent in SKI combinator calculus :-)
In addition, it uses various hacks to parse SKI code as C,
and to satisfy IOCCC's size rule.
* Abuse of function pointers
* Code duplication by macros
* Short coding
These led to the good obfuscation.
See Spoiler section in detail, if you need.
### Limitation
This program supports only "Combinator-calculus style notation" of Lazy K.
"Unlambda style" and "Iota and Jot" style are not supported.
Also, it requires a space between identifiers.
In short, use `(S K)` instead of `(SK)`, "\`sk", `**i*i*i*ii*i*i*ii`,
or `11111100011100`.
Huge memory may be required to compile the program
(about 300 MB on my machine).
In addition, there are some limitations (and workarounds)
mentioned in Spoiler section.
But I think it wouldn't matter only when you run the attached programs.
### Portability
I confirmed that the program successfully worked
with the following compilers.
* gcc 4.6.3 [Linux, Mac OS X]
* clang 3.0 [Linux, Mac OS X]
* tcc 0.9.26 [Linux]
* N.B. tcc 0.9.25 seems to have a bug and fails to run it.
Recent compilers with `-Wall -W -Wextra -pedantic` say nothing.
gcc -Wall -W -Wextra -pedantic prog.c
clang -Wall -W -Wextra -pedantic prog.c
tcc -Wall -W -Wextra -pedantic prog.c
I think it will work on almost all platforms. I confirmed:
* Ubuntu Linux
* Mac OS X
* Raspberry PI
To check whether the program is specified on the command line
or included from another source file,
the program uses a predefined macro `__INCLUDE_LEVEL__`.
It is a gcc extention, and also supported by clang.
If your compiler does not support it,
you cannot use the program as a library.
But you can compile and run it as a standalone program, at least.
In fact, tcc does not support the macro, but does work.
### Spoiler (rot13)
Gur jubyr cebtenz vf vagrecergrq ol znpeb rkcnafvba.
Sbe rknzcyr, `F (X V)` vf genafyngrq gb n abezny P pbqr, `(f)((x)(v))`,
be fvzcyl `f(x(v))`.
Guvf rkcerffvba ergheaf na nofgenpg flagnk gerr,
naq `cebt.p` rinyhngrf vg.
Guvf cebtenz hfrf irel fvzcyr "grez erjevgvat" nccebnpu
sbe rinyhngvat FXV pbzovangbe pnyphyhf.
Gur erjevgvat ehyrf ner fubja va gur funcr bs gur pbqr.
#### Nohfr bs shapgvba cbvagref
Pbafvqre n frdhrapr bs shapgvba nccyvpngvbaf va P:
f(k)(k)(k)(k)...
Jung glcr fubhyq `f` unir?
Hasbeghangryl, P qbrf *abg* cebivqr n "erphefvir glcr",
fhpu nf `glcrqrs s (*s)();`.
Fb, V hfrq n urniyl arfgrq shapgvba cbvagre glcr:
glcrqrs ibvq *(*(*(*...(*(s))()...)())())
Guvf yvzvgf ubj znal nethzragf bar shapgvba pna or pbafrphgviryl nccyvrq gb.
Ohg lbh pna vapernfr gur ahzore ol gjrnxvat gur qrsvavgvba bs znpeb `c`.
#### Pbqr qhcyvpngvba ol znpebf
Arkg, jr arrq gb rapbqr "pybfherf".
N pybfher vf n shapgvba gbtrgure jvgu na raivebazrag
juvpu vf n ersrerapr gb aba-ybpny inevnoyr.
Va guvf pnfr, jr arrq fbzrguvat gung:
* vf pnyynoyr vgfrys,
* vagreanyyl cbffrffrf n ersrerapr gb nabgure pybfher nf n aba-ybpny inevnoyr, naq
* nccyvrf gur vagreany pybfher gb na nethzrag jura vg vf pnyyrq.
Ubjrire, ab glcr va P vf pnyynoyr naq unf n ersrerapr ng gur fnzr gvzr.
(Vg vf srnfvoyr ol qlanzvp pbqr trarengvba, ohg vg vf sne sebz cbegnoyr.)
Fb, V nqqerffrq guvf vffhr ol trarengvat znal shapgvba qrsvavgvbaf
fgngvpnyyl ol (no)hfvat znpebf:
ibvq *k1; ibvq s1(ibvq *l) { erghea nccyl(k1, l); }
ibvq *k2; ibvq s2(ibvq *l) { erghea nccyl(k2, l); }
ibvq *k3; ibvq s3(ibvq *l) { erghea nccyl(k3, l); }
...
ibvq *(u[]) = { s1, s2, s3, ... }
naq ol nyybgvat rnpu bs gurz jura n pybfher vf arrqrq.
Guvf yrnqf gb nabgure yvzvgngvba:
gur ahzore bs cer-qrsvarq pybfherf yvzvgf
ubj znal vaqragvsvref (`F` `X` `V`) bar cebtenz pna hfr.
Ohg lbh pna vapernfr guvf ahzore
ol gjrnxvat gur qrsvavgvba bs znpeb `N` `O` `P` naq `Q`.
(Abgr gung pybfherf ner nyybggrq bayl jura cnefvat;
nsgre gur rinyhngvba fgnegf, "bhg bs pybfher" pnaabg bpphe.)
#### Fubeg pbeqvat
Guvf znetva vf gbb aneebj gb pbagnva n qrgnvyrq rkcynangvba.
Vafgrnq, V whfg nfx lbh bar dhrfgvba.
Pna lbh gryy jung `i f[]={0,0,f+6,f+2,f+4,f,f+3,f+5,f+1};` vf?
V sbhaq guvf ol hfvat FZG fbyire.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+36
View File
@@ -0,0 +1,36 @@
/rot13
.s/rot13/click the text to rot13/
a
<span onclick="
function rot13(txt) {
var buf = '';
var intag = 0, inent = 0;
for (j = 0; j < txt.length; j++) {
var c = txt.charCodeAt(j);
if (intag) {
if (c == 62) intag = 0;
buf += String.fromCharCode(c);
} else if (c == 60) {
intag = 1;
buf += '<';
} else if (inent) {
if (c == 59) inent = 0;
buf += String.fromCharCode(c);
} else if (c == 38) {
inent = 1;
buf += '&';
} else if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) {
buf += String.fromCharCode((c<=90?90:122)>=(c+13)?c+13:c-13);
} else {
buf += String.fromCharCode(c);
}
}
return buf;
}
this.innerHTML=rot13(this.innerHTML);">
.
$
a
</span>
.
wq
+5
View File
@@ -0,0 +1,5 @@
#include "endoh1.c"
S(K(S I I(S(K(S(S(S I(K(K(K(K I)))))(K(K(S I I(S I I(S(S(K S)K)I))))))))(S(S(K S)(S(K(S(S(S I(K K))(K(K(K(K I)))))))(S(S(K S)(S(K K)(S I I)))(K(S I(K(K I)))))))(S(K(S(S(K S)(S(K(S I))(S S(S(S I(K K)))(K K))))))(S(K(S(K K)))(S(S(K S)(S(K K)(S I I)))(K(S(S(K S)(S(K(S I))(S(K K)(S(S I(K K))(K(K I))))))(S(K K)(S I(K(K I)))))))))))))(S(K(S I I(S(K(S(S(K S)(S(K(S(S I(K(K(K(K I)))))))K))))(S(S(K S)(S(K(S(K S)))(S(S(K S)(S(K K)(S(K S)(S(K K)(S I I)))))(K(S(K(S(S(K S)(S(K(S I))(S S(S I)(K K))))))(S(K K)K))))))(K(K(S I(K(K I)))))))(K K)))(S I I(S(K(S(S(K S)(S(K K)(S(K(S I I(S I I(S(S(K S)K)I))(S(K(S I))K)))(S(K K)(S(K(S(S(S I(K(K(K(K I)))))(K(K K)))(S(S(K S)(S(K(S I))K))(K(K(K K))))))(S I(K(K K))))))))))(S(K(S(K(S(S(S I(K K))(K(S(K(S I))K)))))))(S(K(S(K(S(K K)))))(S(S(K S)(S(K(S(K S)))(S(K(S(K(S(S(K(S I(K K)))(S(S(S I(K K))(K(S I(K(K I)))))(K(S(S(K S)K)I(S(S(K S)K)(S I I(S(S(K S)K)I))(S(K(S(S I(K(K I)))))K))(S(S I(K K))(K(S I I(S(K(S(K(S(S I(K(K I)))))K))(S I I)))))))))))))(S(K(S(S(K S)(S S(S(S(K S)(S(K K)(S(K S)(S(K(S I))(S(K K)(S I(K(S(S I(K(S(K(S(S(K S)K)I))(S(S(K S)K)(S I I(S(S(K S)K)I))))))(K(K K)))))))))))(K K)))))(S(K K)(S(S(K S)(S(K K)(S(S I I)(K I))))(K(S I(K(K I))))))))))(S(S(K S)(S(K(S(K S)))(S(S(K S)(S(K K)(S(K S)(S(K K)(S I I)))))(K(S(S(K S)(S(K K)(S(K S)K)))(K(S(S(K S)(S(K K)(S(K S)(S(K(S I))(S S(S I)(K K))))))(K K))))))))(K(K(S I(K(K I))))))))))I))
#include "endoh1.c"
+219
View File
@@ -0,0 +1,219 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall -W -Wno-empty-body
#CWARN= -Wall -W -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT} ${LIBS}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= endoh2
DATA=jpeg.jpg jpeg.c
ALT_OBJ=
ALT_ENTRY=jpeg
#################
# build the entry
#################
#
all: ${ENTRY} ${DATA}
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@
${ALT_ENTRY}: ${ALT_ENTRY}.c
${CC} ${CFLAGS} $< -o $@
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
jpeg.c: ${ENTRY}
${RM} -f $@
./${ENTRY} < ${ENTRY}.c > $@
jpeg.jpg: ${ALT_ENTRY}
${RM} -f $@
@echo This next step will take some time
./${ALT_ENTRY} > $@
check: ${DATA}
${RM} -f jpeg2.c
ruby ocr.rb jpeg.jpg > jpeg2.c
diff jpeg.c jpeg2.c && echo Check succeeded
###############
# utility rules
###############
#
everything: all alt check
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
+46
View File
@@ -0,0 +1,46 @@
/*@@@sssss8]][[[[a#@@sss0['w}8|v}a<{av}a@{av}j>~{v}j8|c[sa?|{8[|#~}
[j#@ra>~}sa!{>}|#r0l}sao8}[a'f8|r'8[j?x[?@<[j?@[j?@[s?>|;[[[j!>b'8'a@<cb@>?
c$kg_@<b#0pf<#keab{_b0|c0#d#0#|'o{i<!8dr,f_{#rg{baiderh{er0}|'{0{ic.df?'o|j{lim
0'{i?#c0b|c#kg!}r!8lp1g!|i_ar<[#0g|h_}ieg>|_ah|sr<|i[[[}s#f@}[{@u~~~r@[|#|{ssss{a
}|0~{?}|<{?}|qj?}s@[_}j0]][[[[a_@@@sssss<[[?>=sln5+a[so#,g-0aw;#*a>*abwa.*+da9=n?<6
-'7%71>e_?>a[j;e=;scdet?>shd??a;5&6:=[ch@aw[sf;[#<[[j>k7__?>>d>==n'6+7*abcdnh3a_jhw
b6;73;b#<ww<7bcw7d+;&i=cn?c>=#d5;8w3;nawn#<;;77__ra?8hi1abcww#>==<[;k7[wn7[=,>ab[a@s[
='b,.[8.?>>fdjn(_2$a8c8[[j_8.=B6+b8]]]]]]]]]j1;7_sj<[[af;7sjd][j_<7!=a>d7_j8d.ab[hybm
?>=;ei7aws1d!ebn _,?>0aka[#;5+7
!?ac;7_wa7{;a3_ bjcna>a<;bs8;7
j-=cabh?97_sj[' -5*j[!;5+a7[1wb[!wBb7w?0wb
_?an+&e_|j'4a<7 0v;7d.kd8wa?.=:a-wwm=:;[e5
*-=fwn7rab[c.j# eaw#c>>>bml;mtdekssae
zqtd[39<u_char* p=$,w[13997],*h=w,
*q,*r_****_;#in clude_*ioccc*2
013*_<stdio.h>_ *--2013-ioc
cc-2013-ioccc-2 013-- *_#define
@n(d);c ((d)>
>8);c (
d
);*B= 32;B[ y=1]=22 .627400; B[2]=16;_*-i occc-2013 -ioccc
-2013-io ccc-201 *_int@a,b,d,e,s,t ,g,z,y;double@f, B[3],i,j,k,l;void
@m(int@z){f or(j=k= l=y=1;y<99;y+=2+0) l*=z*z* .038553 ,k*=-y*(y+1),j+=l_
k;i*=j;}int@c( int@d){ return@ putchar (d)_255; }intmain (){for( ;*p;p++
)*p<33?0:(*h++=*p -32);q= h;for(p =w;p<w +823;p++)for(d=*p-56 ,e=-1+ 0;++e<(
d<00?5:d<6?d>4?160:30 :d>35?2 7<<(d-3 6):d_9* 6);q++)*q=d<0?*p>>e& 1:d<6|| q[d>35?
-108:d%9*-12-12];for(q=h ;g++<61 56;q++)* q?*q=*p- 4?e=*p+ +,e-32?e:0:r&&*r?g
%108<2?2:*r++:(r=r?p++:w, 2):0;n( g=8*8187)n(g+8)n(1 6)n(19014)n(18758) ;for(;s<10;s++)c(
s<3?s:0)n(g+3)n (67)for (;t<65;)c(t++>0) n(g-24)n(11)c(8 )n(612)n(656)n(
257)n(4352)n(g+ 0-20)n( 5*42);; for(;y ++<207;)c( y<3 1?y<19?
y>6:30-y:y<47?y <32||y>36? 16:0:y< 48?2:y%1 6*16+13-
y_16)n(64*960)n (g+5)n(4)n( 1)n(g+2 )n(8)n(257)n(0)n(
2*8064)for(;b<4 04096;b++ ){e=32< a?63-a:a;for(f
=d=t=s=0;e>t;)e
-=++t;e=t%2?e:t -e;;;for(d=a>3
1?e=7-e,14-t-e: t-e;s<64;t=f-=
i*B[!d+!e])z=b_ 64%82*8+s_8-4,
y=b_5248*8+s%8+7 ,i=z<0||z>647||
y%11>9?1:q[h[z_6+y_11*108]*60+y%11*6+z%6]*2-1,m(s_8*2*d+d),m(s++%8*2*e+e);s=2+t*t;;fo
r(d=2;s>3;s_=4)d*=2;;s=8<<(a?12:9);s-=d*2<<!!a*4;s|=t>0?t:t-1+d;c(s_256)?c(0):0;c(s)?
c(0):0;if(a++>62){n(g-8+b_64%8)a=0;}}n(g+1)return@0+0;}*/ /*IOCCC*/#include<stdio.h>
char*p,w[13997],*h=w,*q,*r;int d,e,g;int main(){for(;e<3583;e++>15&&e<3582&&d>32?*h
++=d-95?d:47:0)d=getchar();q=h;for(p=w;p<w+823;p++)for(d=*p-88,e=-1;++e<(d<0?5:d<
6?d>4?160:30:d>35?27<<(d-36):d/9*6);q++)*q=d<0?*p>>e&1:d<6||q[d>35?-108:d%9*-12
-12];for(q=h+108;g++<5995;)putchar(g%109<1?10:*q++?*p-36?(e=*p++)-64?e:32:r
/*IOCCC2013*/&&*r?g%109%108<2?34:*r++:(r=r?p++:w,34):32);return 0;}
+125
View File
@@ -0,0 +1,125 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Most recyclable</title>
</head>
<body>
<h1>Most recyclable</h1>
<p>Yusuke Endoh<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#109;&#97;&#109;&#x65;&#64;&#x72;&#x75;&#98;&#121;&#45;&#x6c;&#97;&#x6e;&#x67;&#x2e;&#x6f;&#x72;&#103;">&#x6d;&#97;&#109;&#x65;&#64;&#x72;&#117;&#98;&#x79;&#45;&#108;&#97;&#x6e;&#103;&#x2e;&#x6f;&#x72;&#x67;</a><br>
<a href="https://github.com/mame/">https://github.com/mame/</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make endoh2
</code></pre>
<h3>To run:</h3>
<pre><code> make all
</code></pre>
<p>You&rsquo;ll need to have Ruby installed to run all the automated check</p>
<pre><code>make check
</code></pre>
<h3>Try:</h3>
<pre><code>cat jpeg.c
</code></pre>
<p>Look at jpeg.jpg in an image viewer program.</p>
<h3>Selected Judges Remarks:</h3>
<p>This is a program which, when fed its own source, generates a program that almost is its whitespace inverse,
which, in its order, generates a JPEG file (speaking of file size abuse, that is about 16.4 times
larger than a PBM file with the same image, but the source was also abusing the size counting program&hellip;)</p>
<p>Don&rsquo;t pay attention to the OCR <del>behind the ruby curtain</del> &mdash; it&rsquo;s a straightforward bitmap comparison.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Highlights</h3>
<ul>
<li>LZ77-like compression for font and template data</li>
<li>tiny JPEG encoder
<ul>
<li>Zig-zag space-filling curve</li>
<li>Discrete cosine transform</li>
<li>JPEG Huffman encoding (cheeting)</li>
</ul>
</li>
</ul>
<h3>Notes</h3>
<p>I picked JPEG instead of PNG, GIF, or BMP
because it is the most difficult to generate.
I believe that the JPEG encoder is the world&rsquo;s smallest ever.
Nevertheless, the program was too big to meet the IOCCC&rsquo;s size rule.
So I created a smaller bootstrap program that generates the main program.
<code>prog.c</code> contains fragments of the main program <em>as a comment</em>
which <code>iocccsize -i</code> does <em>not</em> count.
I gratefully think the judges for spoiling the size rule this year.</p>
<p>I think the program will work on any major platforms and compilers.</p>
<h3>Legal</h3>
<p>This program uses (a part of) Proggy Tiny Fonts
which is distributed in MIT License:</p>
<pre><code>Copyright (c) 2004, 2005 Tristan Grimmer
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</code></pre>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+90
View File
@@ -0,0 +1,90 @@
# Most recyclable
Yusuke Endoh
<mame@ruby-lang.org>
<https://github.com/mame/>
## Judges' comments:
### To build:
make endoh2
### To run:
make all
You'll need to have Ruby installed to run all the automated check
make check
### Try:
cat jpeg.c
Look at jpeg.jpg in an image viewer program.
### Selected Judges Remarks:
This is a program which, when fed its own source, generates a program that almost is its whitespace inverse,
which, in its order, generates a JPEG file (speaking of file size abuse, that is about 16.4 times
larger than a PBM file with the same image, but the source was also abusing the size counting program...)
Don't pay attention to the OCR ~~behind the ruby curtain~~ --- it's a straightforward bitmap comparison.
## Author's comments:
### Highlights
* LZ77-like compression for font and template data
* tiny JPEG encoder
* Zig-zag space-filling curve
* Discrete cosine transform
* JPEG Huffman encoding (cheeting)
### Notes
I picked JPEG instead of PNG, GIF, or BMP
because it is the most difficult to generate.
I believe that the JPEG encoder is the world's smallest ever.
Nevertheless, the program was too big to meet the IOCCC's size rule.
So I created a smaller bootstrap program that generates the main program.
`prog.c` contains fragments of the main program *as a comment*
which `iocccsize -i` does *not* count.
I gratefully think the judges for spoiling the size rule this year.
I think the program will work on any major platforms and compilers.
### Legal
This program uses (a part of) Proggy Tiny Fonts
which is distributed in MIT License:
Copyright (c) 2004, 2005 Tristan Grimmer
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+43
View File
@@ -0,0 +1,43 @@
Font = {
0x000000000000000 => 32, 0x008208208008000 => 33, 0x514500000000000 => 34,
0x00053e514f94000 => 35, 0x0087a870af08000 => 36, 0x00046a50a562000 => 37,
0x01892462589d000 => 38, 0x208200000000000 => 39, 0x108410410408100 => 40,
0x408104104108400 => 41, 0x00022a72a200000 => 42, 0x000208f88200000 => 43,
0x000000000008400 => 44, 0x000000f80000000 => 45, 0x000000000008000 => 46,
0x082104208410800 => 47, 0x01c8a2aa289c000 => 48, 0x00860820821c000 => 49,
0x01c88231083e000 => 50, 0x01c88230289c000 => 51, 0x00431493e104000 => 52,
0x03e820f0289c000 => 53, 0x00c420f2289c000 => 54, 0x03e084108210000 => 55,
0x01c8a272289c000 => 56, 0x01c8a2782118000 => 57, 0x000008000200000 => 58,
0x000008000210000 => 59, 0x00008cc0c080000 => 60, 0x00003e03e000000 => 61,
0x000818198800000 => 62, 0x01c882108008000 => 63, 0x01e86db6f81f000 => 64,
0x00821451c8a2000 => 65, 0x03c8a2f228bc000 => 66, 0x01c8a082089c000 => 67,
0x0389228a2938000 => 68, 0x03e820f2083e000 => 69, 0x03e820f20820000 => 70,
0x01c8a09a289e000 => 71, 0x0228a2fa28a2000 => 72, 0x01c20820821c000 => 73,
0x00e0820820bc000 => 74, 0x022928c28922000 => 75, 0x02082082083e000 => 76,
0x0228b6daaaa2000 => 77, 0x032caaaaa9a6000 => 78, 0x01c8a28a289c000 => 79,
0x03c8a2f20820000 => 80, 0x01c8a28a299e000 => 81, 0x03c8a2f228a2000 => 82,
0x01c8a070289c000 => 83, 0x03e208208208000 => 84, 0x0228a28a289c000 => 85,
0x0228a2514208000 => 86, 0x022aaaa94514000 => 87, 0x0228942148a2000 => 88,
0x0228a2708208000 => 89, 0x03e08421083e000 => 90, 0x710410410410700 => 91,
0x820410208104080 => 92, 0x704104104104700 => 93, 0x008522000000000 => 94,
0x000000000000fc0 => 95, 0x008100000000000 => 96, 0x00001c09e89e000 => 97,
0x82083c8a28bc000 => 98, 0x00001e82081e000 => 99, 0x08209e8a289e000 => 100,
0x00001c8be81e000 => 101, 0x39043c410410000 => 102, 0x00001c8a289e09c => 103,
0x82083c8a28a2000 => 104, 0x008018208208000 => 105, 0x00400c104104138 => 106,
0x410412518512000 => 107, 0x608208208208000 => 108, 0x000034aaaaaa000 => 109,
0x00003c8a28a2000 => 110, 0x00001c8a289c000 => 111, 0x00003c8a28bc820 => 112,
0x00001e8a289e082 => 113, 0x00002cca0820000 => 114, 0x00001e81c0bc000 => 115,
0x01041c41040e000 => 116, 0x0000228a289e000 => 117, 0x000022894508000 => 118,
0x000022aaa514000 => 119, 0x000022508522000 => 120, 0x0000228a289e09c => 121,
0x00003e10843e000 => 122, 0x108208408208100 => 123, 0x208208208208200 => 124,
0x408208108208400 => 125, 0x000000666000000 => 126
}
field = IO.popen("convert #{ ARGV[0] } gray:-") {|f| f.read }
field = field.unpack("C*").map {|n| n >= 0x80 ? 1 : 0 }.each_slice(656).to_a
55.times do |y|
108.times do |x|
print Font[(0..9).map {|j| field[y*11+j+4][x*6+4,6] }.join.to_i(2)].chr
end
puts
end
+202
View File
@@ -0,0 +1,202 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall -Wno-implicit-int -Wno-main -Wno-implicit-function-declaration
#CWARN= -Wall -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} -include stdio.h ${CSTD} ${ARCH} ${OPT}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= endoh3
DATA=
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} ${DATA}
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
+1
View File
@@ -0,0 +1 @@
char a;float b,c;main(d){for(;d>2e3*c?c=1,scanf(" %c%f",&a,&c),d=55-a%32*9/5,b=d>9,d=d%13-a/32*12:1;a=2)++d<24?b*=89/84.:putchar(a=b*d);}
+2
View File
@@ -0,0 +1,2 @@
dc Fzfzfzdc Fzfzfzdc FzfzDzfz Czezez
dc Czezezdc Czezezdc CzezDzez Fzfzfz
+242
View File
@@ -0,0 +1,242 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Most tweetable 1-liner</title>
</head>
<body>
<h1>Most tweetable 1-liner</h1>
<p>Yusuke Endoh<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#109;&#97;&#109;&#x65;&#64;&#x72;&#x75;&#98;&#121;&#45;&#x6c;&#97;&#x6e;&#x67;&#x2e;&#x6f;&#x72;&#103;">&#x6d;&#97;&#109;&#x65;&#64;&#x72;&#117;&#98;&#x79;&#45;&#108;&#97;&#x6e;&#103;&#x2e;&#x6f;&#x72;&#x67;</a><br>
<a href="https://github.com/mame/">https://github.com/mame/</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make endoh3
</code></pre>
<h3>To run:</h3>
<pre><code>./endoh3
</code></pre>
<h3>Try:</h3>
<p>Trying this out will depend on how your system can play sounds. The author&rsquo;s
remarks include some options for different operating systems.</p>
<p>The simplest way is to create a .wav file and have your system play that.</p>
<pre><code>echo 'CDEFGABc' | ./endoh3 | ruby wavify.rb &gt; cde.wav
</code></pre>
<p>There are also some other musical samples, twinkle.abc and menuet.abc.</p>
<h3>Selected Judges Remarks:</h3>
<p>This program can tweet out a tune and is small enough to tweet.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Remarks</h3>
<p>This is a sound synthesizer for a subset of <a href="http://en.wikipedia.org/wiki/ABC_notation">ABC music notation</a>.</p>
<p>Try:</p>
<pre><code>gcc -o prog prog.c
echo "CDEFGABc" | ./prog &gt; /dev/dsp
</code></pre>
<p>If <code>/dev/dsp</code> is not available on your system, use an OSS sound wrapper such
as <code>padsp</code> or <code>aoss</code>:</p>
<pre><code>echo "CDEFGABc" | ./prog | padsp tee /dev/dsp &gt; /dev/null
</code></pre>
<p>If you are using Mac OS X, try <a href="http://sox.sourceforge.net/">sox</a>:</p>
<pre><code>echo "CDEFGABc" | ./prog | sox -q -traw -r8000 -b8 -e unsigned-integer - -tcoreaudio
</code></pre>
<p>If they do not work, use the attached script to convert the output
into a wave file format:</p>
<pre><code>echo "CDEFGABc" | ./prog | ruby wavify.rb &gt; cde.wav
</code></pre>
<p>and play <code>cde.wav</code>.</p>
<p>You can enjoy some music scores that I attached:</p>
<pre><code>cat twinkle.abc | ./prog &gt; /dev/dsp
cat menuet.abc | ./prog &gt; /dev/dsp
</code></pre>
<h3>Obfuscation</h3>
<p>The following sequence of questions may be helpful to understand the program.</p>
<ul>
<li>How does it convert ABC notes into the frequency?</li>
<li>What is <code>89/84.</code>? I found it by using Stern-Brocot tree.</li>
<li>How does it generate a wave? Hint: it generates a saw wave.</li>
</ul>
<h3>Limitation</h3>
<p>The following features are supported:</p>
<ul>
<li>Notes:
<ul>
<li><code>C</code> <code>D</code> <code>E</code> <code>F</code> <code>G</code> <code>A</code> <code>B</code> (in low octave)</li>
<li><code>c</code> <code>d</code> <code>e</code> <code>f</code> <code>g</code> <code>a</code> <code>b</code> (in high octave)</li>
</ul>
</li>
<li>Rests: <code>z</code></li>
<li>Note lengths:
<ul>
<li><code>A</code> (an eighth note)</li>
<li><code>A2</code> (a quarter note)</li>
<li><code>A3</code> (a dotted quarter note)</li>
<li><code>A4</code> (a half note)</li>
</ul>
</li>
</ul>
<p>The following features are <em>not</em> supported:</p>
<ul>
<li>Sharp and flat: <code>^C</code> <code>_C</code>
<ul>
<li>But it is possible to emit the half tones. Do you see how?</li>
</ul>
</li>
<li>Shorter note lengths than 1: <code>C1/2</code>
<ul>
<li>But you can use <code>C0.5</code> instead.</li>
</ul>
</li>
<li>Higher and lower notes: <code>c'</code> <code>C,</code></li>
<li>Any meta fields: <code>T:title</code> <code>L:1/4</code></li>
<li>Bar line, repeat, ties and slurs, and everything else.</li>
</ul>
<h3>Known Bugs</h3>
<p>You can <em>not</em> write a note length immediately followed by a note <code>E</code>,
such as <code>C2E2</code>.
Can you know why?
You can work it around by inserting a whitespace: <code>C2 E2</code>.</p>
<h3>Portability</h3>
<p>I tested it on:</p>
<ul>
<li>Ubuntu 13.10 with gcc 4.7.3, clang 3.2, and tcc 0.9.25.</li>
<li>Mac OS X 10.6 with gcc 4.2.1 and clang 1.7.</li>
</ul>
<h3>Legal</h3>
<p>I believe that all the scores that I attached are out-of-copyright.</p>
<p>I did write a score of the Happy Birthday song too.
(It does not matter because the song is out-of-copyright in my country.)
But I do not attach it to protect you from W****r.</p>
<p>For the same reason, do not play a score that contains only <code>z1092</code>.
You know, it is <a href="http://en.wikipedia.org/wiki/4%E2%80%B233%E2%80%B3">&ldquo;the famous song&rdquo;</a>.</p>
<h3>Spoiler (rot13)</h3>
<p>Urer vf n zntvpny rkcerffvba juvpu V sbhaq ol oehgr-sbepr:</p>
<pre><code>(p % 32 + 5) * 9 / 5 % 13 + a / 32 * 12 - 22
</code></pre>
<p>Vagrerfgvatyl, vg pbairegf na NFPVV ahzore bs NOP abgrf
gb gur pbeerfcbaqvat gbar ahzore.</p>
<pre><code>'P' (NFPVV 67) =&gt; 3
'Q' (NFPVV 68) =&gt; 5
'R' (NFPVV 69) =&gt; 7
'S' (NFPVV 70) =&gt; 9
'T' (NFPVV 71) =&gt; 10
'N' (NFPVV 65) =&gt; 12
'O' (NFPVV 66) =&gt; 14
'p' (NFPVV 99) =&gt; 15
'q' (NFPVV 100) =&gt; 17
'r' (NFPVV 101) =&gt; 19
's' (NFPVV 102) =&gt; 20
't' (NFPVV 103) =&gt; 22
'n' (NFPVV 97) =&gt; 24
'o' (NFPVV 98) =&gt; 26
</code></pre>
<p>Ol gur jnl, lbh pna jevgr n unys-gbar ol gur sbyybjvat punenpgref.</p>
<pre><code>'X' =&gt; 4 (= P#)
'Y' =&gt; 6 (= Q#)
'H' =&gt; 8 (= S#)
'I' =&gt; 11 (= T#)
'C' =&gt; 13 (= N#)
</code></pre>
<p>Abgr gung gur gbar ahzoref fvzcyl rahzrengr gur frzv-gbar fgrcf.
Fb jr pna pnyphyngr gur serdhrapl rnfvyl: <code>cbj(2, a / 12.0)</code>.
Gura, ubj pna jr pnyphyngr <code>cbj</code> jvgubhg <code>zngu.u</code>?
<code>cbj(2, 1.0 / 12.0)</code> vf nccebkvzngrq ol <code>89/84.</code>.
(V sbhaq guvf nccebkvzngvba ol hfvat <a href="uggc://ra.jvxvcrqvn.bet/jvxv/Fgrea%R2%80%93Oebpbg_gerr">Fgrea-Oebpbg gerr</a>.)
Jr pna tnva gur serdhrapl ol zhygvcylvat gur inyhr <code>a</code> gvzrf.</p>
<p>Svanyyl, gur sbyybjvat pbqr trarengrf n fnj jnir:</p>
<pre><code>sbe(p = 0; p &lt; yra; p++) chgpune(n = a * Q);
</code></pre>
<p>jurer <code>Q</code> vf n serdhrapl naq <code>n</code> vf n inevnoyr jubfr glcr vf pune.
Ol nffvtavat sybng gb pune inevnoyr, gur vzcyvpvg glcr pbairegvba vf cresbezrq sebz sybng gb pune (zbqhyb 256).
(Fgevpgyl fcrnxvat, guvf orunivbe vf haqrsvarq nppbeqvat gb 6.3.1.4 va P99;
lbh pna ercynpr vg jvgu <code>(ybat)(a*Q)</code> vs lbh ner crqnagvp.)</p>
<p>Nyy gung jnf yrsg jnf gb pbzovar naq pbaqrafr gur pbzcbaragf.
Gur xrl vf fdhnfuvat gurz vagb whfg bar sbe-ybbc.</p>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+180
View File
@@ -0,0 +1,180 @@
# Most tweetable 1-liner
Yusuke Endoh
<mame@ruby-lang.org>
<https://github.com/mame/>
## Judges' comments:
### To build:
make endoh3
### To run:
./endoh3
### Try:
Trying this out will depend on how your system can play sounds. The author's
remarks include some options for different operating systems.
The simplest way is to create a .wav file and have your system play that.
echo 'CDEFGABc' | ./endoh3 | ruby wavify.rb > cde.wav
There are also some other musical samples, twinkle.abc and menuet.abc.
### Selected Judges Remarks:
This program can tweet out a tune and is small enough to tweet.
## Author's comments:
### Remarks
This is a sound synthesizer for a subset of [ABC music notation](http://en.wikipedia.org/wiki/ABC_notation).
Try:
gcc -o prog prog.c
echo "CDEFGABc" | ./prog > /dev/dsp
If `/dev/dsp` is not available on your system, use an OSS sound wrapper such
as `padsp` or `aoss`:
echo "CDEFGABc" | ./prog | padsp tee /dev/dsp > /dev/null
If you are using Mac OS X, try [sox](http://sox.sourceforge.net/):
echo "CDEFGABc" | ./prog | sox -q -traw -r8000 -b8 -e unsigned-integer - -tcoreaudio
If they do not work, use the attached script to convert the output
into a wave file format:
echo "CDEFGABc" | ./prog | ruby wavify.rb > cde.wav
and play `cde.wav`.
You can enjoy some music scores that I attached:
cat twinkle.abc | ./prog > /dev/dsp
cat menuet.abc | ./prog > /dev/dsp
### Obfuscation
The following sequence of questions may be helpful to understand the program.
- How does it convert ABC notes into the frequency?
- What is `89/84.`? I found it by using Stern-Brocot tree.
- How does it generate a wave? Hint: it generates a saw wave.
### Limitation
The following features are supported:
- Notes:
- `C` `D` `E` `F` `G` `A` `B` (in low octave)
- `c` `d` `e` `f` `g` `a` `b` (in high octave)
- Rests: `z`
- Note lengths:
- `A` (an eighth note)
- `A2` (a quarter note)
- `A3` (a dotted quarter note)
- `A4` (a half note)
The following features are *not* supported:
- Sharp and flat: `^C` `_C`
- But it is possible to emit the half tones. Do you see how?
- Shorter note lengths than 1: `C1/2`
- But you can use `C0.5` instead.
- Higher and lower notes: `c'` `C,`
- Any meta fields: `T:title` `L:1/4`
- Bar line, repeat, ties and slurs, and everything else.
### Known Bugs
You can *not* write a note length immediately followed by a note `E`,
such as `C2E2`.
Can you know why?
You can work it around by inserting a whitespace: `C2 E2`.
### Portability
I tested it on:
* Ubuntu 13.10 with gcc 4.7.3, clang 3.2, and tcc 0.9.25.
* Mac OS X 10.6 with gcc 4.2.1 and clang 1.7.
### Legal
I believe that all the scores that I attached are out-of-copyright.
I did write a score of the Happy Birthday song too.
(It does not matter because the song is out-of-copyright in my country.)
But I do not attach it to protect you from W\*\*\*\*r.
For the same reason, do not play a score that contains only `z1092`.
You know, it is ["the famous song"](http://en.wikipedia.org/wiki/4%E2%80%B233%E2%80%B3).
### Spoiler (rot13)
Urer vf n zntvpny rkcerffvba juvpu V sbhaq ol oehgr-sbepr:
(p % 32 + 5) * 9 / 5 % 13 + a / 32 * 12 - 22
Vagrerfgvatyl, vg pbairegf na NFPVV ahzore bs NOP abgrf
gb gur pbeerfcbaqvat gbar ahzore.
'P' (NFPVV 67) => 3
'Q' (NFPVV 68) => 5
'R' (NFPVV 69) => 7
'S' (NFPVV 70) => 9
'T' (NFPVV 71) => 10
'N' (NFPVV 65) => 12
'O' (NFPVV 66) => 14
'p' (NFPVV 99) => 15
'q' (NFPVV 100) => 17
'r' (NFPVV 101) => 19
's' (NFPVV 102) => 20
't' (NFPVV 103) => 22
'n' (NFPVV 97) => 24
'o' (NFPVV 98) => 26
Ol gur jnl, lbh pna jevgr n unys-gbar ol gur sbyybjvat punenpgref.
'X' => 4 (= P#)
'Y' => 6 (= Q#)
'H' => 8 (= S#)
'I' => 11 (= T#)
'C' => 13 (= N#)
Abgr gung gur gbar ahzoref fvzcyl rahzrengr gur frzv-gbar fgrcf.
Fb jr pna pnyphyngr gur serdhrapl rnfvyl: `cbj(2, a / 12.0)`.
Gura, ubj pna jr pnyphyngr `cbj` jvgubhg `zngu.u`?
`cbj(2, 1.0 / 12.0)` vf nccebkvzngrq ol `89/84.`.
(V sbhaq guvf nccebkvzngvba ol hfvat [Fgrea-Oebpbg gerr](uggc://ra.jvxvcrqvn.bet/jvxv/Fgrea%R2%80%93Oebpbg_gerr).)
Jr pna tnva gur serdhrapl ol zhygvcylvat gur inyhr `a` gvzrf.
Svanyyl, gur sbyybjvat pbqr trarengrf n fnj jnir:
sbe(p = 0; p < yra; p++) chgpune(n = a * Q);
jurer `Q` vf n serdhrapl naq `n` vf n inevnoyr jubfr glcr vf pune.
Ol nffvtavat sybng gb pune inevnoyr, gur vzcyvpvg glcr pbairegvba vf cresbezrq sebz sybng gb pune (zbqhyb 256).
(Fgevpgyl fcrnxvat, guvf orunivbe vf haqrsvarq nppbeqvat gb 6.3.1.4 va P99;
lbh pna ercynpr vg jvgu `(ybat)(a*Q)` vs lbh ner crqnagvp.)
Nyy gung jnf yrsg jnf gb pbzovar naq pbaqrafr gur pbzcbaragf.
Gur xrl vf fdhnfuvat gurz vagb whfg bar sbe-ybbc.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+29
View File
@@ -0,0 +1,29 @@
d2GABc d2GzGz
e2cdeu g2GzGz
c2dcBA B2cBAG
U2GABG B2A4
d2GABc d2GzGz
e2cdeu g2GzGz
c2dcBA B2cBAG
A2BAGU G6
b2gabg a2deud
g2 eugd k2BkA2
ABkdeu g2u2 e2
u2A2k2 d6
d2GUG2 e2GUG2
d2ccB2 AGUGA2
DEUGAB c2B2A2
BdG2U2 G6
b2gabg a2deud
g2 eugd k2BkA2
ABkdeu g2u2 e2
u2A2k2 d6
d2GUG2 e2GUG2
d2ccB2 AGUGA2
DEUGAB ccBBA2
BdG2U2 G6
+2
View File
@@ -0,0 +1,2 @@
CzDzEzFzGzAzBzcz
CKDLEFUGVAPBckdlefugvapb
+6
View File
@@ -0,0 +1,6 @@
CzCzGzGzAzAzG3z
FzFzEzEzDzDzC3z
GzGzFzFzEzEzD3z
GzGzFzFzEzEzD3z
CzCzGzGzAzAzG3z
FzFzEzEzDzDzC3z
+3
View File
@@ -0,0 +1,3 @@
$<.binmode
s=$<.read+"\0"*8000
$><<["RIFF",s.size+36,"WAVEfmt ",16,1,1,8000,8000,1,8,"data",s.size,s].pack("A4VA8VvvVVvvA4VA*")
+4
View File
@@ -0,0 +1,4 @@
czczdzezczezdzGzczczdzezc4BzGz
czczdzezfzezdzczBzGzAzBzc3zcz3
A3BAzGzAzBzc4G3AGzFzEzFzG4
A3BAzGzAzBzczAzGzczBzdzc3zc
+205
View File
@@ -0,0 +1,205 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall
#CWARN= -Wall -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= endoh4
DATA= solids.tbz2
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} data
@${TRUE}
${ENTRY}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
${RM} -rf solids
@echo extracting solids
${TAR} -jxf ${DATA}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${ALT_ENTRY}
${RM} -rf solids
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
+8
View File
@@ -0,0 +1,8 @@
1,1,1
1,1,-1
1,-1,1
1,-1,-1
-1,1,1
-1,1,-1
-1,-1,1
-1,-1,-1
+72
View File
@@ -0,0 +1,72 @@
int
**F,**
V,M, N,i;
#ifndef/**/S
#define S 70,23
#endif/* 000-2E5*/
#define/* 2E5-2E5,2E5
*/_POSIX_C_SOURCE 199309
#include/* 2E5XXX*/<time.h>
/* 2E5-2E5X*/#include<stdio.h>
#include<stdlib.h>/* -2E5-2E5XX*/
struct timespec R={0,1E6};int j,k,m,
#define U/* -2E5X*/rand()*2./RAND_MAX-1
#define/* 2E5*/O(p,q,i)(P[p*3+i]-P[q*3+i])
/* IOCCC2013 IOCCC2013*/#define B(p,q,\
r)(O(q,p,0)*O(r,p,1)-O(q,p,1)*O(r,p, 0))
#define A(t,n)( t*)malloc( sizeof (t)*n)
#define E(p,q,r,s)B(p,q,r)*O(s ,p,2)+B(\
p,r,s)*O(q,p,2)+B(p,s,q)*O( /*XX*/r,p,2)
#define D(e,f)(c-a)?s=a, a=e,e=s,s=f,f=\
d,d=s:0;u=a+.5;m=u+1; T[01]=91;T[2]=060;
#define C (Q[u]-X) *a+(Q[u+1]-Y)*b+(Q[u\
+2]-Z)*c,g=e*c- f*b,h=f*a-d*c,f=c,c=d*b\
-e*a,d=a,a=g ,e=b,b=h,P[k]=W/2-q/s/p*3*\
W,P[k+1]= H/2+r/s/p*H/2,T[3]=0x48,*T=033
n,u,v, w,t,W,H;double*P,*Q,I,J,K,L,x,y,z
,X, Y,Z,a,b,c,d,e,f,g,h,p,q,r,s ;void o(
double x){for(p=q=i=0,s=r=1;i<99;s=(s+x
/s)/2)i%2?q+=r,r=-r:(p+=r),r*=3.14*x/++i;}
int G(int p,int q,int s,int g,int f){i\
nt* v=A(int,N),*a,*b,h=-1,r=h;for(F[f]=V
[f]=v; ++h<f;)if(V[h][p]==q){if(s+1&&E(p
,q,V[h][q ],s)<1E-4){for(a=F[g],b=F[h];N
>++r;v[r]=q+ 1?a[q]-r?q:b[p]-r?p:-1:p)p=
a[r],q=b[r];for (r=0;r<f;r++)F[r]==a||F[
r]==b?F[r]=v:0;};; return f;}for(h=0;h<N
;v[h++]=-1)r=h-p&&h-q &&(r<0||E(p,q,r,h)
<0)?h:r;v[v[v[p]=q]=r]=p ;return G(r,q,p
,f,G(p,r,q,f,G(p,q,s,g,f+1) ));}char *T;
int main(void) {H=(W=S)*2;T=A( char,(H*W
+4));for(srand(t=(int)time(0));i= scanf(
"%lf,",P=(Q=(double*)realloc(Q,(N+1) *s\
izeof(double)))+N),i>=0;)i?c+=*P**P,1<N
++%3?o(c),b=b<s?s:b,c=0:0:scanf("%*s");for
(P=A(double,N*2);j<N;)Q[j++]/=b;o(U);I=
p/1E3;J=q/1E3;K=U;L=U;N/=3;F=A(int*, 4*N
);V=F+2*N;for(;u==v;){for(j=u=m=n =0;j<3
*N;j++)P[j]=Q[j]+(U)/1E5;for(; m<N;m++)u
=P[u*3]>P[m*3]?m:u;for(v=!u ;n<N;n++)v=B
(u,v,n)>0?n:v;}for(puts( "\x1b[2J"),M=G(
u,v,-1,-1,0);;K+=I+0, L+=J){for(i=4;i<W*
H/2+3;T[++i]=j=0)T [i]=i%W-3?32:10;for(;
j<M;j++){for(n= k=0;F[j][m=n]<0;)n++;for
(;u=F[j][m]* 3,o(K=K<-1?K+2:K>1?K-2:K),c
=z=9*p,b= 9*q,o(L=L<-1?L+2:L>1?L-2:L),a=
x=b*q, y=b*=p,d=x-X,e=y-Y,f=z-Z,o(d*d+e*
e+f *f),p=C,q=C,r=C,k+=2,m=F[j][m],m-n;)
;for(p=n=0;n<k;n+=2)p+=P[n]*(P[(n+3)%k]
-P[(n+k-1)%k]);for(q=time(0)<t+3;(q||p>=0)
&&n;){a=P[n%k];b=P[n%k+1];c=P[n-=2];d=P
[n+1];e=d-b;i=e*e>(c-a)*D(b,c)0>D(c,
b)for(;c-a&&u<c+.5;0<=w&&w<W-1&&0
<=m&&m<H?v=m/2*W+w+4,T[v]="',"
";;;,;'"[T[v]%8^m%2]:0)m=v=
(d-b)*(u-a)/(c-a)+b+0.5,
w=i?m=u++,v:u++,u=u<c
&&q?c+0.5:u;}}puts
(T);nanosleep(&
R,0);X=x;Y=y
;Z=z;}}/*
IOCCC*
\*/
+150
View File
@@ -0,0 +1,150 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Most solid</title>
</head>
<body>
<h1>Most solid</h1>
<p>Yusuke Endoh<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#109;&#97;&#109;&#x65;&#64;&#x72;&#x75;&#98;&#121;&#45;&#x6c;&#97;&#x6e;&#x67;&#x2e;&#x6f;&#x72;&#103;">&#x6d;&#97;&#109;&#x65;&#64;&#x72;&#117;&#98;&#x79;&#45;&#108;&#97;&#x6e;&#103;&#x2e;&#x6f;&#x72;&#x67;</a><br>
<a href="https://github.com/mame/">https://github.com/mame/</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make endoh4
</code></pre>
<h3>To run:</h3>
<pre><code>./endoh4
</code></pre>
<h3>Try:</h3>
<p>NOTE: The author recommends the use of xterm.</p>
<pre><code>./endoh4 &lt; cube.txt
</code></pre>
<p>For example, if you are a soccer fan, try:</p>
<pre><code>make all
./endoh4 &lt; solids/archimedian-solid/a11-truncated-icosahedron.txt
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This program is formatted as the net for a tetrahedron. (hint, try feeding the
program it&rsquo;s own source code). When it runs there is an animation for the
computation to work out the convex hull.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Spec</h3>
<p>This is a convex polyhedron viewer, which:</p>
<ol>
<li>reads three-dimentional vertices (3N float values) from stdin,</li>
<li>calculates a convex hull of them, and</li>
<li>renders it.</li>
</ol>
<p>This simple spec involves many details.</p>
<ul>
<li>3D convex hull calculation
<ul>
<li>recursive gift wrapping algorithm</li>
<li>automatical merging of (almost) co-planar faces
(i.e., faces are not triangulated)</li>
<li>random perturbation for robustness</li>
</ul>
</li>
<li>3D rendering
<ul>
<li>perspective projection</li>
<li>ASCII line drawing: <code>"',;;;,;'"</code></li>
<li>camera in a spherical spiral orbit</li>
</ul>
</li>
</ul>
<p>(Note that this program does not use <code>math.h</code>.)</p>
<h3>Portability</h3>
<p>I think it conforms with both C89 and C99.
I confirmed that it worked on gcc, clang, and tcc.
It should not be warned with -pedantic and -Wextra.</p>
<h3>Tips</h3>
<p>You may want to use <code>tput</code> to hide a terminal cursor.</p>
<pre><code>tput civis
./endoh4 &lt; cube.txt
tput cnorm
</code></pre>
<h3>Bonuses</h3>
<p>You can change the screen size. Let the aspect ratio be about 3:1.</p>
<pre><code>gcc -DS=120,40 -o endoh4 endoh4.c
</code></pre>
<p>The shape of this code is the geometric net of a regular tetrahedron.
So, try:</p>
<pre><code>./endoh4 &lt; endoh4.c
</code></pre>
<p>The solids.tbz2 file includes various solid data:
<a href="http://en.wikipedia.org/wiki/Platonic_solid">Platonic solids</a>,
<a href="http://en.wikipedia.org/wiki/Archimedean_solid">Archimedean solids</a>,
<a href="http://en.wikipedia.org/wiki/Prism_%28geometry%29">Prisms</a>,
<a href="http://en.wikipedia.org/wiki/Antiprism">Antiprisms</a>,
<a href="http://en.wikipedia.org/wiki/Bipyramid">Bipyramids</a>,
<a href="http://en.wikipedia.org/wiki/Trapezohedron">Trapezohedrons</a>, and
<a href="http://en.wikipedia.org/wiki/Johnson_solid">Johnson solids</a>.</p>
<p>I created the files by using the POV-Ray scripts
(<a href="http://en.wikipedia.org/wiki/File:Poly.pov">1</a> and
<a href="http://en.wikipedia.org/wiki/User:AndrewKepert/poly.pov">2</a>)
in Wikipedia.
They are copyrighted in CC BY-SA 3.0
by &ldquo;User:Cyp&rdquo; and &ldquo;User:AndrewKepert&rdquo;.</p>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+105
View File
@@ -0,0 +1,105 @@
# Most solid
Yusuke Endoh
<mame@ruby-lang.org>
<https://github.com/mame/>
## Judges' comments:
### To build:
make endoh4
### To run:
./endoh4
### Try:
NOTE: The author recommends the use of xterm.
./endoh4 < cube.txt
For example, if you are a soccer fan, try:
make all
./endoh4 < solids/archimedian-solid/a11-truncated-icosahedron.txt
### Selected Judges Remarks:
This program is formatted as the net for a tetrahedron. (hint, try feeding the
program it's own source code). When it runs there is an animation for the
computation to work out the convex hull.
## Author's comments:
### Spec
This is a convex polyhedron viewer, which:
1. reads three-dimentional vertices (3N float values) from stdin,
2. calculates a convex hull of them, and
3. renders it.
This simple spec involves many details.
* 3D convex hull calculation
* recursive gift wrapping algorithm
* automatical merging of (almost) co-planar faces
(i.e., faces are not triangulated)
* random perturbation for robustness
* 3D rendering
* perspective projection
* ASCII line drawing: `"',;;;,;'"`
* camera in a spherical spiral orbit
(Note that this program does not use `math.h`.)
### Portability
I think it conforms with both C89 and C99.
I confirmed that it worked on gcc, clang, and tcc.
It should not be warned with -pedantic and -Wextra.
### Tips
You may want to use `tput` to hide a terminal cursor.
tput civis
./endoh4 < cube.txt
tput cnorm
### Bonuses
You can change the screen size. Let the aspect ratio be about 3:1.
gcc -DS=120,40 -o endoh4 endoh4.c
The shape of this code is the geometric net of a regular tetrahedron.
So, try:
./endoh4 < endoh4.c
The solids.tbz2 file includes various solid data:
[Platonic solids](http://en.wikipedia.org/wiki/Platonic_solid),
[Archimedean solids](http://en.wikipedia.org/wiki/Archimedean_solid),
[Prisms](http://en.wikipedia.org/wiki/Prism_%28geometry%29),
[Antiprisms](http://en.wikipedia.org/wiki/Antiprism),
[Bipyramids](http://en.wikipedia.org/wiki/Bipyramid),
[Trapezohedrons](http://en.wikipedia.org/wiki/Trapezohedron), and
[Johnson solids](http://en.wikipedia.org/wiki/Johnson_solid).
I created the files by using the POV-Ray scripts
([1](http://en.wikipedia.org/wiki/File:Poly.pov) and
[2](http://en.wikipedia.org/wiki/User:AndrewKepert/poly.pov))
in Wikipedia.
They are copyrighted in CC BY-SA 3.0
by "User:Cyp" and "User:AndrewKepert".
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
Binary file not shown.
+786
View File
@@ -0,0 +1,786 @@
| 22nd International Obfuscated C Code Contest Official Guidelines
| Copyright (C) 2006-2013 Leonid A. Broukhis, Simon Cooper, Landon Curt Noll.
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.
| This guidelines file is version 2013-07-30-v17.
| Most of the changes from the previous IOCCC guidelines
| been marked with a "|" on the left hand side of the line.
ABOUT THIS FILE:
This file contains guidelines intended to help people who wish to
| submit entries to the International Obfuscated C Code Contest (IOCCC).
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.
We recommend that you follow the twitter handle:
@IOCCC
to learn about IOCCC news, important IOCCC related alerts, IOCCC
reminders, and changes to the rules and these guidelines.
| You do not have to be a twitter user to follow @IOCCC. Non-twitter
| users should access:
| https://twitter.com/ioccc
| Non-twitter users should force their browsers to reload the above URL
| to be sure they are seeing the most recent tweets.
While we try to post use news at:
http://www.ioccc.org/index.html#news
such postings may be delayed or obscured by slow to respond mirrors.
| WHAT'S NEW IN 2013:
| The contest runs from 2013-Aug-01 3:14:15 UTC to 2013-Oct-03 9:26:53 UTC.
| Rule 2 (the size rule) has been changed. In particular the secondary size
| limit has changed to use an algorithm implemented by the IOCCC size tool.
| See below for details.
| The submission URL:
| https://submit.ioccc.org/
| should be active on or slightly before 2013-Aug-01 3:14:15 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
* compile it (with flags to enable all warnings)
* 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. :-)
| There are 19 reasons why these guidelines seem obfuscated.
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. Clever people will note that 16 might be prime
under certain conditions. Wise people, when submitting something clever
will fully explain such cleverness in their entry's remarks file.
People who are considering to just use some complex mathematical
function or state machine to spell out something such as "hello,
world!" really really, and we do mean really, do need to be more creative.
Ultra-obfuscated programs are, in 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. A clean looking program with
misleading comments and variable names might be a good start.
| When programs use VTxxx/ANSI sequences, they should NOT limited to a
| specific terminal brand. Those programs that work in a standard xterm
are considered more portable.
| Rule 2 (the size rule) has been changed. In particular rule 2 refers to
| the use of an IOCCC size tool. The source for this tool is found at:
| http://www.ioccc.org/2013/iocccsize.c
| The IOCCC size tool should be compiled as:
| cc -pedantic -Wall -std=c99 iocccsize.c -o iocccsize
| This tool imposes a 2nd limit on C code size. To check your program
| source against the 2nd limit of rule 2, use the -i command line option.
| For example:
| ./iocccsize -i < prog.c
| The IOCCC size tool, when using the -i option, may be summarized as:
| The size tool counts most C reserved words (keyword, secondary,
| and selected preprocessor keywords) as 1. The size tool counts all
| other octets as 1 excluding ASCII whitespace, and excluding any
| ';', '{' or '}' followed by ASCII whitespace, and excluding any
| ';', '{' or '}' octet immediately before the end of file.
| ASCII whitespace includes ASCII tab, ASCII space, ASCII newline,
| ASCII formfeed, and ASCII carriage return.
| In cases where the above summary and the algorithm implemented by
| the IOCCC size tool source code conflict, the algorithm implemented
| by the IOCCC size tool source code is preferred by the judges.
| There are at least 2 other reasons for selecting 2053 as the 2nd limit
| besides the fact that 2053 is the next prime > 2048. These reasons
| may be searched for and discovered if you are "Curios!" about 2053. :-)
| Moreover, 2053 was the number of the kernel disk pack of one of the
| judge's BESM-6.
| Take note that this secondary limit imposed by the IOCCC size tool
| obviates some of the need to #define C reserved words in an effort
| to get around the size limits of rule 2.
| Yes Virginia, that is a hint!
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 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_fine;
| this_is_not; /* <-- Try to avoid implicit type declarations */
We suggest that you compile your entry with an ISO/IEC 9899-1999
("ISO C99") C compiler or at least an ANSI C compiler.
DO NOT assume that we will use gcc to compile your program.
We will first try to compile your program using Clang.
It is much better to not use any given obscure compiler flags if
you can help it. We want to discourage the use of obscure compiler
flags that would make the program less portable.
One side effect of the above is that you cannot assume the use
of nested functions such as:
main() {
| void do_not_do_this() { printf("Lemon Curry?\n"); }
do_not_do_this();
}
This is because such nested functions often requires one to compile with
a flag such as -fnested-functions that is not found on some compilers.
On 2012 July 20, the judges rescinded the encouragement of
nested functions. Such constructions, while interesting and sometimes
amusing, will have to wait until they required by a C standard that are
actually implemented in commonly used C compilers. Sorry!
| We prefer programs that don't require a fish license for pet fish.
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.
On 28 January 2007, the Judges rescinded the requirement that the
| '#" in a C preprocessor directive must be the 1st non-whitespace octet.
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 to 120
| octets long. Going well beyond 140 octets is a bit too long to be called
| a one-liner in our vague 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 "blob-ier" than they need to be
| * are too similar to previous winners :-(
* are identical to previous losers :-)
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.
At least one judge prefers to maintain the use of the leap-second
as part of the world's time standard.
The "how to build" make process should not be used to try and get
around the size limit. It is one thing to make use of a several -D's
on the compile like to help out, but it is quite another to use many
bytes of -D's in order to try and squeeze the source under the size limit.
You should try to restrict commands used on the build file to
POSIX-like or common Un*x-like commands. You can also compile
and use your own programs. If you do, try to build and execute
from the current directory. This restriction is not a hard and
absolute one. The intent is to ensure that the building if your
program is reasonably portable.
| You are in a maze of twisty guidelines, all different.
Don't forget that the building of your program should be done
***without human intervention***. So don't do:
prog: prog.c
| #echo this next line requires data from standard input
cat > prog.c
${CC} prog.c -o prog
However, you can do something cute such as making your program
| do something dumb (or cute) when build 'automatically'. And
when it is run with a human involved, do something more clever.
For example, one could use the build instructions:
prog: prog.c
${CC} prog.c -DNON_HUMAN_COMPILE -o prog
@echo "See remarks section about alternate ways to compile"
and then include special notes in the program "remarks" for
alternate / human intervention based building.
We want to get away from source that is simply a compact blob of
| octets. Really try to be more creative than blob coding.
Please do not use things like gzip to get around the size limit.
Be more creative.
We really dislike entries that make blatant use of including
large data files to get around the source code size limit.
Did we remember to indicate that programs that blatantly use
some complex state machine to do something simple are boring?
We think we did. :-)
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!
| Remember, you can submit more than one entry. See the rules for details.
We suggest that you avoid trying for the 'smallest self-replicating'
source. The smallest, a zero byte entry, won in 1994.
| Programs that claim to be the smallest C source that does something
| better be the smallest such program or they risk being rejected because
| they do not work as documented.
| Please note that the C source below, besides lacking in obfuscation,
| is NOT the smallest C source file that when compiled and run, dumps core:
| main;
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.
However, initialized char arrays are OK to write over. This is OK:
| char b[] = "Is this OK";
b[9] = 'K';
| There is a typo in this sentence.
X client entries should be as portable as possible. Entries that
adapt to a wide collection of environments will be favored. For
example, don't depend on a particular type or size of display.
Don't assume the use of a particular browser. Instead assume a
generic browser that forms to a widely used W3C standard.
Don't assume a particular sound sub-system or video driver is installed
in the OS. Instead, make use of a well known and widely available open
source program (one that actually works) to display audio/visual data.
X client entries should avoid using X related libraries and
software that is not in wide spread use.
| This is the only guideline that contains the word fizzbin.
We don't like entries that use proprietary toolkits such as the M*tif,
Xv*ew, or OpenL*ok toolkits, since not everyone has them. Use of an
open source toolkit that is widely and freely available instead.
You should avoid depending on a particular window manager.
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 program "remarks".
Try to avoid entries that play silent sound segments or play the
| Happy Birthday song; music that some people believe is copyrighted
| (even if such copyrights appear to be bogus and/or blatant abuses of
| the copyright system).
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.
| You very well might not be prohibited from failing to not partly
| misunderstand this particular guideline. You are not required to
| determine that this or the previous sentence is false and misleading.
| Nevertheless, it might not hurt to not fail to consider failing to do so.
We like programs that:
* are as concise and small as they need to be
* do something at least quasi-interesting
* 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 really helps!)
Some types of programs can't excel (anti-tm) in some areas. 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 program
"remarks" section rather than leaving it obscure for the judges
as we might miss something and/or be too tired to notice.
| Avoid this specific individual guideline, if you can.
We freely admit that interesting, creative or humorous comments in
the program "remarks" 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 program "remarks" during the judging process, so it is worth your
while to write remarkable program "remarks".
We dislike C code with trailing control-M's (\r or \015) that results
in compilation failures. Some non-Un*x/non-Linux tools such as
MS Visual C and MS Visual C++ leave trailing control-M's on lines.
Users of such tools should strip off such control-M's before submitting
their entries. In some cases tools have a "Save As" option that will
prevent such trailing control-M's being added.
We dislike entries that depend on non-portable libcurses features such
as halfdelay(). One should restrict libcurses to portable features
found on BSD or Linux curses.
| Rule 13 states any C source that fails to compile because of unescaped
| octets with the high bit set (octet value >= 128) will be rejected.
| Instead of unescaped octets, you should use \octal or \hex escapes:
/* 123456789 123456789 123456789 123456 */
char *foo = "This string is 36 octets in length \263";
/* This octet requires 4 octets of source ^^^^ */
if (strlen(foo) == 36) printf("foo is 36 octets plus a final NUL\n");
else printf("This code should not print this message\n");
It is a very good idea to, in your remarks file, tell us why you
think your entry is obfuscated. This is particularly true if
your entry is has some very subtle obfuscations that we might
otherwise overlook. <<-- Hint!
Anyone can format their code into a dense blob. A really clever
author will try format their entry using a "normal" formatting style
such that at first glance (if you squint and don't look at the details)
the code might pass for non-obfuscated C. Deceptive comments,
and mis-leading formatting, in some cases, may be a plus. On the
other hand, a misleading code style requires more source bytes.
If you do elect to use misleading formatting and comments, we
suggest you remark on this point in your remarks where you talk
about why you think your entry is obfuscated. On the other hand,
if you are pushing up against the size limits, you may be forced
into creating a dense blob. Such are the trade offs that obfuscators face!
| We prefer code that can run on either a 64-bit or 32-bit processor.
| However, it is unwise to assume it will run on an i386 or x86 architecture.
| While programs that only run in a specific word size are OK. If you have
| to pick a 64-bit word size.
If we are feeling ornery we might choose to compile your program
for running on an Arduino or a PDP-11. Heck, should we ever find
an emulator of 60-bit CDC Cyber CPU running a POSIX-like OS, we
might just try your entry on that emulator as well| :-)
If your entry MUST run only in 32-bit mode on an Intel processor, add the
following compiler flag:
-arch i386
to your "how to build" make compile line. For example:
prog: prog.c
${CC} prog.c -arch i386 -o prog
Be even more 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 program
"remarks". 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 web submission procedure tends to annoy us more
than amuse us. Spend your creative energy on content of your
entry rather than on the submission process itself.
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. A cleaver author
should be able to read them and "drive a truck through the holes" in
the rules and guidelines.
At the risk of stating the obvious, this contest is a parody 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
rules and guideline process as a parody of the sometimes tragic
mismatch between what a customer (or marketing) wants and what
engineering delivers. Real programmers must face obfuscated
and sometimes conflicting specifications and requirements from marketing,
sales, product management an even from customers themselves on a
all to regular basis. This is one of the reasons why the rules and
guidelines are written in obfuscated form.
JUDGING PROCESS:
Entries are judged by Leonid A. Broukhis, Simon Cooper, Landon Curt Noll.
Each entry submitted is given an id number and subdirectory. The
entry files including, but not limited to prog.c, Makefile (that we
form from around your "how to build" information), as well as any
data files that you submit are all places under their own directory.
stored and judged from this directory.
| Any information about the authors is not read by the judges until
the judging process is complete, and then only from entries that have
won an award.
Because we do not read this information for entries that do not win,
do not know who did not win.
The above process helps keep us biased for/against any one particular
individual. Therefore you MUST refrain from putting any information
that reveals your identity in your entry.
Now some people point out that coding style might reveal the information
about the others. However we consider this to be simply circumstantial
and outside the scope of the above paragraph.
Some people, in the past, have attempted to obfuscate their identity by
including comments of famous Internet personalities such as Peter Honeyman
(http://www.citi.umich.edu/u/honey/). The judges are on to this
trick and therefore consider any obfuscated source or data file
claiming to be from Honeyman to not be form Honeyman. This of course
creates an interesting paradox known as the "obfuscated Peter Honeyman
paradox". Should Peter Honeyman actually submit an obfuscated entry,
| he alone is excluded from above mentioned refrain as we will likely believe
it just another attempt at confusion. This guideline is known
as the "Peter Honeyman is exempt" guideline.
BTW: None of the entries claiming to be from Peter Honeyman have ever
won an award. So it is theoretically possible that Peter Honeyman
did submit an entry in the past. In the past, Peter had denied
submitting anything to the IOCCC. Perhaps those entries were
submitted by one of his students?
| We seemed to have digressed ... :-) Returning to the judging process:
We prefer to be kept in the dark as much as you are until the final
awards are given. We enjoy 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.
| During the judging process. a process that spans multiple sessions
| over a few weeks, post general updates from our @IOCCC twitter account.
| Once we have selected the winners, for each category we will tweet:
|
| category name
| name(s) of the authors (or anonymous if requested)
| twitter handle(s) (if provided and if anonymity was not requested)
| country code(s) of the author(s)
After the initial 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 "how to build" information and forming a Makefile
* reading prog.c, the C source
* reviewing the "remarks" information
* briefly looking any any supplied data files
* 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
* compiling/building the source
* running the program
* Doing other things that only IOCCC judges know about :-)
In later rounds, other actions are performed including 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 will often 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 (code with deceptive comments and source code)
* best X client (see OUR LIKES AND DISLIKES)
* best abuse of ISO/IEC 9899-1999 ("ISO C99") C or ANSI C
* best abuse of the C preprocessor
* 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 to about
| half that number: declaring those remaining to be 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 is 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 than one IOCCC judge has been known to bribe another IOCCC judge
into voting for a winning entry by offering a bit high quality chocolate.
This technique is highly discouraged for use by non-IOCCC judges.
More often than not, we select a small entry (usually one line), a
strange/creative layout entry. We sometimes also select an
entry that abuses the contest guidelines in an interesting way,
or that stretches the content rules that while legal, is
nevertheless goes against the intent of the rules.
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 judges will tweet initial announcement of who won, the name
of their award, and a very brief description of the winning entry
| from the @IOCCC twitter handle. Non-twitter users should visit:
| https://twitter.com/ioccc
| Non-twitter users should force their browsers to reload the above URL
| to be sure they are seeing the most recent tweets.
The judges will then post an initial announcement of who won, the name
of their award, and a very brief description of the winning entry
on the IOCCC web site:
http://www.ioccc.org/whowon.html
We will also attempt to submit a brief announcement story to /.:
http://slashdot.org
that, depending on the willingness of the /. editors, may be posted
to their site at the same time.
Note that initial announcement will NOT contain source. This is because
the winning authors are given a chance to review the judges comments,
and test our Makefile. This review process typically takes a few weeks.
Sometime after the initial announcement, and once the the review
by the winners has been completed, the winning source will be
posted to the IOCCC web site:
http://www.ioccc.org/years.html
NOTE: previous winners are available at that URL
| We will also tweet, via @IOCCC, when the winning source is available.
| It is pointless to ask the IOCCC judges how many entries we receive.
| Other government TLA based snooping organizations may neither confirm
| not deny any knowledge of this data point. :-)
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. More than one winner has been turned in a tattoo!
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:
| q.2013@ioccc.org (do not submit entries to this address)
| You must include the words 'ioccc 2013 question' in the subject of your
EMail message when sending EMail to the judges.
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.
Check out the IOCCC Web page:
http://www.ioccc.org
It has rules, guidelines and winners of previous contests (1984 to date).
| For the updates and breaking IOCCC news, you are encouraged to follow
| the twitter handle:
| @IOCCC
| You do not have to be a twitter user to follow @IOCCC. Non-twitter
| users should access:
| https://twitter.com/ioccc
| Non-twitter users should force their browsers to reload the above URL
| to be sure they are seeing the most recent tweets.
Leonid A. Broukhis
Simon Cooper
chongo (Landon Curt Noll) /\cc/\
+77
View File
@@ -0,0 +1,77 @@
* {
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
}
body {
max-width: 50em;
margin: 0 auto;
color: #111;
}
pre, code {
font-family: Monaco, Courier New, monospace;
font-size: 12px;
}
h1 {
font-size: 40px;
font-weight: bold;
letter-spacing: -1px;
margin-bottom: -5px;
}
h1 code {
font-size: 40px;
}
h2 {
color: rgb(43,105,145);
font-weight: bold;
margin-bottom: -5px;
}
h2 code {
font-size: 22px;
}
h3 {
/* color: rgb(43,105,145); */
font-weight: bold;
margin-bottom: -5px;
}
h3 code {
font-size: 16px;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: navy;
}
a:hover {
text-decoration: underline;
}
pre {
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.3);
border-width: 1px;
border-color: rgb(16,48,0);
border-style: solid;
padding: 0.6em;
padding-left: 1em;
margin-left: 5%;
margin-right: 8%;
background-color: rgb(16,48,0);
overflow: auto;
color: rgb(75,224,0);
}
p, li {
font-size: 14px;
line-height: 18px;
}
+212
View File
@@ -0,0 +1,212 @@
#!/usr/bin/env make
#
# 2013 makefile
#
# This work by Landon Curt Noll, Simon Cooper, and Leonid A. Broukhis
# is licensed under:
#
# Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
# See: http://creativecommons.org/licenses/by-sa/3.0/
################
# tool locations
################
#
SHELL= /bin/bash
CP= cp
CPP= cpp
GUNZIP= gunzip
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
# Set X11_LIBDIR to the directory where the X11 library resides
#
X11_LIBDIR= /usr/X11R6/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
X11_INCDIR= /usr/X11R6/include
# Compiler warnings
#
#CWARN=
CWARN= -Wall
#CWARN= -Wall -pedantic
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c99
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# Libraries needed to build
#
LIBS=-lm
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${OPT}
# 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
#CC=clang
MAY_NEED_GCC= gcc
##############################
# Special flags for this entry
##############################
#
ENTRY= hou
OTHER_PROG= a
OTHER_SRC= a.c
OTHER_OBJ= a.o
DATA=
ALT_OBJ=
ALT_ENTRY=
#################
# build the entry
#################
#
all: ${ENTRY} ${DATA}
@${TRUE}
${OTHER_PROG}: ${ENTRY}.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
${OTHER_SRC}: ${OTHER_PROG}
${RM} -f $@
./${OTHER_PROG} > $@
${ENTRY}: ${OTHER_SRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${ENTRY}.o ${OTHER_OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${ENTRY} ${OTHER_SRC} ${OTHER_PROG} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. Lehmer!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
easter_egg:
@echo you expected to mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from being unable to not partly misunderstand this partocular final echo.
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: nuke
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v4; \
else \
echo "We are not expected to understand that"; \
fi
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "Park different"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 391581 --level 216193 --FNV1a_hash 512-bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Paul Erdos!"; \
fi
@${TRUE}
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

+352
View File
@@ -0,0 +1,352 @@
# Scene format documentation
This file is encoded in UTF-8 as the BOF marker indicates.
You can directly feed it to the renderer. If you're wondering about what the following code block does, that's why:)
@|?|?z#
@|||?z&
>?Sedvf
??Tdeu#
>>Tdeui
??Tdmmf
??[[euf
?}?Oq}e
?}?Oqqf
v}?|q}e
v}?|qqf
?Sj|?{f
?Tjk?{e
FF?Oqq$
RR?Oqq$
^^?Oqq$
jj?Oqq$
vv?|qq$
IOBMqqe
U]BMqqe
aiBMqqe
muBMqqe
EEEJpp%
QQEJpp%
]]EJpp%
iiEJpp%
uuEJpp%
ZnY|{|e
[mZ|{{#
[mZ|||f
kkdr{{%
lkdr{{>
## Basic structure
A scene file begins with arbitrary binary data, followed by several shader functions.
Shader functions are declared using a one-character name followed by a ']' character. There are some special function names, which will be explained below.
The language used to write shader functions is very simple. Basically, you write a sequence of assignment statements like this:
A=A+D
B=B+E
Namely, you write a one-character variable name, an equal sign '=', followed by an expression (made of operators and one-character variable names, of course).
## Expressions
The shader language supports seven operators, listed highest priority first:
*/+-<#:
`*/+-<` mean what they mean in C, but the priority part is a bit different. Basically, `*` has higher priority than `/`, so `A/4*4` actually computes `A/(4*4)`. And you can't write `(A/4)*4` -- brackets are not supported. As an advice, keep your expressions simple :) If you really needs to write something like C=(A/4)*4, write instead:
B=A/4+
C=B*4
The # operator acts somewhat like the C ?:. It returns one of its two operands based on, what else, the value of variable #. When # is true, # returns its second operand.
The : operator calls built-in functions. The first operand is the function id and the second is the parameter. Here is a list of functions:
0:x = the x-th byte of the scene file
1:x = sin(x*PI)
2:x = atan2(x,#)/PI
3:x = sqrt(max(x,0))
4:x = floor(x)
5:x = the next number in the (allegedly random) number sequence, can't be called in volume shaders
6:x = value of the variable (char)(120+x)
7:x = write #'s value to the variable (char)(120+x)
Contrary to popular belief, the language itself doesn't support numerical constants. Any character sitting between operators is a variable. When you see 1/2, it's in fact dividing the variable 1's value by the variable 2's value. For everyone's convenience, though, in the beginning every variable is initialized to its ASCII code minus 48. As long as you don't write something like 3=1+1, you can use single digit numbers as, well, single digit numbers. If you need something like 1920 or 0.73, you need to compute it yourself. And yes, all variables store floating point values.
If a character appears as the first character of any argv, it goes to zero. This includes the scene filename. If you name your scene '1.scene', well, good luck with 1=0!
You can terminate a statement using any character that isn't an operator, be it \n or ;. But you must put in one and only one character. Put in two (e.g. the Windows \r\n), and it terminates your function. Also, the first statement must begin immediately after ']'.
When a function terminates, the interpreter calls the next function specified by variable R. If you want to call function 'n', just write somewhere:
R=n
providing you have left n at its initial value. If you want to actually return to the renderer, put in R=0.
As you may have noticed, you can put in all kinds of stuff between functions, like this comment.
## How the ____ do I render an image with shaders?
Basically, you define a geometry using volume shaders, define a camera using a camera shader, and define light sources and surface reflectance properties using material shaders.
-------------------------------------------
Continue to the comments before function A
-------------------------------------------
//As an (optional) assignment, figure out what function `n` does. And why there is a plus sign at every EOL except the last.
n]#=1+
x=X+1/2+
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
x=Y+1/2+
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
x=Z+1/2+
d=0:U;d=d-n;U=U+1;A=d<x;#=#*A+
d=0:U;d=d-n;U=U+1;A=x<d+1;#=#*A+
d=0:U;d=d-n;U=U+1+
U=U+2+
C=C#d+3*9+
#=d+
R=0#n
-------------------------------------------
The function "A" initializes global settings:
G -- Image width, in pixels
H -- Image height, in pixels
I -- Perturbation probability
J -- Camera ray stratification probability
If you have used a MLT renderer before, you probably know what I and J does. If you don't, well, use the same value as the default scene. Everything converges just fine under suboptimal settings, just a little slower. Generally, use a higher value for I if your scene is primarily illuminated by some indirect source.
"A" also serves as the geometry shader for volume 0. The scene geometry is made of up to 32 volumes, each with 64x64x64 cells. The volume 0 is the 'top level' volume where the camera goes. Each cell of a volume can be empty, filled with a material, or another volume. The round-ish characters in old_default.scene and the carpet on the floor in this file are examples where a cell is defined to another volume. Materials will be explained later.
The volume shader for the i-th volume is named as the (i+1)-th capital letter. Each volume shader is invoked once for each cell. The cell coordinates (0..63) are given as inputs in variable x,y,z, and you're supposed to return the cell content in variable C. To fill it with material i, return 64+i in C. To fill it with volume i, well, return i. To leave it empty, return C=0.
Before starting to build a scene, it's better to have a draft sketch handy first. Something like ![ Draft sketch ](draft.png). Sometimes it's hard to imagine where something should go without the sketch. And you don't have to stick to your sketch :)
What motivated my default scene: it was the full moon's day (a national holiday) in China and my parents were planning to renovate their apartment. I rendered the image to tell my mom how ridiculous her starry-sky wall paper would look like if she used it on every single wall. She ends up using it on just one wall, the one facing my bed, to thank me for the effort.
-------------------------------------------
Continue to the comments before function a
-------------------------------------------
//As a bonus, find out what the first line does
A]#=#-#;"=7:0-p+^;#="+
R=n+
G=p*:+
#=0<B+
G=G*2#G+
H=G*3/4+
I=4/5+
J=1/2+
C=p+1+
U=w+w+w
-------------------------------------------
The function 'a' is the camera shader, which, well, generates the camera ray. It's supposed to return the ray in variables UVWXYZ and ABCDEF (that may sound like a lot of variables, but it really isn't that much).
Here comes some subtlety of PSSMLT (Primary Sample Space Metropolis Light Transport, or Kelemen-style MLT). Basically, a PSSMLT renderer gives you an (allegedly random) number sequence, and you compute a color out of it. This is usually done by generating and tracing rays out of those random numbers. The renderer would assemble the colors into an image.
Remember the function 5? Here it comes. The first two "random" numbers have special meaning and must specify a point on the image plane [0,1)x[0,1). You're supposed to transform the image plane to the 3D space, choose a point for the camera, and shoot a ray from the camera point to the image plane point, see ![ Camera convention ](camera.png). The camera point goes to (U,V,W), and the ray direction vector (image plane point - camera point) is (X,Y,Z). For the coordinate space, volume 0 is scaled up 64x here to (0,0,0)-(4096,4096,4096).
For a basic camera shader example, check "otherroom.scene".
If any ray goes out of volume 0, the renderer crashes. Make sure it doesn't happen. Wall up everything.
Variables ABCDEF control the color returned from the ray. They will be explained in the material shaders part. For now, just put in:
A=0;B=0;C=0
D=1;E=1;F=1
-------------------------------------------
Continue to the comments before function 1
-------------------------------------------
a]R=0+
X=5:5+
Y=5:5+
X=X-1/2+
Y=Y-1/2+
x=5:5+
y=5:5+
x=x-1/2+
y=y-1/2+
x=x*8*7;y=y*8*7+
X=X*G+
Y=Y*H+
Z=H*2/3+
d=4*;+
d=d*p/Z+
X=x+X*d+
Y=y+Y*d+
Z=Z*d+
U=p*p/2-p*2+x+
V=p*p/2+p*1-y+
W=p*8+
A=0;B=0;C=0+
D=1;E=1;F=1
--------------------------------------------------------
The numbered functions define materials, i.e., surface reflectance properties. As the name suggests, the shader simulates ray-surface interaction. It's done by updating UVWXYZABCDEF, of course.
ABCDEF define colors. (A,B,C) is the RGB irradiance ultimately returned to the renderer, and (D,E,F) maintains the cumulative RGB reflectance of the current ray path. This may sound confusing, but basically, if the surface is a light source, you accumulate the current path reflectance (D,E,F), multiplied by the light strength, to (A,B,C). See shader 6 for an example.
If you want a colored surface, use its color to modulate (D,E,F), i.e. D=D*red;E=E*green;F=F*blue, easy as that. To get some texturing, compute the color procedurally or look up a binary table.
There's something subtle about colors. To go along with the trend, the renderer follows the practice of linear rendering with a gamma of 2. Stripping the fancy jargons, that basically means after picking a color in your favorite image editing program, you need to convert the RGB values from 0..255 to 0..1, and then put here its *square*. Only after squaring you get your real, lively color in the output image, as opposed to something dull and gray. You need to do the same if you use a RGB texture. And yes, that is the what the second sqrt in a.c is for.
Going beyond colors, to define a shiny or dull surface one needs more maths, and optics. The jargon for this is BRDF (Bidirectional Reflectance Distribution Function) importance sampling. Let's continue to function o.
-------------------------------------------
Continue to the comments before function o
-------------------------------------------
//This function computes the starred wallpaper
//Original color: 0.36 0.714285 0.8
1]R=o+
d=p*6+
x=U+W+
x=4:x/d+
z=4:V/d+
#=3*x-4*z+
y=4:#/5+
#=#-y*5+
y=1#0+
x=x*d+d/2-U+W+
z=z*d+d/2-V+
r=3:x*x+z*z+
#=z+
u=2:x+
d=1:u*5+
d=d*d*d+3/2+
d=d*p+
#=r<d+
#=#*y+
d=2/5#I+
D=D*d+
E=E*4/7+
d=I#2/5+
F=F*d
-------------------------------------------
Function o defines a diffuse (that is, dull) surface. To define reflectance properties like this, one needs to sample an outgoing ray direction, based on the incoming direction and the surface normal. It's called importance sampling, because here the probability of each outgoing direction has to be proportional to the reflected light strength (i.e., the BRDF) on that direction. For a diffuse surface, sample the upper hemisphere with a probability proportional to the cosine of the outgoing angle, see ![ Cosine sampling ](cosine.png).
The incoming direction is in (X,Y,Z) and the hit point is (U,V,W). The outgoing direction is returned in, where else, (X,Y,Z).
The surface normal is provided in variables S and T. Since the geometry is defined as a bunch of cube-shaped cells, there are only 6 possible normals: (±1,0,0) (0,±1,0) (0,0,±1). Here S is the sign and T is the dimension. If you get S=-1 and T=1, the normal is (0,-1,0).
If you don't want to redo all the math yourself... this file provides a few simple shader functions:
o -- Diffuse surface. Do the color thing your self and call R=o
5 -- Perfect mirror.
f -- Surface with a Fresnel term. Basically, it resembles a polished surface made from a dielectric material.
For something more complex like a fluffy carpet, well, you could use a volume to directly model the mesoscopic detail. Shader D in this file produces a bunch of dense, tiny spikes to simulate a fluffy appearance.
-------------------------------------------
Continue to the EOF
-------------------------------------------
//diffuse ray generation
o]R=0+
u=5:5+
v=5:5+
v=v*2+
r=3:u+
z=1:v+
y=1:1/2+v+
z=z*r+
y=y*r+
x=3:1-u+
x=0-x*S+
X=6:T+
w=x;x=z;z=y;y=w+
Y=6:T+
w=x;x=z;z=y;y=w+
Z=6:T
//reflector
5]R=0+
x=1;y=1;z=1+
#=0-1+
#=7:T+
X=x*X;Y=y*Y;Z=z*Z
//approximate Fresnel, works better than the real thing when you don't want to tweak the IOR
f]x=X;y=Y;z=Z+
r=3:x*x+z*z+y*y+
d=6:T+
d=1-d*S/r+
d=d*d*d+
#=5:5+
#=d<#+
R=5#o+
d=d#1-d+
u=1#u+
v=1#v+
w=1#w+
D=D*d*u+
E=E*d*v+
F=F*d*w
//the handles
B]R=0+
#=X<8*3+
C=3#0
C]R=0+
#=X<8*4+
C=0#4
//red-Fresnel
2]R=f+
u=1/2;v=1/9;w=v
//white-Fresnel and the full moon
3]R=f+
u=7*9/p;v=u;w=v+
x=3*:+8+
z=U-x*p+p/2+
x=V-x*p-p/2+
r=3:x*x+z*z+
#=4<r/p+
D=D*I#D+
E=E*4/7#E+
F=F*2/5#F+
d=1/5#0+
A=A+D*d+
B=B+E*d+
C=C+F*d
//handle
4]R=5+
D=D*I;E=E*4/7;F=F*2/5
//light from the window
6]R=0+
#=P+
d=2#8*2+
A=A+D*d+
B=B+E*d+
C=C+F*d*I+
P=9
//carpet
7]R=o+
D=D/7+
E=E/3+
F=F/7
D]R=0+
#=8<Y+
C=0#3+
#=4:3*X-4*Z+
y=4:#/7+
#=#-y*7+
C=7#C
-------------------------------------------
The last line, well, is the output filename. Just remember to throw in two ']'s and don't put a newline after it.
]]example.ppm
+150
View File
@@ -0,0 +1,150 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Best use of 1 Infinite Loop</title>
</head>
<body>
<h1>Best use of 1 Infinite Loop</h1>
<p>Qiming Hou<br>
<a href="&#x6d;&#97;&#105;&#x6c;&#116;&#x6f;&#x3a;&#104;&#113;&#109;&#x30;&#51;&#x73;&#x74;&#101;&#114;&#64;&#x67;&#109;&#x61;&#x69;&#x6c;&#x2e;&#x63;&#111;&#x6d;">&#104;&#113;&#x6d;&#48;&#x33;&#115;&#116;&#x65;&#114;&#64;&#103;&#x6d;&#97;&#x69;&#x6c;&#x2e;&#x63;&#111;&#109;</a><br>
<a href="http://www.houqiming.net">http://www.houqiming.net</a></p>
<h2>Judges' comments:</h2>
<h3>To build:</h3>
<pre><code>make hou
</code></pre>
<h3>To run:</h3>
<pre><code>./hou [scene-file-name] [options]
Follow the instructions in stdout, preferably with an auto-refreshing PPM image viewer ready.
Refresh the image every time the output refreshes, all effects should be more or less recognizable when you see 16.
</code></pre>
<h3>Try:</h3>
<pre><code>./hou BIG
./hou old_default.scene BIG
./hou otherroom.scene
./hou otherroom.scene NAIVE
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>You could consider that this program violates the source code size
limit. This is because the first compliation of this program is
really just a decompressor to generate the real source code of the
program.</p>
<p>This program will loop infinitely while progressivly refining a
raytraced image.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Using hou</h3>
<p>This program is a programmable rendering engine with a built-in default scene. The standard command line is:</p>
<pre><code>./hou [scene-file-name] [options]
</code></pre>
<p>As hou runs, it writes a progressively refining image to a ppm file specified in the scene. The initialization may take a while, but once it&rsquo;s done, a rough preview should be available in seconds. Leave hou running for the night, and you get a high quality result like the attached *.jpg files. Kill hou manually after you&rsquo;re satisfied with the image quality.</p>
<p>To save time and energy for the judges, rendered images for all provided scenes are provided as attached files.</p>
<h3>Features</h3>
<ul>
<li><p>Fully programmable: Almost every stage of the renderer is programmable with a shader, i.e., a short script that does something rendering-related. In particular, each scene consists of one or more geometry shaders, a camera shader, and one or more material shaders. Shaders are written in an interpreted language that supports basic arithmetic, a few math functions, variables and procedural call in the CPS (Continuation Passing Style).</p></li>
<li><p>Fast preview: This renderer isn&rsquo;t just a naive path tracer, it actually uses a modern global illumination algorithm which is robust against challenging scene configurations. You can mostly place light sources and specify surface properties as you please without worrying too much about the convergence speed &ndash; you always get a nice fast preview within one or two minutes. As proof, there is a comparison: &ldquo;./hou otherroom.scene&rdquo; gives a rough idea about the overall illumination at 16 samples per pixel (i.e., when the program prints 16), whereas the naive approach &ldquo;./hou otherroom.scene NAIVE&rdquo; only produces a mess of white dots.</p></li>
<li><p>Rich visual effects: The algorithm samples all light path types so most physically based effects can be produced. The default scene demonstrates quite a few of them: reflection, area light, soft shadows, color bleeding, caustics, and depth-of-field blur. Of course, one can also get programmable-shading effects like procedural texturing and approximated Fresnel terms.</p></li>
<li><p>Accelerated ray tracing: The ray tracing part uses an algorithm better than the brute-force intersection of everything. The renderer even builds an acceleration data structure! Despite the double precision and the single-threaded-ness, it still runs at about 0.5 million rays per second on the author&rsquo;s machine.</p></li>
<li><p>Pause and resume: Can&rsquo;t run ./hou overnight? No problem! You can kill and resume a rendering session whenever you want. The renderer automatically saves the progress every 16 samples and resumes where it&rsquo;s left off when restarted. Also, each scene/parameter combination gets a different saved session so you don&rsquo;t have to worry about conflicts.</p></li>
</ul>
<h3>Abuse of the rules</h3>
<ul>
<li><p>hou.c uses compression to get around the size limit. The compression fully complies with the rules and the guidelines (at least the portion that shows up in grep &ldquo;size limit&rdquo;). Please see the &ldquo;Self-imposed restrictions&rdquo; section below for more details.</p></li>
<li><p>hou does not terminate (as suggested by the second line of rule 6).</p></li>
</ul>
<h3>Self-imposed restrictions</h3>
<ul>
<li><p>The building process does not involve any OS tool beyond cc and make. No gzip compression! a.c.gz doesn&rsquo;t fit in 2053 bytes, anyway.</p></li>
<li><p>Neither hou.c nor a.c (the <em>real</em> decompressed source) uses #define (or cc -D) at all.</p></li>
<li><p>The source code is not required at runtime.</p></li>
<li><p>a.c does not drop optional features to reduce size. There are pure optimization code that can be dropped without affecting the converged output (only affecting the ray tracing speed / convergence rate). All files are properly fopened with &ldquo;rb&rdquo; / &ldquo;wb&rdquo; for Windows compatibility. The PPM header has a comment line for non-standard-compliant viewers (specifically, my old HDRShop 1.0). And there is a nice text message saying &ldquo;please wait&hellip;&rdquo;.</p></li>
<li><p>Despite the messy look, a.c and hou.c compiles warning-free (hou.c even wastes 18 bytes on #include&lt;stdio.h> just for putchar). a.c compiles mostly clean in the C99/ANSI modes of clang and gcc (with -Wall &ndash;pedantic). The only warning generated is a pedantic one: &ldquo;string constant too long&rdquo;.</p></li>
</ul>
<h3>Comments and why obfuscated</h3>
<ul>
<li><p>Both the compression and the rendering use mathematically involved algorithms. Understanding the C doesn&rsquo;t help much if one isn&rsquo;t familiar with the math.</p></li>
<li><p>Modern renderers provide shader access to just about any internal state. This one follows suit and reuses the same shader-accessible array for all important internal states.</p></li>
<li><p>Infinity and not-a-number are used during normal course of execution.</p></li>
<li><p>Previous image-generating entries may take care to hide the &ldquo;IOCCC&rdquo; string in the code, but they leave the text clear in the <em>result</em>. This entry takes it further and obfuscates the output image as well. Can you find the text in the image? Hint: look up.</p></li>
<li><p>a.c leaves all shaders in plain text, but the plain text shader code can&rsquo;t be taken for its face value &ndash; the arithmetic rules subtly diverge from our common sense.</p></li>
<li><p>a.c is less portable than hou.c itself. hou.c only depends on ASCII and should run just fine on 16-bit, small memory, or float-incapable machines. a.c, while still reasonably portable, is quite memory consuming, requires IEEE754-compliant double, and assumes int to be 32-bit.</p></li>
<li><p>Though technically endian-dependent, a.c remains portable providing that one doesn&rsquo;t copy saved sessions across endians.</p></li>
</ul>
<h3>Spoiler</h3>
<pre><code> 3225 3225 3225 9 9 3225 3225
1 1 1 1 1 1 1 1 1 1
4225 1226 1 1 1 1 1222 1226
1 1 1 1 1 1 1 1 1
4226 1 4226 8 4222 4226 1 1
</code></pre>
<p> The program consists of a recursive-descend interpreter, a 3DDDA (3D Discrete Differential Analysis) ray tracer, a PSSMLT (Primary Sample Space Metropolis Light Transport) light path sampler, all squeezed into the size limit using a PPM compressor (Prediction by Partial Matching, and yes, the output format is chosen for the pun).</p>
<p> PSSMLT uses the Metropolis-Hasting algorithm to sample a 32D unit hypercube. Each point in the hypercube is interpreted as a sequence of random numbers, and is sent to a path tracer to generate a light path. The point&rsquo;s Metropolis-Hasting energy is then defined as the corresponding path&rsquo;s contribution value to the final image. Since each path is sampled with a probability proportional to its energy, the sample distribution directly corresponds to the final image, which can then be produced as a simple per-pixel histogram of all generated paths. The robustness comes from a state mutation strategy that actively tries to explore the neighborhood of high energy peaks (e.g. paths that happen to hit the light source in otherroom.scene). In addition, a rudimentary form of lens path stratification is added to balance the attention each pixel receives. The Metropolis-Hasting process completely avoids the tell-tale pixel sampling loop required in most other image generation methods.</p>
<p> The 3DDDA tracer is chosen for scalability: its performance doesn&rsquo;t get much worse as scene complexity increases. Another benefit is that with the DDA code in place one can naturally use hierarchical grids as an acceleration structure. The downside, of course, is that the setup involves quite a few divisions, which naturally turns into division-by-zeros. Fortunately, the IEEE754 standard has a nice set of rules just for this purpose and the arithmetics are organized in a specific way to take advantage of this. The shader interpreter component is relatively straightforward, just an expression evaluator stripped to the bare minimum &ndash; it doesn&rsquo;t even support numerical constants natively. A final little bit is a just-good-enough PRNG (Pseudo Random Number Generator) to replace the low precision Windows rand() and the non-C99 Unix drand48(). An overnight session would run through its short period many times, but that doesn&rsquo;t necessarily map to the same set of paths in PSSMLT. After all, Metropolis et al. used an even worse PRNG in their 1953 paper.</p>
<p> The PPM compressor uses statically weighted fixed order contexts with an arithmetic encoder tweaked for iocccsize. The encoder emits octet-space pairs where each octet encodes ~6.5 bits of information and each space encodes 2 bits (thanks to the generous definition of &ldquo;space&rdquo; in iocccsize.c). The compressor actively shuffles the variable names around until the compressed string happens to contain enough &ldquo;{}; &rdquo; to pass the final iocccsize test. There are a few other tweaks:</p>
<ul>
<li><p>The PPM model uses mostly whitespace characters for weights.</p></li>
<li><p>The encoder never emits &lsquo;&ldquo;&rsquo; and &lsquo;\&rsquo;.</p></li>
<li><p>The decoder uses an O(n<sup>2</sup>) algorithm to avoid the gigabytes-sized hash table frequently found in other PPM implementations.</p></li>
</ul>
<hr />
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
<TABLE><TR>
<TD><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a></TD>
<TD><P>&copy; Copyright 1984-2015,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
+123
View File
@@ -0,0 +1,123 @@
# Best use of 1 Infinite Loop
Qiming Hou
<hqm03ster@gmail.com>
<http://www.houqiming.net>
## Judges' comments:
### To build:
make hou
### To run:
./hou [scene-file-name] [options]
Follow the instructions in stdout, preferably with an auto-refreshing PPM image viewer ready.
Refresh the image every time the output refreshes, all effects should be more or less recognizable when you see 16.
### Try:
./hou BIG
./hou old_default.scene BIG
./hou otherroom.scene
./hou otherroom.scene NAIVE
### Selected Judges Remarks:
You could consider that this program violates the source code size
limit. This is because the first compliation of this program is
really just a decompressor to generate the real source code of the
program.
This program will loop infinitely while progressivly refining a
raytraced image.
## Author's comments:
### Using hou
This program is a programmable rendering engine with a built-in default scene. The standard command line is:
./hou [scene-file-name] [options]
As hou runs, it writes a progressively refining image to a ppm file specified in the scene. The initialization may take a while, but once it's done, a rough preview should be available in seconds. Leave hou running for the night, and you get a high quality result like the attached *.jpg files. Kill hou manually after you're satisfied with the image quality.
To save time and energy for the judges, rendered images for all provided scenes are provided as attached files.
### Features
* Fully programmable: Almost every stage of the renderer is programmable with a shader, i.e., a short script that does something rendering-related. In particular, each scene consists of one or more geometry shaders, a camera shader, and one or more material shaders. Shaders are written in an interpreted language that supports basic arithmetic, a few math functions, variables and procedural call in the CPS (Continuation Passing Style).
* Fast preview: This renderer isn't just a naive path tracer, it actually uses a modern global illumination algorithm which is robust against challenging scene configurations. You can mostly place light sources and specify surface properties as you please without worrying too much about the convergence speed -- you always get a nice fast preview within one or two minutes. As proof, there is a comparison: "./hou otherroom.scene" gives a rough idea about the overall illumination at 16 samples per pixel (i.e., when the program prints 16), whereas the naive approach "./hou otherroom.scene NAIVE" only produces a mess of white dots.
* Rich visual effects: The algorithm samples all light path types so most physically based effects can be produced. The default scene demonstrates quite a few of them: reflection, area light, soft shadows, color bleeding, caustics, and depth-of-field blur. Of course, one can also get programmable-shading effects like procedural texturing and approximated Fresnel terms.
* Accelerated ray tracing: The ray tracing part uses an algorithm better than the brute-force intersection of everything. The renderer even builds an acceleration data structure! Despite the double precision and the single-threaded-ness, it still runs at about 0.5 million rays per second on the author's machine.
* Pause and resume: Can't run ./hou overnight? No problem! You can kill and resume a rendering session whenever you want. The renderer automatically saves the progress every 16 samples and resumes where it's left off when restarted. Also, each scene/parameter combination gets a different saved session so you don't have to worry about conflicts.
### Abuse of the rules
* hou.c uses compression to get around the size limit. The compression fully complies with the rules and the guidelines (at least the portion that shows up in grep "size limit"). Please see the "Self-imposed restrictions" section below for more details.
* hou does not terminate (as suggested by the second line of rule 6).
### Self-imposed restrictions
* The building process does not involve any OS tool beyond cc and make. No gzip compression! a.c.gz doesn't fit in 2053 bytes, anyway.
* Neither hou.c nor a.c (the *real* decompressed source) uses #define (or cc -D) at all.
* The source code is not required at runtime.
* a.c does not drop optional features to reduce size. There are pure optimization code that can be dropped without affecting the converged output (only affecting the ray tracing speed / convergence rate). All files are properly fopened with "rb" / "wb" for Windows compatibility. The PPM header has a comment line for non-standard-compliant viewers (specifically, my old HDRShop 1.0). And there is a nice text message saying "please wait...".
* Despite the messy look, a.c and hou.c compiles warning-free (hou.c even wastes 18 bytes on #include<stdio.h> just for putchar). a.c compiles mostly clean in the C99/ANSI modes of clang and gcc (with -Wall --pedantic). The only warning generated is a pedantic one: "string constant too long".
### Comments and why obfuscated
* Both the compression and the rendering use mathematically involved algorithms. Understanding the C doesn't help much if one isn't familiar with the math.
* Modern renderers provide shader access to just about any internal state. This one follows suit and reuses the same shader-accessible array for all important internal states.
* Infinity and not-a-number are used during normal course of execution.
* Previous image-generating entries may take care to hide the "IOCCC" string in the code, but they leave the text clear in the *result*. This entry takes it further and obfuscates the output image as well. Can you find the text in the image? Hint: look up.
* a.c leaves all shaders in plain text, but the plain text shader code can't be taken for its face value -- the arithmetic rules subtly diverge from our common sense.
* a.c is less portable than hou.c itself. hou.c only depends on ASCII and should run just fine on 16-bit, small memory, or float-incapable machines. a.c, while still reasonably portable, is quite memory consuming, requires IEEE754-compliant double, and assumes int to be 32-bit.
* Though technically endian-dependent, a.c remains portable providing that one doesn't copy saved sessions across endians.
### Spoiler
3225 3225 3225 9 9 3225 3225
1 1 1 1 1 1 1 1 1 1
4225 1226 1 1 1 1 1222 1226
1 1 1 1 1 1 1 1 1
4226 1 4226 8 4222 4226 1 1
The program consists of a recursive-descend interpreter, a 3DDDA (3D Discrete Differential Analysis) ray tracer, a PSSMLT (Primary Sample Space Metropolis Light Transport) light path sampler, all squeezed into the size limit using a PPM compressor (Prediction by Partial Matching, and yes, the output format is chosen for the pun).
PSSMLT uses the Metropolis-Hasting algorithm to sample a 32D unit hypercube. Each point in the hypercube is interpreted as a sequence of random numbers, and is sent to a path tracer to generate a light path. The point's Metropolis-Hasting energy is then defined as the corresponding path's contribution value to the final image. Since each path is sampled with a probability proportional to its energy, the sample distribution directly corresponds to the final image, which can then be produced as a simple per-pixel histogram of all generated paths. The robustness comes from a state mutation strategy that actively tries to explore the neighborhood of high energy peaks (e.g. paths that happen to hit the light source in otherroom.scene). In addition, a rudimentary form of lens path stratification is added to balance the attention each pixel receives. The Metropolis-Hasting process completely avoids the tell-tale pixel sampling loop required in most other image generation methods.
The 3DDDA tracer is chosen for scalability: its performance doesn't get much worse as scene complexity increases. Another benefit is that with the DDA code in place one can naturally use hierarchical grids as an acceleration structure. The downside, of course, is that the setup involves quite a few divisions, which naturally turns into division-by-zeros. Fortunately, the IEEE754 standard has a nice set of rules just for this purpose and the arithmetics are organized in a specific way to take advantage of this. The shader interpreter component is relatively straightforward, just an expression evaluator stripped to the bare minimum -- it doesn't even support numerical constants natively. A final little bit is a just-good-enough PRNG (Pseudo Random Number Generator) to replace the low precision Windows rand() and the non-C99 Unix drand48(). An overnight session would run through its short period many times, but that doesn't necessarily map to the same set of paths in PSSMLT. After all, Metropolis et al. used an even worse PRNG in their 1953 paper.
The PPM compressor uses statically weighted fixed order contexts with an arithmetic encoder tweaked for iocccsize. The encoder emits octet-space pairs where each octet encodes ~6.5 bits of information and each space encodes 2 bits (thanks to the generous definition of "space" in iocccsize.c). The compressor actively shuffles the variable names around until the compressed string happens to contain enough "{}; " to pass the final iocccsize test. There are a few other tweaks:
* The PPM model uses mostly whitespace characters for weights.
* The encoder never emits '"' and '\\'.
* The decoder uses an O(n^2) algorithm to avoid the gigabytes-sized hash table frequently found in other PPM implementations.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2015, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].
[judges]: http://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/
-->
+18
View File
@@ -0,0 +1,18 @@
#include<stdio.h>
char*s="0 V Y b z * U . q ` E Q 7 d > A + 4 5 4 S Q b M a S p . U * & 3 m i k $ i n 1 J ` X ` 8 p p U ' 3 / K [ @ > r u h m o M T ` 4 : O w ^ x @ W o I 6 X O ; ' Q l j o K ( } [ ? x 7 P S g _ # - { W ? Z ; F w % t A O r n . q m A k e v v H C  / : - % | , # F N v { V u J d ) Z ^ +  ^ ! y + w | g A [ C v ? 5 N { K % s G Q  A s @ ? V S b b A b = 1 l D z C H q N Q f K F 9 ; j @ x 0 W l { Y w { 2 1 k _ { 9 W 8 N D R  V R ; @  % } a P 3 B # l = h 0 z x k O , G I e Z ^ [ i | / O 4 / e ? c _ x 8 j P / . - I 4 E | C . k I 0 = D C ~ h 3 A f B V F P p X B P - R U ( P e I w d = n f > > L Q L B B @ s f j B < m J % e $ F z q a 1 W V [ m e m a # ! Y x 2 X I ! E 8 & f J % , b r u A D , t $ L g L $ d g x G  _ ( Z ? t g Y > O ` @ 5 t & ' 6 F i 0 m I | a S _ V M E m W H V N O B 7 I 2 % & 2 w : / N F V n  # $ T + ] q  O + W + c q u w ~ , 5 O [ { G [ w F C _ Z 9 F ~ * l x L ' > % @ g , 8 & g m b F D [ 0 : p B ' Z # f 3 p r ; , D / F = g _ N 4 [ Y j } J 9 m _ + r c * 8 4 ] | c o ' i n ~ < p l a ~ B ( H  1 4 Z C i S 3 R  C s ' T r B , g L 4 x _ t # y U p * ~ { / r W _ d O * 1 g o w H U s Z ~ Y a ? r R X 7 Z K R p P - i l b ; i 5 _ [ ? ] X m [ 4 O # + S O * r ' Z W d ' E 7 N y b u 5 , $ o X $ J ? m : e [ ) U 8 Q , u ? E u G + 5 p ] L - y _ ; . ! s ] O X K Y s G p J R 9 G d ' i n ` % Z 9 h 0 E % z j b u > Q W P 4 r r 2 f C g r ! H x # 4 P X t ` ! , M S ^ _ C N > | e G K p ^ t ! Y Z @ O C , c ( ] # M Y H $ Z ? : , F # W T @ N W ) b L } @ + S j j 8 s ( H V j U / k - t - ] D [ ! B $ ] g > : n 3 > ] t C ( < 5 T * R ` # U q v ] & u Y b < Z C r q x H ; y H a < 7 ! t h c Y f i d f 9 ~ ^ W E Y 7 U _ 8 + l 2 w + u x ~  D ; 5 # l ' q J 7 a x - Z  v Z ? o 6 % . e ! c ' , ~ # P l = B 4 b { C k l u O / W $ K $ e i I W J 5 $ 6 y c l ) { @ % 1 % G 0 7 U B _ ( 2 $ ' [ H h B N ! i ' b C U R / 0 ! - V d V c ~ / , ~ $ _ ] i - d < _ ' Q W ( # g k + : : & F 0 Q E L N : E c w X , s & j K ' ~ W h 0 3 J , C x W j w 3 6 E d 4 j * + u } $ y # z 9 ! E R ` u G t ? [ * : U y N k 3 e G l K W i Q W 5 _ E 8 A 9 O ; - ( O D = ? W - 8 8 ( $ i c i N W 8 F U / x x | x 7 ] j H q & 5 y v 4 9 B k w v e 2 4 K 2 = W _ D / b @ * [ } } g | ) f y K L 1 B Z G 4 ) _ N > 5 ! [ 0 a % X c  * ! I g e s t ; $ + % } r Q !  X q 8 [ ( ~ W L r > X ) ` $ N { | 9 | . P P s ^ , J ! t T m q L & t z D N Q U a t 9 S ` ' @ [ 7 y A F v k ) G 4 R k C 6 S { L i , G D O F % P g w ' 0 - J C ` I _ h  4 6 ~ p H ? p [ G x H b # j s ? 4 C + a d 2 G : { L ) N : G f R a J : j @ z R 1 o 3 ~ $  u F | 8 k R y & - o 3 - J R z d I L < j E i 1 3 + _ < b _ # } h G X 8 { u k y  ' 1 Z Q @ h ~ 3 g ^ t u @ i # x L ! { = M w I w 1 : ] y N B l 3 z 9 T = n Z T p A 7 U ` U 0  I b * _ D $ K * t T t n U q f Y O P i K V 5 $ ^ $ + _ J ' c * q [ : 9 p M 1 C M 2 & 1 8  3 i % / u ; w f ( G s i } s % 0 z w G ` W A } 3 _ u ( s f Y z $ M F _ % B c * < ; 7 A j | R > b K 8 j $ U X Q Z / c { @ L ' c 8 I n ( ~ 2 < z F - } ^ M 2 t 6 r c ( | : w b 2 P O _ P & $ X - W 1 y H P B M y W # l * | j p @ a _ x c A # 2 r e ( ; 5 = V 2 / < R } s T w i b z 7 - u s g q j g N T } o a i 6 M 3 k D I S ' 6 I > ~ C o } o 1 Y + ~ x $ = r J ] [ ` O ~ z Q P ^ ^ v a O } ~ j } P z A - Z E [ Q h @ U i | B 3 F = 6 q J . J | K  f V s W W 1 | [ r [ r n c y . 3 M y ^ 5 { e w 7 5 u L @ q N - { I e W k ! U $ i . } 4 J ! p S o q s ] ` k 2 $ 8 ( C I [ P ^ 7 O : P U Z ^ @ { . N ) 4 } j + u M ] 7 = & 2 F 4 - l Q x Q F m t N , M j ' 5 = H k ^ A w : A e | / =  7 - ^ X 1 ~ B H y & @ $ k s | & G ^ X } g N B I F ; 9 p | [ W : + B < h T L o 2 f / 0 p F _ 6 f ; ) 4 ' r ~ 2 S O A g 7 0 Y Z t S t ^ ' $ k 8 F K M . [ x ; m D a S t { y 9 % P # 6 1 # d 1 r & a u ' X f ^ j % | K .  ' ` 6 ? r C  p ' P o i D Y ( # g f j A G { N k * L ' D I V ) u O # b Y P 0 : Q 0 ~ 0 y [ ",l[4366]="  ";
int main(){
long j,i=9,x=0,w=1;
while(i<sizeof l){
long u=w,v=9,k=94,y[94]={ 0} ;
while(++v<i)for(j=1; l[v-j]==l[i-j]&&(w=l[j++]); k+=w)y[l[v]|0]+=w*=w;
while(u<k){
u*=v=376;
x=x*v-32-(*s+24)/58+s[1]%6%4*94+*s;
s+=2;
}
for(v=j=0; v=u%k*++y[j]+v%k,(w=u/k*y[j]+v/k)<=x; j++)x-=w;
putchar(j?j+32:10);
l[i++]=j;
}
return 0;
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

+245
View File
@@ -0,0 +1,245 @@
09032250322503225032250101001010080100801008010100101000010000100001010010100901009010090804226042260422604226000000000000000000000000322503225009003225000000010100100100000100003226010010010002270000100001001001000001000042260422600800422600
A]G=p*:
#=0<B
G=G*2#G
H=G*3/4
I=9/:
J=1/2
#=X<2
C=0#p+2
#=p-3<X
C=C#p+3
#=Y<2
C=C#p+4
#=Z<2
C=C#p+4
#=p-3<Z
C=C#p+4
#=4*:+2<Y
C=C#p+9
#=p-4<X
A=2*:+5<Y;#=#*A
A=Y<4*:+4;#=#*A
A=1*:+1<Z;#=#*A
A=Z<3*:+5;#=#*A
C=C#p+6
A=2*:+6<Z
D=Z<2*:+8
A=A*D
D=X<4*:+3
A=A*D
D=2*:+1<X
A=A*D
D=3*:+1<Y
A=A*D
D=Y<4*:+3
#=A*D
y=Y-3*:+2
T=0:0#X-2*:+2-y*2*:+y*2+1
T=T-4*:+8
#=A*D
C=C#T
x=X-p/2
z=Z-4*:+8
#=z
t=2:x
y=4:Y/:*2
y=Y-y*:*2+:
t=y-t*:
r=3:x*x+z*z
r=r-:
r=3:t*t+r*r
#=r<1
C=C#p+3
#=0-z
t=2:0-x
t=y-t*:
r=3:x*x+z*z
r=r-:
r=3:t*t+r*r
#=r<1
C=C#p+2
R=0
q]z=Z-D/2
d=3:x*x+z*z
#=d<2*:+4
C=0#8
R=0
//torus
s]z=Z-D/2
R=D/2
r=3:x*x+y*y
x=x-x*R/r
y=y-y*R/r
d=3:x*x+y*y+z*z
#=d<2*:+4
C=C#8
#=0<r
C=0#C
R=0
B]D=p-1
x=X-D/2
R=q
C]D=p-1
x=Y-D/2
R=q
D]D=p-1
x=X-D
y=Y-D
C=0
R=s
E]D=p-1
x=X-D
y=Y
C=0
R=s
F]D=p-1
x=X
y=Y-D
C=0
R=s
G]D=p-1
x=X
y=Y
C=0
R=s
H]D=p-1
x=X
y=Y
z=Z-D/2
R=D/2
r=3:x*x+y*y
x=x-x*R/r
y=y-y*R/r
d=3:x*x+y*y+z*z
#=d<2*:+4
x=X
y=Y-D
C=0#8
R=s
v]x=X-D/2
y=Y-D/2
z=Z-D/2
y=y#0
d=3:x*x+y*y+z*z
#=d<2*:+4
C=0#8
R=0
I]D=p-1
#=Y<D/2
R=v
J]D=p-1
#=D/2<Y
R=v
//UVWXYZ
//ABCDEF
a]X=5:5
Y=5:5
X=X-1/2
Y=Y-1/2
x=5:5
y=5:5
x=x-1/2
y=y-1/2
x=x*p;y=y*p
X=X*G
Y=Y*H
Z=H/2
d=:+4
d=d*p/Z
X=X*d+x
Y=Y*d+y
Z=Z*d
U=p*p/2-x
V=p*p/2+p*4-y
W=p*3+p*:
A=0;B=0;C=0
D=1;E=1;F=1
R=0
//red
2]R=5
E=E/9
F=F/9
//blue
3]R=5
D=D/9
E=E/9
//grey
4]R=5
D=D*8/9
E=E*8/9
F=F*8/9
//diffuse ray generation
5]R=0
a=5:5
b=5:5
b=b*2
r=3:a
z=1:b
y=1:1/2+b
z=z*r
y=y*r
x=3:1-a
x=0-x*S
X=6:T
w=x;x=z;z=y;y=w
Y=6:T
w=x;x=z;z=y;y=w
Z=6:T
//light
6]R=0
A=A+D*5
B=B+E*5
C=C+F*5
P=9
//reflector
7]R=0
Y=0-Y
//golden reflector
8]R=5
D=D*8/9
E=E*4/9
F=F*2/9
A=A+D/3
B=B+E/3
C=C+F/3
//silver stars on the floor
9]R=p*p/4
u=U*7+W*3
w=U*3-W*7
x=4:u/R
z=4:w/R
x=x*R+R/2-u
z=z*R+R/2-w
r=3:x*x+z*z
#=z
t=2:x
d=1:t*5
d=d*d*d+3/2
d=d*p*2
#=r<d
R=4#7
]]old_default.ppm
Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Loaded 100 of 1683 files, more files were not shown because too many files have changed in this diff. Show more