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.
+106
View File
@@ -0,0 +1,106 @@
2015/MANIFEST
2015/Makefile
2015/burton/Makefile
2015/burton/calc.man
2015/burton/hint.html
2015/burton/hint.text
2015/burton/prog.c
2015/burton/prog.orig.c
2015/burton/road.to.obscurity
2015/burton/rule2.c
2015/burton/src.doc.rot13
2015/burton/test.in
2015/burton/test.out
2015/burton/test32.out
2015/dogon/Makefile
2015/dogon/hint.html
2015/dogon/hint.text
2015/dogon/prog.c
2015/duble/Makefile
2015/duble/codes.txt
2015/duble/hint.html
2015/duble/hint.text
2015/duble/lorem-ipsum.txt
2015/duble/prog.c
2015/duble/prog.orig.c
2015/endoh1/Makefile
2015/endoh1/center.txt
2015/endoh1/hint.html
2015/endoh1/hint.text
2015/endoh1/ioccc.txt
2015/endoh1/line.txt
2015/endoh1/prog.c
2015/endoh2/Makefile
2015/endoh2/hint.html
2015/endoh2/hint.text
2015/endoh2/prog.c
2015/endoh3/Makefile
2015/endoh3/hint.html
2015/endoh3/hint.text
2015/endoh3/ioccc.c
2015/endoh3/mullender.c
2015/endoh3/prog.c
2015/endoh4/Makefile
2015/endoh4/hint.html
2015/endoh4/hint.text
2015/endoh4/prog.c
2015/endoh4/prog.orig.c
2015/guidelines.txt
2015/hint.css
2015/hou/Makefile
2015/hou/hint.html
2015/hou/hint.text
2015/hou/prog.c
2015/howe/Makefile
2015/howe/avgtime.sh
2015/howe/hint.html
2015/howe/hint.text
2015/howe/makeholes.c
2015/howe/prog-test.sh
2015/howe/prog.c
2015/howe/prog.orig.c
2015/howe/spoiler/Makefile
2015/howe/spoiler/err.h
2015/howe/spoiler/prog.c
2015/iocccsize.c
2015/iocccsize.mk
2015/mills1/Makefile
2015/mills1/hint.html
2015/mills1/hint.text
2015/mills1/prog.c
2015/mills2/Makefile
2015/mills2/hint.html
2015/mills2/hint.text
2015/mills2/ioccc_guidelines.txt.Z
2015/mills2/ioccc_rules.txt.Z
2015/mills2/prog.c
2015/muth/Makefile
2015/muth/hint.html
2015/muth/hint.text
2015/muth/machine_beaver_4_2.h
2015/muth/machine_champ_2_4.h
2015/muth/machine_chaos_5_2.h
2015/muth/machine_cmplx_5_2.h
2015/muth/machine_count_5_2.h
2015/muth/machine_gcd.h
2015/muth/machine_great_3_2.h
2015/muth/machine_ioccc.h
2015/muth/machine_nop.h
2015/muth/machine_ru_2_4.h
2015/muth/machine_times2.h
2015/muth/prog.c
2015/muth/tape_15_50.h
2015/muth/tape_77_55.h
2015/muth/tape_empty.h
2015/muth/tape_five.h
2015/rules.txt
2015/schweikhardt/Makefile
2015/schweikhardt/hint.html
2015/schweikhardt/hint.text
2015/schweikhardt/prog.c
2015/whowon.html
2015/yang/Makefile
2015/yang/hint.html
2015/yang/hint.text
2015/yang/prog.c
2015/yang/spoiler.html
+153
View File
@@ -0,0 +1,153 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# ANSI compiler
#
# Set CC to the name of your ANSI compiler.
#
CC= cc
###############
# IOCCC winners
###############
#
WINNERS= burton dogon duble endoh1 endoh2 endoh3 endoh4 hou howe mills1 mills2 muth schweikhardt yang
###################
# 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:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
haste:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
waste:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
make:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
easter_egg:
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
# The IOCCC resident astronomer states
#
charon: supernova
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
pluto: supernova
@for i in ${WINNERS} ; do \
echo "(cd $$i && $(MAKE) $@)"; \
(cd $$i && $(MAKE) $@); \
done
+263
View File
@@ -0,0 +1,263 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-return-type -Wno-parentheses -Wno-char-subscripts \
-Wno-empty-body -Wno-cast-align -Wno-conversion \
-Wno-missing-prototypes -Wno-missing-variable-declarations \
-Wno-shadow -Wno-shorten-64-to-32 -Wno-sign-conversion \
-Wno-unused-parameter
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
#CDEFINE=
CDEFINE= -DR=return -DI=typedef -DH=unsigned -DX=long -D"W(x)=for(;x;)"
# include files that are needed to compile
#
CINCLUDE=
#CINCLUDE= -include stdlib.h
#CINCLUDE= -include stdio.h
#CINCLUDE= -include stdlib.h -include stdio.h
#CINCLUDE= -I ${X11_INCDIR}
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
LIBS=
#LIBS= -L ${X11_LIBDIR}
# 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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+78
View File
@@ -0,0 +1,78 @@
NAME
calc - an integer expression calculator that outputs in both hex and decimal
SYNOPSIS
calc [expr]
DESCRIPTION
calc presents a simple signed integer expression calculator.
The result is printed on stdout as both a decimal value and its hex equivalent.
Results are presented as 32-bit values, displaying as 64-bits only if necessary.
If the program name begins with 'e', the input is also copied to stdout.
stdin is read if there are no arguments.
Constants may be decimal, octal or hex.
There are 26 registers, initialized to zero, named A-Z;
the most recent result is always remembered in the register '.' (dot).
Assignments are silent; the character '$' will print a table of the non-zero registers.
All input is case-insensitive.
Semicolons and/or newlines separate statements.
Whitespace is ignored, except newlines cannot occur within expressions.
Comments are introduced with '#' and extend through the following newline.
Operator precedence is as found in Go:
OR and XOR are treated as additive, SHIFTing and AND are multiplicative.
This allows a more natural expression without parentheses,
as in `a&0xff | b<<8'.
Supported operations in decreasing precedence:
() forced precedence
- + ! ~ ? unary plus/minus, not, compl, byteswap
* / % & << >> >>> mul, div, mod, bitand, shift: left, right, unsigned right
+ - | ^ add, sub, bitor, xor
= assignment ([a-z] = expr)
EXAMPLES
Display the decimal value of 0x42
$ calc 0x42
66 0x00000042
What is the mask value for 22 bits?
$ calc '1<<22-1'
4194303 0x003fffff
What is the integer value of byte-swapped 0x11223344?
$ calc ?0x11223344
1144201745 0x44332211
Some canned expressions:
cat <<! | ecalc
# multiple assignments
a=32;n=10;c=50;m=100;$
7+7/7+7*7-7 # pedmas
m|a-a*3 # convenient precedence
?(1<<14|1<<9)-1<<4-1<<3
57005<<16+48879
-1 >> 32 # signed shift
-1 >>> 32 # unsigned shift
!
BUGS
An assignment with certain types of syntax error will replace the registers with a
partial evaluation:
calc 'a = 1; a; a = 3 4; a'
1 0x00000001
syntax error
3 0x00000003
Command line expressions longer than 64 characters will give a syntax error.
SEE ALSO
https://golang.org/
+217
View File
@@ -0,0 +1,217 @@
<!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 Useful</title>
</head>
<body>
<h1>Most Useful</h1>
<p>Dave Burton <a href="&#109;&#x61;&#105;&#108;&#116;&#x6f;&#58;&#x69;&#x6f;&#99;&#x63;&#x63;&#64;&#115;&#110;&#x6f;&#120;&#46;&#x6e;&#101;&#116;">&#105;&#x6f;&#99;&#99;&#x63;&#64;&#115;&#110;&#x6f;&#x78;&#46;&#110;&#x65;&#116;</a><br>
<a href="http://snox.net/ioccc">http://snox.net/ioccc</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog "expression"
</code></pre>
<p>or</p>
<pre><code>./prog
(input expressions)
</code></pre>
<h3>Try:</h3>
<pre><code>./prog '?0x3343&lt;&lt;2'
echo '?0x3343&lt;&lt;2' | ./prog
./prog
Enter:
a=0xfeedface
b=0xcafe
a &lt;&lt; 16 + b
grep '[0-9]' prog.c
./prog &lt; test.in
less calc.man
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>&ldquo;Look, Ma, no <del>hands</del> digits!&rdquo;</p>
<p>The place where some arithmetic operations are done, for example,
division or modulo, are easy to find. Where are addition and subtraction?</p>
<p>We were impressed with the level of detail the author &ldquo;blogged&rdquo; the obfuscation process.</p>
<h2>Author&rsquo;s comments:</h2>
<h2>calc - an integer expression calculator that outputs in both hex and decimal</h2>
<p>All useful tools should include sufficient documentation.
See the included man page. ;-)</p>
<h2>Notes</h2>
<p>This program is named calc. Onomatopoeia of sorts, in the visual realm.
The formatting was easier: Form Follows Function (although <a href="http://www.ioccc.org/2011/hou/hint.html" title="Hou Qiming">Hou</a> did this better).
It was tempting to call it iCalc, with i for integer (and it was written on an iDevice),
but sanity prevailed.</p>
<p>Printed in 8 pt Courier, it makes aesthetically pleasing 8.5 x 11 wall art.</p>
<h2>prog.c vs prog.orig.c</h2>
<p>Dominik Muth observed a syntax error on <code>1+1</code>, <code>1-1</code>, <code>1|1</code>, and <code>1^1</code> when using an
ARM based computer, although <code>1*1</code> and others worked correctly.
This occurs because some platforms by default treat <code>char</code> as <code>unsigned char</code>.
The original code has this weakness, which can be corrected by adding <code>-fsigned-char</code>
to the compile line.
The modified code is agnostic to <code>char</code> signed-ness.</p>
<h2>Why is this entry obfuscated/interesting?</h2>
<p>Yes, this is another calculator program.</p>
<p>However, unlike any other calculator source code the author is aware of,
this one contains no digits. At all. Anywhere. As in</p>
<pre><code>grep '[0-9]' prog.c || echo no digits!
</code></pre>
<p>Nor are the digits simply obfuscated. There are no character constants.
There is only one single, short string, and it does not contain any obfuscated digits.
And yet the output is in decimal and hexadecimal, and it accepts octal, decimal, and hex input.</p>
<p>Flow control is by <code>for</code> and <code>return</code>. It is If-less. Switch-less. While-less. Hope-less. <br>
Literally, if not figuratively. ;-)</p>
<p>The code size is intentionally 2015, as stated by iocccsize -i,
and can be reformatted without changes (as in rule2.c) to exactly 4096 octets.</p>
<p>Finally, calc is interesting, if for no other reason than it is practically useful:
Hex/decimal conversion, arithmetic, byte-swapping, bit-shifting, and logical operations with memory,
on the command line, or interactively.</p>
<h2>But the question is why is the entry obfuscated?</h2>
<p>The code follows many industry best-practices:</p>
<ul>
<li><p>You know what it does just by looking at it.</p></li>
<li><p>Numbers and digits have often been used for obfuscation,
so in a bid for better clarity, this code has no digits at all.</p></li>
<li><p>In the spirit of clarity, most of the variables are declared before use, so they
are readily visible, with single letter names that don&rsquo;t clutter the screen,
in a tautological arrangement.</p></li>
<li><p>More helpful is the use of <code>typedef</code>s instead of <code>#define</code>, so the types remain useful
even in the debugger, and source code beautifiers will not undo careful presentation.</p></li>
<li><p><code>#defines</code> are used here in the best spirit of the preprocessor: to shorten
repetitive constructs, not for obscurity.</p></li>
<li><p>All functions are short (and therefore easy to understand?) and do only one thing, well, &hellip;.</p></li>
<li><p>Curly braces invite endless holy wars over readability. This code only uses them
for function definitions, thereby greatly improving readability, and reducing arguments
about said readability.</p></li>
<li><p>One of C&rsquo;s many blessings (until recently) is a modicum of keywords,
of which only 8 are used:
<code>for</code>, <code>return</code>, <code>typedef</code>, <code>void</code>, <code>char</code>, <code>short</code>, <code>unsigned</code> and <code>long</code>;
10 if <code>#include</code> and <code>#define</code> are counted.</p></li>
<li><p>The code helpfully declares &ldquo;syntax_error!&rdquo; right up front, filling the reader with confidence.</p></li>
<li><p>In spite of its inherent clarity, the code was presented to both <em>indent</em>(1) and
<em>clang-format</em>(1), after running it through the preprocessor, sustaining its better qualities.</p></li>
<li><p>That the code is obfuscated is spelled out two different ways in the source; it helps
to reformat the code to see the second spelling.</p></li>
<li><p>The author is overly fond of the code that handles input.
There is no memory allocation, nor pre-allocation of arrays, so where does the
memory come from? The multi-base strtol() code is pretty trick.
No special attempt was made to replace operations with obscure mathematical relations,
as the (lack of) beauty is in the parsing &ndash; ask not where is the modulus operation,
but how does it know when to mod &ndash; okay, but where is add and subtract?
And really, who doesn&rsquo;t enjoy a setjmp() in the argument list?</p></li>
<li><p>Finally, documentation of the source code structure is helpfully provided in rot13 format.
But isn&rsquo;t it unsportsmanlike to rely upon it? However, even with this helpful guide,
things like reading input lines remain as tricky to read as they are to write.</p></li>
</ul>
<h2>Compiler warnings</h2>
<p>Calc is C99 compliant, and is ANSI/C90 compliant except for wanting 64-bit <code>long long</code>.
Changing the two <code>long long</code> typedefs to <code>long</code>, and compiling with <code>gcc -m32</code>
yields a program that operates on 32-bit values, with wrap-around of shifts mod 32:</p>
<pre><code>1&lt;&lt;48
65536 0x00010000
</code></pre>
<p>gcc 4.2.1 without arguments compiles cleanly (e.g. cc prog.c -o prog).
This is my workaday compiler. gcc is also clean with -ansi, and -std=c99.</p>
<p>clang 3.6.0 lives up to its namesake, resounding on non-problems.
To stifle these complaints:
-Wno-return-type -Wno-parentheses -Wno-empty-body</p>
<p>When invoked with -ansi -pedantic, there are two warnings, which can be ignored:</p>
<ul>
<li><code>ISO C90 does not support 'long long'</code></li>
</ul>
<p>With -Wall -std=c99, both are quite noisy, and all can be ignored:</p>
<ul>
<li><code>array subscript has type 'char' [-Wchar-subscripts]</code></li>
<li><code>value computed is not used [-Wunused-value]</code></li>
<li><code>operation on 'j' may be undefined [-Wsequence-point]</code></li>
</ul>
<h2>Test Suite</h2>
<p>If the program name begins with an &ldquo;e&rdquo;, it echoes stdin to stdout.
This allows for a convenient test suite:</p>
<pre><code>ln -s prog eprog
PATH=. eprog &lt; test.in | diff - test.out
</code></pre>
<h2>Spoilers</h2>
<p>If you do not want to puzzle out how it works, see spoilers.markdown.</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+202
View File
@@ -0,0 +1,202 @@
# Most Useful
Dave Burton <ioccc@snox.net>
<http://snox.net/ioccc>
## Judges' comments:
### To use:
make
./prog "expression"
or
./prog
(input expressions)
### Try:
./prog '?0x3343<<2'
echo '?0x3343<<2' | ./prog
./prog
Enter:
a=0xfeedface
b=0xcafe
a << 16 + b
grep '[0-9]' prog.c
./prog < test.in
less calc.man
### Selected Judges Remarks:
"Look, Ma, no ~~hands~~ digits!"
The place where some arithmetic operations are done, for example,
division or modulo, are easy to find. Where are addition and subtraction?
We were impressed with the level of detail the author "blogged" the obfuscation process.
## Author's comments:
calc - an integer expression calculator that outputs in both hex and decimal
----------------------------------------------------------------------------
All useful tools should include sufficient documentation.
See the included man page. ;-)
Notes
-----
This program is named calc. Onomatopoeia of sorts, in the visual realm.
The formatting was easier: Form Follows Function (although [Hou][1] did this better).
It was tempting to call it iCalc, with i for integer (and it was written on an iDevice),
but sanity prevailed.
Printed in 8 pt Courier, it makes aesthetically pleasing 8.5 x 11 wall art.
[1]: http://www.ioccc.org/2011/hou/hint.html "Hou Qiming"
prog.c vs prog.orig.c
---------------------
Dominik Muth observed a syntax error on `1+1`, `1-1`, `1|1`, and `1^1` when using an
ARM based computer, although `1*1` and others worked correctly.
This occurs because some platforms by default treat `char` as `unsigned char`.
The original code has this weakness, which can be corrected by adding `-fsigned-char`
to the compile line.
The modified code is agnostic to `char` signed-ness.
Why is this entry obfuscated/interesting?
-----------------------------------------
Yes, this is another calculator program.
However, unlike any other calculator source code the author is aware of,
this one contains no digits. At all. Anywhere. As in
grep '[0-9]' prog.c || echo no digits!
Nor are the digits simply obfuscated. There are no character constants.
There is only one single, short string, and it does not contain any obfuscated digits.
And yet the output is in decimal and hexadecimal, and it accepts octal, decimal, and hex input.
Flow control is by `for` and `return`. It is If-less. Switch-less. While-less. Hope-less.
Literally, if not figuratively. ;-)
The code size is intentionally 2015, as stated by iocccsize -i,
and can be reformatted without changes (as in rule2.c) to exactly 4096 octets.
Finally, calc is interesting, if for no other reason than it is practically useful:
Hex/decimal conversion, arithmetic, byte-swapping, bit-shifting, and logical operations with memory,
on the command line, or interactively.
But the question is why is the entry obfuscated?
------------------------------------------------
The code follows many industry best-practices:
- You know what it does just by looking at it.
- Numbers and digits have often been used for obfuscation,
so in a bid for better clarity, this code has no digits at all.
- In the spirit of clarity, most of the variables are declared before use, so they
are readily visible, with single letter names that don't clutter the screen,
in a tautological arrangement.
- More helpful is the use of `typedef`s instead of `#define`, so the types remain useful
even in the debugger, and source code beautifiers will not undo careful presentation.
- `#defines` are used here in the best spirit of the preprocessor: to shorten
repetitive constructs, not for obscurity.
- All functions are short (and therefore easy to understand?) and do only one thing, well, ....
- Curly braces invite endless holy wars over readability. This code only uses them
for function definitions, thereby greatly improving readability, and reducing arguments
about said readability.
- One of C's many blessings (until recently) is a modicum of keywords,
of which only 8 are used:
`for`, `return`, `typedef`, `void`, `char`, `short`, `unsigned` and `long`;
10 if `#include` and `#define` are counted.
- The code helpfully declares "syntax_error!" right up front, filling the reader with confidence.
- In spite of its inherent clarity, the code was presented to both *indent*(1) and
*clang-format*(1), after running it through the preprocessor, sustaining its better qualities.
- That the code is obfuscated is spelled out two different ways in the source; it helps
to reformat the code to see the second spelling.
- The author is overly fond of the code that handles input.
There is no memory allocation, nor pre-allocation of arrays, so where does the
memory come from? The multi-base strtol() code is pretty trick.
No special attempt was made to replace operations with obscure mathematical relations,
as the (lack of) beauty is in the parsing -- ask not where is the modulus operation,
but how does it know when to mod -- okay, but where is add and subtract?
And really, who doesn't enjoy a setjmp() in the argument list?
- Finally, documentation of the source code structure is helpfully provided in rot13 format.
But isn't it unsportsmanlike to rely upon it? However, even with this helpful guide,
things like reading input lines remain as tricky to read as they are to write.
Compiler warnings
-----------------
Calc is C99 compliant, and is ANSI/C90 compliant except for wanting 64-bit `long long`.
Changing the two `long long` typedefs to `long`, and compiling with `gcc -m32`
yields a program that operates on 32-bit values, with wrap-around of shifts mod 32:
1<<48
65536 0x00010000
gcc 4.2.1 without arguments compiles cleanly (e.g. cc prog.c -o prog).
This is my workaday compiler. gcc is also clean with -ansi, and -std=c99.
clang 3.6.0 lives up to its namesake, resounding on non-problems.
To stifle these complaints:
-Wno-return-type -Wno-parentheses -Wno-empty-body
When invoked with -ansi -pedantic, there are two warnings, which can be ignored:
* `ISO C90 does not support 'long long'`
With -Wall -std=c99, both are quite noisy, and all can be ignored:
* `array subscript has type 'char' [-Wchar-subscripts]`
* `value computed is not used [-Wunused-value]`
* `operation on 'j' may be undefined [-Wsequence-point]`
Test Suite
----------
If the program name begins with an "e", it echoes stdin to stdout.
This allows for a convenient test suite:
ln -s prog eprog
PATH=. eprog < test.in | diff - test.out
Spoilers
--------
If you do not want to puzzle out how it works, see spoilers.markdown.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+110
View File
@@ -0,0 +1,110 @@
#include<stdio.h>
#include<setjmp.h>
#define R return
#define W(x)for(;x;)
#define I typedef
#define H unsigned
I jmp_buf J;
I void P;
I char L;
I int Q;
I H C;
I long long V;
I H char O;
I H short Y;
I H long long Z;
O S[]="syntax_error!"
"M@K~|JOEF\\^~_NHI]"; L*N,*K,*
B,*E,*T,*A,*x,D; Q(*k)(),v; V z(P),j,_,*
o,b,f,u,s,c,a,t,e,d; J l; Q _k(P){ R*K?*K++:
~-d; } V r(L a){ R a&&putchar(a); } L n(){ R*T=j=
k(),++j; } O G(P){ *o=d,longjmp(l,b); } Z g(Y a){ R a
>>s|(a&~-e)<<s;} C p(L*T) { W(r(*T++)); *--T-c&&r(c);} L m
(P){ W(!((v=A[*T++])-f)); R v; } P q(L**N) { O*q; b=!b; f=-~b;
u=f|b; s=b<<u; c=s|f; a=s<<f; t=-~u; e=a
<<u; D=v=u<<t;q=S +c-~t; q[~s]=a;
q--[f]+=a;q--[c ]+=a; B=(L*)
N+~e*e;x=B+e ; A=B+e/f;
o=(V*)(x+a ); A[-
~s]=f; T =K =A-
a*f;A[*-- q]=c+
c; *q=! c; W
(++j&&* ++q)
A[*q-a ]=j;
W(v<D +c)
x[v- D]=
v,A[ v++
]=j; ++j
,v= D=e/
t; W(++
v<= D+f*
u)x [v-D+~
-c]= v|a,A[
v]=A [v|a]=j;
W(( A[v]=A[v|a
]=j ,++v<a*u+~t));
for( ; E=*++N;T[~d]
=a)W (*T++=*E++);k=
T
-K?_k:
getchar; } Z h
(C a){ R(g(a)<<s*
f)+g(a>>s*f); } P _i (L*T)
{ *o||p(T); } V _b(V a ){ Z e=a
; R A[*T++]!=v+c?G():~-v ?a<<z():c-A
[*T++]+b ?--T,a>> z():e>>z();}
V _c(L* l){ T=B +a; W(j)*T--
=v+j%c ,j/=c; E=B+ (*B==
a+c+u );W(T< B+a)*
E++=* ++T; T =E ;
l-B&& ++ *-- E; }
P M( Z k){ L*p,e
=a>> u; m ()&&G(
); p =T=B ; _=j=k
; v=u <<t,* T=a; j<d
&&(*T+++=c+u,j=j==-j?++p,--j:-j);!j?*T++=
v:_c(p); *T++=-~s; *T++=v;*T++=a*t-s; p=T
; E=T+=s*f; W(k)*T--=x[k&~-a/f],k>>=e; W(T
-e*f>p)*T--=v; W(T<E)*p++=*++T; *p=d;} P U
(L*E){ V*N=o,f; *E=f=d; W(++f<c*u-u)*++N
&&(M(*N),r(f+a*u),r(-~s),p(B),*(T=E)=d)
; } V w(P){ L*S=N,*x=N; E=T=B; E+=a
<<f;
W(T
<E
&&n( ))*
T==a -~u
?U(T),T:*T==c?E=S?T=S:T:S?T:*T==(a|u)?S=T:*T==a*f-c/f?E=T:!x&&A[*T]!=f?x=T++:
++T; *T=d;R j&&!x?w():T-B; } P _d(V e){ L T=c*f-f;V o=j*e+v; D=d; A[v]==T++?D
=u<<t:e>c&&A[v]==T++&&(v|a)-a*-~f<~-s?D=b+(v&a)+a*f-c:d; D&&(j=o-D); }V y(P){
V a=z();W(m()&&v<c+f&&(v-=u<<b)>=d)v?v-b?v-f?v-u?v-=t,a=_b(a):(a&=z()):(a%=z(
)):(a/=z()):(a*=z()); R--T,a;} V _f(P){ V e=c; j=d; D=b; *T==u<<t&&(e-=f)&&(*
++T|a)>>f==a-f&&(e<<=b)&&T++; W(D&&(v=*T++))_d(e); R--T,j; } V F(P){ V n=y();
W(m()&&v<u*f)v<t?n+=(v-f)*y():v-b^t?n^=y():(n|=y()); R--T,n; } V i(Z n){R n>>
a/f?
n>>a
?h(n)<<a|h(n>>a
):h(n):g(n); } Q main(Q x
,L**K){ V*A; q(K); W(w())**
K-c*c-b||p(B),_i(!setjmp(l)?T=B
,M(((A=(*o=m()==c-~s&&(j=a|T[-b])&&
s-m()==~s)?&o[j-a*u]:(T=B,&_)),*A=F())
),B:(L*)S); } V z(P){ V
s; W(m() &&v<=f*c
)R v<t ?(v-f)*
z():( v-=u<<
f)<f ?v?--v
?G() : i(z(
)):~ z( ):
(v-= f) <u
?v?s = F()
,m() ==a>>
b?s :G ():
_:! (v-=
t)? --T,_f
(): v-f?o[
(T[ -b]|a)-
a*u]: !z();
G(); }
+110
View File
@@ -0,0 +1,110 @@
#include<stdio.h>
#include<setjmp.h>
#define R return
#define W(x)for(;x;)
#define I typedef
#define H unsigned
I jmp_buf J;
I void P;
I char L;
I int Q;
I H C;
I long long V;
I H char O;
I H short Y;
I H long long Z;
O S[]="syntax_error!"
"M@K~|JOEF\\^~_NHI]"; L*N,*K,*
B,*E,*T,*A,*x,D,v; Q(*k)(); V z(P),j,_,*
o,b,f,u,s,c,a,t,e,d; J l; Q _k(P){ R*K?*K++:
~-d; } V r(L a){ R a&&putchar(a); } L n(){ R*T=j=
k(),++j; } O G(P){ *o=d,longjmp(l,b); } Z g(Y a){ R a
>>s|(a&~-e)<<s;} C p(L*T) { W(r(*T++)); *--T-c&&r(c);} L m
(P){ W(!((v=A[*T++])-f)); R v; } P q(L**N) { O*q; b=!b; f=-~b;
u=f|b; s=b<<u; c=s|f; a=s<<f; t=-~u; e=a
<<u; D=v=u<<t;q=S +c-~t; q[~s]=a;
q--[f]+=a;q--[c ]+=a; B=(L*)
N+~e*e;x=B+e ; A=B+e/f;
o=(V*)(x+a ); A[-
~s]=f; T =K =A-
a*f;A[*-- q]=c+
c; *q=! c; W
(++j&&* ++q)
A[*q-a ]=j;
W(v<D +c)
x[v- D]=
v,A[ v++
]=j; ++j
,v= D=e/
t; W(++
v<= D+f*
u)x [v-D+~
-c]= v|a,A[
v]=A [v|a]=j;
W(( A[v]=A[v|a
]=j ,++v<a*u+~t));
for( ; E=*++N;T[~d]
=a)W (*T++=*E++);k=
T
-K?_k:
getchar; } Z h
(C a){ R(g(a)<<s*
f)+g(a>>s*f); } P _i (L*T)
{ *o||p(T); } V _b(V a ){ Z e=a
; R A[*T++]!=v+c?G():~-v ?a<<z():c-A
[*T++]+b ?--T,a>> z():e>>z();}
V _c(L* l){ T=B +a; W(j)*T--
=v+j%c ,j/=c; E=B+ (*B==
a+c+u );W(T< B+a)*
E++=* ++T; T =E ;
l-B&& ++ *-- E; }
P M( Z k){ L*p,e
=a>> u; m ()&&G(
); p =T=B ; _=j=k
; v=u <<t,* T=a; j<d
&&(*T+++=c+u,j=j==-j?++p,--j:-j);!j?*T++=
v:_c(p); *T++=-~s; *T++=v;*T++=a*t-s; p=T
; E=T+=s*f; W(k)*T--=x[k&~-a/f],k>>=e; W(T
-e*f>p)*T--=v; W(T<E)*p++=*++T; *p=d;} P U
(L*E){ V*N=o,f; *E=f=d; W(++f<c*u-u)*++N
&&(M(*N),r(f+a*u),r(-~s),p(B),*(T=E)=d)
; } V w(P){ L*S=N,*x=N; E=T=B; E+=a
<<f;
W(T
<E
&&n( ))*
T==a -~u
?U(T),T:*T==c?E=S?T=S:T:S?T:*T==(a|u)?S=T:*T==a*f-c/f?E=T:!x&&A[*T]!=f?x=T++:
++T; *T=d;R j&&!x?w():T-B; } P _d(V e){ L T=c*f-f;V o=j*e+v; D=d; A[v]==T++?D
=u<<t:e>c&&A[v]==T++&&(v|a)-a*-~f<~-s?D=b+(v&a)+a*f-c:d; D&&(j=o-D); }V y(P){
V a=z();W(m()&&v<c+f&&(v-=u<<b)>=d)v?v-b?v-f?v-u?v-=t,a=_b(a):(a&=z()):(a%=z(
)):(a/=z()):(a*=z()); R--T,a;} V _f(P){ V e=c; j=d; D=b; *T==u<<t&&(e-=f)&&(*
++T|a)>>f==a-f&&(e<<=b)&&T++; W(D&&(v=*T++))_d(e); R--T,j; } V F(P){ V n=y();
W(m()&&v<u*f)v<t?n+=(v-f)*y():v-b^t?n^=y():(n|=y()); R--T,n; } V i(Z n){R n>>
a/f?
n>>a
?h(n)<<a|h(n>>a
):h(n):g(n); } Q main(Q x
,L**K){ V*A; q(K); W(w())**
K-c*c-b||p(B),_i(!setjmp(l)?T=B
,M(((A=(*o=m()==c-~s&&(j=a|T[-b])&&
s-m()==~s)?&o[j-a*u]:(T=B,&_)),*A=F())
),B:(L*)S); } V z(P){ V
s; W(m() &&v<=f*c
)R v<t ?(v-f)*
z():( v-=u<<
f)<f ?v?--v
?G() : i(z(
)):~ z( ):
(v-= f) <u
?v?s = F()
,m() ==a>>
b?s :G ():
_:! (v-=
t)? --T,_f
(): v-f?o[
(T[ -b]|a)-
a*u]: !z();
G(); }
+231
View File
@@ -0,0 +1,231 @@
Development of the obfuscated calculator.
--------------------------------------------------
I wanted to enter the IOCCC....
I think I can write something clever. Possibly even obscure. The competition is fierce,
but not a closed door.
I needed an interesting program, that had a reasonable chance of begin shrunk within 4096 bytes,
and lent itself to obfuscation. I had been revisiting utilities I've written over
the years. One useful program was calc, a simple recursive descent signed integer
expression parser I developed from first principles as a demonstration of how computers
work for my son. That program did the basic four operations, but as a programmer,
I needed more, so those were added over time.
Calc is a useful, functioning utility. The operators before the obfuscation dance began
(this is called fore-shadowing):
() forced precedence
- ~ ? unary minus, compl, byteswap
* / % & << >> mul, div, mod, bitand, shift: left, right
+ - | ^ add, sub, bitor, xor
NUM 0-9
This seemed like a reasonable candidate to experiment with obfuscation; perhaps it might
yield good results.
Principle of operation
--------------------------------------------------
The algorithm was and is rather straightforward:
expr() {
n = term()
t = token()
if (t == ADD) return n += expr()
if (t == SUB) return n -= expr()
if (t == BOR) return n |= expr()
if (t == XOR) return n ^= expr()
ungettoken(t)
return n
}
term() {
n = factor()
t = token()
if (t == MUL) return n *= term()
if (t == DIV) return n /= term()
if (t == AND) return n &= term()
if (t == RSH) return n >> term()
if (t == LSH) return n << term()
ungettoken(t)
return n
}
factor() {
t = token()
if (t == LPAREN) {
n = expr()
if token() == RPAREN
return n
error()
}
if (t == SUB) return -factor()
if (t == CMP) return ~factor()
if (t == QUE) return byteswap(factor())
if (t == DIG) return strtol()
error()
}
Obfuscation is a process
--------------------------------------------------
Within the above algorithm, there are many details unmentioned, all ripe for obfuscation:
- input
- tokenization
- atoi input values
- sprintf results
- error recovery
- swapping bytes
- user interface (command line vs stdin)
Uncertain as to how this would progress, I started obfuscating/condensing everything
except the conversion operations, leaving those to sprintf() and strtol(). The first
version of the obfuscated code used an homage to 1984 anon for I/O, and it featured a
#define for else's and the types, to help minimize the repetition. And of course, most
functions were renamed with one or two letters, and most of the variables became single
letter globals. Tokenization was rather easy with a declared array, just initialized with
unique values for each.
This was when the obfuscation took a turn for the better (worse): it was easy to hide the
operations via a simple transformation. The code now dealt with small integer values
instead of direct ASCII representation of the operations. And the strings where collapsed
into a single combined error message and operator tokenization table. This was relatively
obscure.
Next, sprintf() was replaced with a custom formatter. This was rather simple, but at least
the formatting was not obvious. Formatting and printing were split early. strtol() was
replaced with custom logic, limited to 3 practical bases: octal, decimal, and hex. The
last result was remembered in a special variable, dot.
By this time, I had a version which I considered obscure, and shared this early version
with a couple of colleagues for comments. I suggested I could improve the obfuscation of
a term() and factor(), and would like to have assignable memories.
This code was pretty dense, but inspired by previous IOCCC entries, I thought I might get
rid of all the else's, which showed the structure of the parser rather clearly. Investing
in the ternary operator, the code got quite a bit more difficult to follow, used only
for-loops, and I had to start taking notes to follow it. This was a good sign! ;-)
I started testing the code. I wrote a test suite to ensure the changes I made did not
corrupt the processing (oh so easy to do with this obfuscated mess). Why does -1>>32
yield -1? Oh, yeah: signed arithmetic. Enter Java's unsigned shift: >>>. Better. But
with more features, more to get wrong, and harder to know which expression is causing the
error. The easy solution: if the name begins with 'e', echo the input. Now I can see the
failing expression. Wait, what is this test expression supposed to be testing?
Wouldn't it be nice to have comments?
Adding new functionality to an obscure program is ... going about it backwards. Get the
functionality correct and complete, THEN obscure. Sounds obvious, but that did not
happen. I got comments working, then desired to have multiple statements on a single
line (read: semicolon expression terminators). This involved quite a bit of rework of
the input code, but now allowed very convenient user interaction.
Better Obscurity is a laborious process
--------------------------------------------------
Satisfied with the functionality, but unsatisfied with the obscurity, I pondered if I
could get rid of all the constants? This had not been done before (to my knowledge), and
I was able to work out the how-tos and the compromises. Now I can no longer declare my
arrays, I have to allocate them. Obscurity now increased!
But wouldn't it be nice to have assignable memories?
Around this time, the formatted code no longer fit with the 2053 limit (due to a lack of
comprehension of the significance of the space-after-brace-and-semi rule, and a layout
program that did not know how to do this). Frustrated, I wrote another program to
reformat this code into rule2.c, which was a single C token per line. This solved the
formatting problem, but intriguingly introduced another. Now I was faced with the 4096
rule as well as the 2053 rule. But this was a challenge!
I wrote a de-obfuscator, and worked on both the unobfuscated version and the master code.
I worked on the template formatter to make this as automated as possible, and worked to
achieve both a perfectly presented picture AND the single-line exactly-at-4096 rule2.c.
Finally, "perfection", with assignable memories! Where perfection is defined as a nicely
formatted picture at less than 2053, and exactly 4096 token-per-line rule2.c.
Testing Testing Testing
--------------------------------------------------
Cross platform, it works on Mac OSX, fails on Linux. It works if #include <stdlib.h>, but
it dumps core without it (the only change!)?. 64bits without proper declaration of ints
in syscalls yields unpredictable results. 32bit compilation showed problems with byte-
swapping in using addition versus bitwise-or. In 32bit land, x<<32 == x, so x<<32 + x>>32
does not yield the desired result, but x<<32 | x>>32 does (with appropriate care and
feeding). And the different compilers on different hosts complained loudly and
differently, although all produced correct bits in spite of the noise.
Further, the program did not do UNIX pipelines well, due to the unbuffered homage code
(byte-at-a-time I/O), of which write() was also the source of the portability problem.
Replace write() with getchar()/putchar(), and it piped well but lost some obscurity and
no longer paid (direct) homage to history.
Another problem: only one expression at a time was allowed on the command line, no semis,
no comments, and it turns out $2, $3, ... were not handled correctly. Given the new I/O
code, it was now possible to copy the command line arguments into a buffer, and write a
small routine to retrieve bytes from this buffer like getchar(). Voila! Better obfuscation
with much better functionality!
But wouldn't it be nice to show what the current variables hold?
Bytes are now hard to find to keep exactly at 4096, and adding functionality to obscured
code is not easy. Restructuring the logic to gain the bytes necessary, code to display
the variables was added.
Test. Test. Test. Oh, noes! More bugs! Typing "1 + 2 5" yields 3, but no syntax error.
"g = 1" yields a syntax error, and "0xg" does not! ")" causes a seg fault! Why didn't I
test these before I started obfuscating?! By this point, everything I did to the code
perturbed the 4096 bytes, all variables were already a single character, and it was really
difficult to follow the logic in a debugger (single-stepping an expression did the entire
line of code, even if it involved multiple statements -- and it did, everywhere, even in
the unobfuscated version; think: a complex chain of ternary expressions is a single
statement). This involved careful examination of all the expressions within the logic,
trying to find a different way of getting the same result, but typically within fewer
bytes than before to allow for the added logic to fix the bugs.
The bugs were fixed, the code re-formatted, and rule2.c was again 4096 bytes.
But wouldn't it be nice for unary plus to work?
Add unary plus, re-balance. Little things now take a fair bit of work. Adding anything
requires taking away in others, but since all the logic is functional, this means
rewriting the logic to be more concise. After several rounds of this, bytes are scarce to
come by.
But wouldn't it be nice for assignments to be silent?
Made them silent (easier said than done!). Why does "1 + 2 5" print a syntax error, but
"a = 1 + 2 5" does not? Rewrite(!) the assignment logic -- and this requires more bytes!
Better Obscurity Through Simplification
--------------------------------------------------
Except there were not enough bytes to do this, unless #include <unistd.h> is removed. But
then sbrk() must be declared, eating into the savings. If only there were 512 bytes of
memory already allocated that could be portably touched for free....
Light bulb! Memory allocation was excised, and the code became more obscure.
It was working again! It formats beautifully, it compiled cleanly (with apropos
-Wno-guards), it remains obscure after cpp and clang-format, it measures within the limits
and exactly at 4096 (this latter was really getting challenging to maintain). No more bugs
known, it is feature complete, documentation written.
But wouldn't it be nice to have a logical not?
Sigh. This was the last operation added. Another round of code churn, expressions are
difficult to rewrite because they are both obscure and relatively tight. But changing
around the stable initialization code -- by now the largest piece of logic -- yielded the
necessary bytes, and improved obscurity by double duty encoding of the operations
initialization.
The utility is now truly functional, and feature complete, and obscure. Without src.doc
(basic documentation of the code structure), and some commented expanded logic stashed away,
and the familiarity I have with the code having written and revised it repeatedly, I would
not even want to attempt to decipher the logic. Many times in the debugging, I was thwarted
by my own obfuscations, and went down blind paths in trying to fix a bug or add functionality.
Now I think I have a good entry.
But wouldn't it be nice to import pre-set definitions from a file?
+1875
View File
File diff suppressed because it is too large. Load diff
+67
View File
@@ -0,0 +1,67 @@
zrzbel znc: O [128,v/b] N [128,gbxraf] k [32,urkpbai] b [224,ertvfgref]
Zrzbel vf "nyybpngrq" sebz gur fgnpx, ol gnxvat n ybpny (fgnpx) inevnoyr
naq fhogenpgvat 64x -- gurerol yrnivat cyragl bs ebbz sbe rira eryngviryl
ynetr fgnpx senzrf qhevat erphefvba.
v znva(v,p**) cnefr pbzznaq yvar be fgqva, nffvtazragf, cevag erfhyg, reebe erpbirel
v64 _ qbg
p *N yrkvpny gbxraf
p *O vachg ohssre
gq P hafvtarq
p Q fbzr fgngr orgjrra shapf
p *R reebe fgevat, raq cbvagre
v64 S() rkce: + - ^ |
hp T() aba-ybpny tbgb
#q U hafvtarq
#q V glcrqrs
gq W wzc_ohs
p *X cbvagre gb pzq yvar netf
gq Y pune
i Z(h64) qrgrpg reebef, fnir nafjre va qbg, sbezng erfhyg va qrpvzny naq urk
p *A serrovr ahyy cbvagre
gq B hafvtarq pune
gq C ibvq
gq D vag
#q E erghea
p F flagnk reebe + gbxraf
p *G pheerag gbxra cbvagre
i H(p*) cevag gur ertvfgref
gq I ybat ybat
#q J(k) sbe(;k;)
gq K ybat - bayl sbe ehyr2fc.p
gq L hafvtarq fubeg
gq M hafvtarq ybat ybat
v64 n qrevirq: 32
v64 o qrevirq: 1
v64 _o(v64) grez: << >> >>>
v64 p qrevirq: 10
v64 _p(p*) pbaireg ovanel tybony w gb nfpvv qrpvzny
v64 q serrovr: 0
i _q(v64) npphzhyngr pbairegrq nfpvv olgrf vagb w va onfr cnffrq va
v64 r qrevirq: 256
v64 s qrevirq: 2
v64 _s() pbaireg sebz nfpvv gb ovanel: fryrpgf pbaireg onfr (10,8,16), erfhyg va w
h64 t(h16) olgr fjnc 16-ovgf
h64 u(h32) olgr fjnc 32-ovgf
v64 v(h64) fryrpg fvmr naq olgr fjnc zvavzny olgrf
i _v(p*) pbaqvgvbany cevag
v64 w ubyqf cnegvny/npphzhyngrq erfhygf
*() x cge-gb-shap-trgpune
v _x() trg punef sebz fnirq pzq yvar
wo y sbe cnefre reebe erpbirel
p z() fpnaf vachg sbe gbxra, vtaberf juvgrfcnpr
p a() trg arkg vachg punenpgre
v64 *b ertvfgref
h32 c(p*) jevgrf gb fgqbhg hagvy ahyy, arjyvar nccraqrq vagryyvtragyl
i d(**) vavg
v64 e(p) jevgrf p gb fgqbhg
v64 f qrevirq: 8
v64 g qrevirq: 4
v64 h qrevirq: 3
p i pheerag vachg gbxra
v64 j() ernq sebz fgqva hagvy arjyvar be frzv, fxvcf oynax yvarf + pbzzragf, erghea yra
p *k ncgyl anzrq urk pbairefvba gnoyr
v64 l() grez: * / % & (<< >> >>>)
v64 m() snpgbe ~ ! ? -/+ () INE AHZ QBG
+84
View File
@@ -0,0 +1,84 @@
# comments and blank lines are skipped
# factors
1
-1
-2
~0
~1
~-1
?0x1234
?0x12345678
?0x1122334455667788
?0xffff1234
?0xffffffff1234
?0xffffffffffff1234
# terms
1+1
1 + 1
1 - 1
2 * 2
3 / 3
4 % 3
5 & 6
6 | 7
7 ^ 1
8 << 2
9 >> 2
-1 >> 32
-1 >>> 32
1 << 63
# expressions
1<<63 -1
1<<63+1
?.
( 4 + 3) * 5 - 1
~.
# syntax errors
4**5
1+(4*3
# byte swwapping
0xff00ff00
?.
. >> 1
. >> 2
. >> 3
. >> 4
?0xff00ff00
. << 1
. << 2
. << 3
. << 4
~0
0xABCD
# multiple statements per line, unary +, case indifference
1<<5;.+10;a=?.
+2
+3
a>>8
0xAbC00+.
# syntax errors found late
)
0xfgh
0xg;0xG;0xh;0xI
1+2 4
a = 1+2 4
a=1;b=2;c=3;d=4;e=5;f=6;g=7;h=8
# careful!
a=0x11223344<<32
b=a+0x55667788
a
?b
$
!0
!3
!z
!a
+151
View File
@@ -0,0 +1,151 @@
1
1 0x00000001
-1
-1 0xffffffffffffffff
-2
-2 0xfffffffffffffffe
~0
-1 0xffffffffffffffff
~1
-2 0xfffffffffffffffe
~-1
0 0x00000000
?0x1234
13330 0x00003412
?0x12345678
2018915346 0x78563412
?0x1122334455667788
-8613303245920329199 0x8877665544332211
?0xffff1234
873660415 0x3412ffff
?0xffffffff1234
3752342914529689600 0x3412ffffffff0000
?0xffffffffffff1234
3752342914529755135 0x3412ffffffffffff
1+1
2 0x00000002
1 + 1
2 0x00000002
1 - 1
0 0x00000000
2 * 2
4 0x00000004
3 / 3
1 0x00000001
4 % 3
1 0x00000001
5 & 6
4 0x00000004
6 | 7
7 0x00000007
7 ^ 1
6 0x00000006
8 << 2
32 0x00000020
9 >> 2
2 0x00000002
-1 >> 32
-1 0xffffffffffffffff
-1 >>> 32
4294967295 0xffffffff
1 << 63
-9223372036854775808 0x8000000000000000
1<<63 -1
9223372036854775807 0x7fffffffffffffff
1<<63+1
-9223372036854775807 0x8000000000000001
?.
72057594037928064 0x100000000000080
( 4 + 3) * 5 - 1
34 0x00000022
~.
-35 0xffffffffffffffdd
4**5
syntax error
1+(4*3
syntax error
0xff00ff00
4278255360 0xff00ff00
?.
16711935 0x00ff00ff
. >> 1
8355967 0x007f807f
. >> 2
2088991 0x001fe01f
. >> 3
261123 0x0003fc03
. >> 4
16320 0x00003fc0
?0xff00ff00
16711935 0x00ff00ff
. << 1
33423870 0x01fe01fe
. << 2
133695480 0x07f807f8
. << 3
1069563840 0x3fc03fc0
. << 4
17113021440 0x3fc03fc00
~0
-1 0xffffffffffffffff
0xABCD
43981 0x0000abcd
1<<5
32 0x00000020
.+10
42 0x0000002a
a=?.
+2
2 0x00000002
+3
3 0x00000003
a>>8
42 0x0000002a
0xAbC00+.
703530 0x000abc2a
)
syntax error
0xfgh
syntax error
0xg
syntax error
0xG
syntax error
0xh
syntax error
0xI
syntax error
1+2 4
syntax error
a = 1+2 4
syntax error
a=1
b=2
c=3
d=4
e=5
f=6
g=7
h=8
a=0x11223344<<32
b=a+0x55667788
a
1234605615003729920 0x1122334400000000
?b
-8613303245920329199 0x8877665544332211
a 1234605615003729920 0x1122334400000000
b 1234605616436508552 0x1122334455667788
c 3 0x00000003
d 4 0x00000004
e 5 0x00000005
f 6 0x00000006
g 7 0x00000007
h 8 0x00000008
!0
1 0x00000001
!3
0 0x00000000
!z
1 0x00000001
!a
0 0x00000000
+151
View File
@@ -0,0 +1,151 @@
1
1 0x00000001
-1
-1 0xffffffff
-2
-2 0xfffffffe
~0
-1 0xffffffff
~1
-2 0xfffffffe
~-1
0 0x00000000
?0x1234
13330 0x00003412
?0x12345678
2018915346 0x78563412
?0x1122334455667788
-2005440939 0x88776655
?0xffff1234
873660415 0x3412ffff
?0xffffffff1234
873660415 0x3412ffff
?0xffffffffffff1234
873660415 0x3412ffff
1+1
2 0x00000002
1 + 1
2 0x00000002
1 - 1
0 0x00000000
2 * 2
4 0x00000004
3 / 3
1 0x00000001
4 % 3
1 0x00000001
5 & 6
4 0x00000004
6 | 7
7 0x00000007
7 ^ 1
6 0x00000006
8 << 2
32 0x00000020
9 >> 2
2 0x00000002
-1 >> 32
-1 0xffffffff
-1 >>> 32
-1 0xffffffff
1 << 63
-2147483648 0x80000000
1<<63 -1
2147483647 0x7fffffff
1<<63+1
-2147483647 0x80000001
?.
16777344 0x01000080
( 4 + 3) * 5 - 1
34 0x00000022
~.
-35 0xffffffdd
4**5
syntax error
1+(4*3
syntax error
0xff00ff00
-16711936 0xff00ff00
?.
16711935 0x00ff00ff
. >> 1
8355967 0x007f807f
. >> 2
2088991 0x001fe01f
. >> 3
261123 0x0003fc03
. >> 4
16320 0x00003fc0
?0xff00ff00
16711935 0x00ff00ff
. << 1
33423870 0x01fe01fe
. << 2
133695480 0x07f807f8
. << 3
1069563840 0x3fc03fc0
. << 4
-66847744 0xfc03fc00
~0
-1 0xffffffff
0xABCD
43981 0x0000abcd
1<<5
32 0x00000020
.+10
42 0x0000002a
a=?.
+2
2 0x00000002
+3
3 0x00000003
a>>8
42 0x0000002a
0xAbC00+.
703530 0x000abc2a
)
syntax error
0xfgh
syntax error
0xg
syntax error
0xG
syntax error
0xh
syntax error
0xI
syntax error
1+2 4
syntax error
a = 1+2 4
syntax error
a=1
b=2
c=3
d=4
e=5
f=6
g=7
h=8
a=0x11223344<<32
b=a+0x55667788
a
287454020 0x11223344
?b
-861239194 0xccaa8866
a 287454020 0x11223344
b 1720232652 0x6688aacc
c 3 0x00000003
d 4 0x00000004
e 5 0x00000005
f 6 0x00000006
g 7 0x00000007
h 8 0x00000008
!0
1 0x00000001
!3
0 0x00000000
!z
1 0x00000001
!a
0 0x00000000
+262
View File
@@ -0,0 +1,262 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-implicit-int -Wno-variadic-macros -Wno-absolute-value \
-Wno-bitwise-op-parentheses -Wno-char-subscripts -Wno-dangling-else \
-Wno-implicit-function-declaration -Wno-parentheses \
-Wno-shift-op-parentheses -Wno-unsequenced -Wno-conversion \
-Wno-float-conversion -Wno-missing-variable-declarations \
-Wno-reserved-id-macro -Wno-shadow -Wno-shorten-64-to-32 \
-Wno-sign-conversion
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
#CDEFINE=
CDEFINE= -DW=1024 -Dp=800
# include files that are needed to compile
#
#CINCLUDE=
CINCLUDE= -I ${X11_INCDIR} -include stdlib.h
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
#LIBS=
LIBS= -L ${X11_LIBDIR} -lm -lX11
# 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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+144
View File
@@ -0,0 +1,144 @@
<!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 Crafty</title>
</head>
<body>
<h1>Most Crafty</h1>
<p>Gil Dogon<br>
<a href="http://sokoban-gild.com">http://sokoban-gild.com</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code>./prog
press and hold the Left Arrow key until you turn 90-degrees to the left
when you see a long tunnel, press the function key F2
Use the Up, Down, Left and Right keys to change your path
Press function higher numbered function keys (F3, F4, ...) to go faster
Press F1 to stop
Turn 90-degrees to one side
Press F4 to and drill into some blocks for a bit
Press F1 to stop
Turn 180-degrees to face the way you came
Press F2 and navigate back down the new hole until you reach the long tunnel again
Press F1 to stop
etc.
Press the ESC key
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>You are in a twisty maze blocks, almost all alike.</p>
<p>Those blocks are generated by twisty maze of code blocks, almost all different.</p>
<p>Can you find your way around either and understand where you are?</p>
<p>How many function keys does your keyboard have? Can you generate very high number function keys such as F30 or F31? :-)</p>
<p><em>Textures? We don&rsquo;t need no stinking textures.</em></p>
<h2>Author&rsquo;s comments:</h2>
<h3>What is it?</h3>
<p>Just run prog with no arguments on an X11-compatible system. The scenery, though pseudo-randomly generated should be strangely familiar, specially to those still in their teen age. You can navigate using the keyboard arrow keys and the function keys. Your speed is a linear function of (n-1) where Fn is the last function key you have pressed, and you always move in the direction you are looking at. Be aware that you are probably some kind of a Creeper as is obvious from looking at the program, hence your movement is destructive to the environment. So after pressing F12 for warp speed, and moving around randomly, you might find yourself in a 3D maze of twisty little passages, from which there is only one Esc(ape) key. Note that in theory if you have a specialty keyboard with 32 function keys you may even press F31 to reach infinite improbability drive speed, though the author had never tested this feature. However a hidden comment in keysymdef.h suggests the existence of a mythical Sun Keyboard with 35 function keys :)</p>
<h3>Full disclosure.</h3>
<p>This entry, tough pretty thoroughly obfuscated, is not entirely original, nor am I Notch. The inspiration for this entry is a demo code written by the Notch himself, which was released with the following license: &ldquo;you may use the code in here for any purpose in any way you want, at your own risk&rdquo;. That version will henceforth be referred to as the original. Though the original in itself was quite nice and rather dense piece of code, it was not written in C, nor entirely and meticulously obfuscated, a state of things I hopefully rectified.</p>
<h3>Some extra features.</h3>
<p>Basing it on the original which already had a wonderful simple and concise ray casting through a generated voxel world rendering, I added a few tweaks of my own device:</p>
<ul>
<li>Two pass optimized rendering. The program first calculates 1/16 of the output image by ray casting, and then, when possible uses texture interpolation on the voxel faces. It speeds up the rendering by at least a factor of 4 on most scenes, but extra care must be taken when passing rays through the leaves voxels &hellip;</li>
<li>Fixed a small omission in the original. When you looked though a transparent leaves voxel, you did not see the leaves at voxel faces that were far from you. In this version the rendering of those (far face leaves) is correct.</li>
<li>Window rendering size specified in Makefile.</li>
<li>Added the keyboard controls for navigation (and destruction).</li>
</ul>
<h3>Portability issues.</h3>
<p>This entry is rather portable I think on modern platforms. It assumes of course basic X-windows availability. There are several other salient assumptions though:</p>
<ul>
<li>The entry assumes sizeof(int)=4. This seems to cover pretty much everything that supports X-windows so would be broken only on quite ancient machines, embedded processors, or some big iron 64 bit system where sizeof(int)=8.</li>
<li>The entry assumes the default visual has 24 bit depth (RGB). This seems to be the case on most X Servers this days.</li>
<li><p>The entry, does a thing which is an absolute No-No for X-windows program, i.e. assuming it knows some numeric values for keysyms defined in keysymdef.h . I have searched far and wide the lord Google&rsquo;s domain, yet was unable to find a version of the file where those assumptions were broken. This enables the important support of up to 32 function keys keyboards without spilling over the size limit, and allows us to use such fun expression for arrow view control as the following:</p>
<pre><code> *(a&amp;1?&amp;C:&amp;B)-=(.05 -a/2%2*.1)*!(a-1&amp;4092^3920)
</code></pre></li>
</ul>
<h3>Precision issues.</h3>
<p>The entry, on purpose, (see the section about SIMD below) does not use enough bits of precision, so some times the ray will miss the intersection of two voxel faces and push on through. That&rsquo;s why you may notice some noise along close up voxel edges. Fixing this issue would have taken the entry over the size limit regrettably.</p>
<h3>Obfuscations.</h3>
<p>Well, of course you have all the usual suspects, used for extreme compression, and such a nice layout: not very informative identifiers, which are being reused all over the place, some rather gruesome looking expressions, a whole load of magic constants with apparently no rhyme nor reason (including a Lagrange polynomial), and a message from our friendly Cetaceans. However it also includes some clever and not so obvious though instructive techniques, to subtly make the code more magical and efficient, at the same time.</p>
<p>Those techniques are about the use of 64 bit integers in order to do SIMD work, in a portable way without ever using any SSE/AVX or other non-portable compiler inline functions! The irony though, is that when compiling the program on modern X86 architectures indeed SSE/AVX is used for the long longs.
Following is some &ldquo;Spoiler&rdquo; information, So if you want to play tough, stop reading at this point.</p>
<h3>Portable SIMD programming.</h3>
<p>So how is this done? Quite simply by using the whole long long arithmetic&rsquo;s capability. I think the C99 standard assures us that long long has at least 64 bits. Most of those bits are unused in normal programs, however here we use them more wisely. For example, in the inner loop of the program you have the innocent looking expression i+=d. What it does in fact, is a SIMD addition of two vectors, each with three signed fixed point coordinates, advancing our ray in 3D space!
To spell it out, the macro producing such vectors is P, and the assignment q=0x820008202625a0 sets our creeper original position to about (32.5, 32.5019, 2441.406) .</p>
<p>Evidently when doing such arithmetics, care must me taken to avoid overflow from one component to the other, but since our voxel world is a torus of size 64 in each dimension this hardly matters. A subtle issue, is how to deal with signed quantities. In the i+=d expression above i has 3 positive components, but d has arbitrary signed components, as our ray may face in any direction. It seems things should not work, specially as we defined both i and d as unsigned! However notice that the T (and P )macro converts float to signed long longs. Once sign is extended from a least component into higher bits, it seems at first to be recipe for disaster, however everything works beautifully, and you get precise component results when the final accumulation components in i are positive. This only gets broken a bit when the final accumulation has a least significant negative component. To see this bug in action change the assignment above to q=0x82000820000000, and look towards the negative direction of the main tunnel.</p>
<p>Similar technique is used on the RGB components so their brightness can be adjusted simultaneously by the expression: o=o*b>>8 . Of course some spare bits are needed between the components, so they are spread in the long long and reordered as RBG.</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+111
View File
@@ -0,0 +1,111 @@
# Most Crafty
Gil Dogon
<http://sokoban-gild.com>
## Judges' comments:
### To use:
make
./prog
### Try:
./prog
press and hold the Left Arrow key until you turn 90-degrees to the left
when you see a long tunnel, press the function key F2
Use the Up, Down, Left and Right keys to change your path
Press function higher numbered function keys (F3, F4, ...) to go faster
Press F1 to stop
Turn 90-degrees to one side
Press F4 to and drill into some blocks for a bit
Press F1 to stop
Turn 180-degrees to face the way you came
Press F2 and navigate back down the new hole until you reach the long tunnel again
Press F1 to stop
etc.
Press the ESC key
### Selected Judges Remarks:
You are in a twisty maze blocks, almost all alike.
Those blocks are generated by twisty maze of code blocks, almost all different.
Can you find your way around either and understand where you are?
How many function keys does your keyboard have? Can you generate very high number function keys such as F30 or F31? :-)
*Textures? We don't need no stinking textures.*
## Author's comments:
### What is it?
Just run prog with no arguments on an X11-compatible system. The scenery, though pseudo-randomly generated should be strangely familiar, specially to those still in their teen age. You can navigate using the keyboard arrow keys and the function keys. Your speed is a linear function of (n-1) where Fn is the last function key you have pressed, and you always move in the direction you are looking at. Be aware that you are probably some kind of a Creeper as is obvious from looking at the program, hence your movement is destructive to the environment. So after pressing F12 for warp speed, and moving around randomly, you might find yourself in a 3D maze of twisty little passages, from which there is only one Esc(ape) key. Note that in theory if you have a specialty keyboard with 32 function keys you may even press F31 to reach infinite improbability drive speed, though the author had never tested this feature. However a hidden comment in keysymdef.h suggests the existence of a mythical Sun Keyboard with 35 function keys :)
### Full disclosure.
This entry, tough pretty thoroughly obfuscated, is not entirely original, nor am I Notch. The inspiration for this entry is a demo code written by the Notch himself, which was released with the following license: "you may use the code in here for any purpose in any way you want, at your own risk". That version will henceforth be referred to as the original. Though the original in itself was quite nice and rather dense piece of code, it was not written in C, nor entirely and meticulously obfuscated, a state of things I hopefully rectified.
### Some extra features.
Basing it on the original which already had a wonderful simple and concise ray casting through a generated voxel world rendering, I added a few tweaks of my own device:
* Two pass optimized rendering. The program first calculates 1/16 of the output image by ray casting, and then, when possible uses texture interpolation on the voxel faces. It speeds up the rendering by at least a factor of 4 on most scenes, but extra care must be taken when passing rays through the leaves voxels ...
* Fixed a small omission in the original. When you looked though a transparent leaves voxel, you did not see the leaves at voxel faces that were far from you. In this version the rendering of those (far face leaves) is correct.
* Window rendering size specified in Makefile.
* Added the keyboard controls for navigation (and destruction).
### Portability issues.
This entry is rather portable I think on modern platforms. It assumes of course basic X-windows availability. There are several other salient assumptions though:
* The entry assumes sizeof(int)=4. This seems to cover pretty much everything that supports X-windows so would be broken only on quite ancient machines, embedded processors, or some big iron 64 bit system where sizeof(int)=8.
* The entry assumes the default visual has 24 bit depth (RGB). This seems to be the case on most X Servers this days.
* The entry, does a thing which is an absolute No-No for X-windows program, i.e. assuming it knows some numeric values for keysyms defined in keysymdef.h . I have searched far and wide the lord Google's domain, yet was unable to find a version of the file where those assumptions were broken. This enables the important support of up to 32 function keys keyboards without spilling over the size limit, and allows us to use such fun expression for arrow view control as the following:
*(a&1?&C:&B)-=(.05 -a/2%2*.1)*!(a-1&4092^3920)
### Precision issues.
The entry, on purpose, (see the section about SIMD below) does not use enough bits of precision, so some times the ray will miss the intersection of two voxel faces and push on through. That's why you may notice some noise along close up voxel edges. Fixing this issue would have taken the entry over the size limit regrettably.
### Obfuscations.
Well, of course you have all the usual suspects, used for extreme compression, and such a nice layout: not very informative identifiers, which are being reused all over the place, some rather gruesome looking expressions, a whole load of magic constants with apparently no rhyme nor reason (including a Lagrange polynomial), and a message from our friendly Cetaceans. However it also includes some clever and not so obvious though instructive techniques, to subtly make the code more magical and efficient, at the same time.
Those techniques are about the use of 64 bit integers in order to do SIMD work, in a portable way without ever using any SSE/AVX or other non-portable compiler inline functions! The irony though, is that when compiling the program on modern X86 architectures indeed SSE/AVX is used for the long longs.
Following is some "Spoiler" information, So if you want to play tough, stop reading at this point.
### Portable SIMD programming.
So how is this done? Quite simply by using the whole long long arithmetic's capability. I think the C99 standard assures us that long long has at least 64 bits. Most of those bits are unused in normal programs, however here we use them more wisely. For example, in the inner loop of the program you have the innocent looking expression i+=d. What it does in fact, is a SIMD addition of two vectors, each with three signed fixed point coordinates, advancing our ray in 3D space!
To spell it out, the macro producing such vectors is P, and the assignment q=0x820008202625a0 sets our creeper original position to about (32.5, 32.5019, 2441.406) .
Evidently when doing such arithmetics, care must me taken to avoid overflow from one component to the other, but since our voxel world is a torus of size 64 in each dimension this hardly matters. A subtle issue, is how to deal with signed quantities. In the i+=d expression above i has 3 positive components, but d has arbitrary signed components, as our ray may face in any direction. It seems things should not work, specially as we defined both i and d as unsigned! However notice that the T (and P )macro converts float to signed long longs. Once sign is extended from a least component into higher bits, it seems at first to be recipe for disaster, however everything works beautifully, and you get precise component results when the final accumulation components in i are positive. This only gets broken a bit when the final accumulation has a least significant negative component. To see this bug in action change the assignment above to q=0x82000820000000, and look towards the negative direction of the main tunnel.
Similar technique is used on the RGB components so their brightness can be adjusted simultaneously by the expression: o=o*b>>8 . Of course some spare bits are needed between the components, so they are spread in the long long and reordered as RBG.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+56
View File
@@ -0,0 +1,56 @@
#define So long
#define R rand()
#include <math.h>
#include <X11/Xlib.h>
#define T(i,F) ((So long)(i)<<F)
#define O(c,L,i) c*sin(i)+L*cos(i)
#define y(n,L) for(n=0; n<L 3; n++)
#define P(v,L) d=0; y(l,)d+=T(L*l[v],l*20);
#define X(q) q>>10&63|q>>24&4032|q>>38&258048
char J[1<<18]; int G[W*p],_,k,I=W/4+1,w=p/4+1; float C,B,e;
unsigned So long A,n,d, t,h,x, f,o,r,a,l,L,F,i,s,H=1<<18,b=250,D[1<<14],z[W*p],q
=0x820008202625a0;main(){Display *j=XOpenDisplay(0);Window u=XCreateSimpleWindow
(j,RootWindow(j,0),0,0,W,p,1,0,0);XImage *Y=XCreateImage(j,DefaultVisual(j,0),24
,2,0,(char*)G,W,p,32,0); XEvent M; for(XMapWindow(j,u); XSelectInput( j,u,1)&&a-
65307; ){ if(!H){ if(XCheckWindowEvent(j,u,1,&M)){ a=XLookupKeysym(&M.xkey,0);*(
a&1?&C:& B)-=(.05
-a/2% 2* .1)*!(a-
1& 4092^ 3920);a+
2&0xfe0^ 0xfc0||(
s=a+2&31 ); }else
{ y(k,p+ ){ F=k%w* 4|k/w; float a[6],S=(F-p /2.) /p;
y(_,W+){ i=_%I*4|_/I; if( F<p&i<W){ o=1; L= i+F*W;if
(l=i&3); else{ l=F&3; o=W ; } h=z[L-o*l]; f =z[L+(4-
l)*o]; t =F-p/2||i-W/2; r =h^f; if(!l| !t|( int)r|(!
(h- 3&3) &&258063&r>>38)) { float V=(i-W/2. )/p,U=O(
S,1,B),m =32768,Q=m; a[4] =O(-1,S,B); a[3]= O(U,V,C)
; a[5]=O (-V,U,C); P((a+3 ),s*42); t||(A=d) ;f=0;y(n
,){float N=a[n+3], E=1024 /fabs(N); b= N<0; float K=
(((q>>20 *n)^~-b)+!b&1023 )/1024.; y(d,)a[d ]=a[d+3]
*E; a[n] =round(a[n]); P( a,K); i=q+d; P(a, 1); e=E*
K; for(; e<m; i+=d){ l=X(i); t=r=l^(l^l-( 1<<6*n))
&63<<6*n ; if(b){ r=l; l=t; } if(J[r])l=r ; if(t=J
[l]){x=( n-1)?(i|i>>40)&1023|i>>8&4190208 |4194304
:i&1023| i>>28&4190208|(b^l==r)<<23; if(h =D[(x>>6
&0xf|x>> 14&0x3f0)+t*768]){ o=h; f=n|l*4| x<<32; m
=e; } if (t==8&e<Q)Q=e; } e+=E; } }b=(255 -((f&3)+
2)%3*51) *(1-m/32768); o=o*b>>8; G[L]=o>> 32<<8|o&
16711935 ; z[L]=3*(Q<=m)|f|b<<56; } else{ d=l*(f<<
8>>40)+( 4-l)*(h<<8>>40)>>2&16774143; o=D [(d>> 6&
15|d>>14 &1008)+J[(int)h/4]*768]*(b=h>>56 )>>8; G[
L]=o>>32 <<8 | o& 16711935 ; z[L]=(
int) h|d <<32|b<< 56; } }} } q +=A;
XPutImage (j, u+0, DefaultGC (j,J[X(q
)]=0),Y, 0,0,0,0, W,p); }} else{ L=
--H/768; J[H] =R% 16*(R%4< abs((H>>
6&63)-32 )+abs((H
>>12&63) -32)-3);
i=H &15; F=H %768
>>4; if( L<16){if
(L-1|!(R %3))b=R%
96^255; l=i*i*3+i*81/4&3; a=L>3?L-8?L-5?9858122:12365733-488848*((i+F/4*4)%8&&F%
4):R%2*5298487:3352537*L*L-14202379*L+19205553; if(L==4)if(F<l+18)a=6990400;else
if(l>F-19)b*=0.7; if(L==3){ if((i-1&15)<14&(F-1&15)<14&!(F&16)){ a=12359778; _=7
-i; k=7-F%16; _^=_>>31; k^=k>>31; b=196-R%32+(k>_?k:_)%3*42;} else{ b*=1+R%2*(.5
-(i&1)); } } D[H]=(a&16711935|(a&65280)<<24)*(b>>(F>>5))>>8&0xff00ff00ff; } } }}
+259
View File
@@ -0,0 +1,259 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
CSILENCE= -Wno-parentheses -Wno-unused-value -Wno-return-type \
-Wno-overlength-strings -Wno-unused-result \
-Wno-implicit-int
clang_CSILENCE=-Wno-string-plus-int -Wno-int-conversion
# compiler standard
#
CSTD= -std=c11 \
-D_BSD_SOURCE \
-D_XOPEN_SOURCE
# _BSD_SOURCE needed for function usleep()
# _XOPEN_SOURCE needed for function lrand48()
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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
CSILENCE+= ${${CC}_CSILENCE}
##############################
# Special flags for this entry
##############################
#
ENTRY= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+38
View File
@@ -0,0 +1,38 @@
k: CALL l_no_end 1_FORWARD GO_BACK 1_TURN_RIGHT 2_FORWARD TGGL_PEN GO_BACK 1_TURN_LEFT 1_FORWARD TGGL_PEN 1_FORWARD
h: CALL l_no_end 1_FORWARD GO_BACK 2_FORWARD 1_TURN_RIGHT BOUNCE 1_TURN_RIGHT 1_FORWARD
f: CALL l_no_end 2_FORWARD 2_FORWARD 1_TURN_RIGHT
l: CALL l_no_end 1_TURN_LEFT
l_no_end: 2_FORWARD TGGL_PEN 1_TURN_RIGHT 1_FORWARD 1_TURN_LEFT 1_FORWARD 1_TURN_LEFT BOUNCE 1_TURN_LEFT 2_FORWARD 2_FORWARD
j: MIDDLE 5_FORWARD 1_FORWARD 1_TURN_RIGHT GO_BACK TGGL_PEN 1_FORWARD 1_TURN_LEFT 5_FORWARD 2_FORWARD TGGL_PEN
i: MIDDLE 2_FORWARD 1_TURN_LEFT GO_BACK TGGL_PEN 1_FORWARD 1_TURN_RIGHT 2_FORWARD 1_FORWARD TGGL_PEN
t: ABOVE 5_FORWARD 1_FORWARD 1_TURN_LEFT TGGL_PEN 2_TURN_LEFT 2_TURN_LEFT 2_FORWARD GO_BACK TGGL_PEN 1_TURN_LEFT 1_FORWARD
s: 1_FORWARD TGGL_PEN 1_TURN_RIGHT 1_FORWARD BOUNCE 2_TURN_RIGHT 1_TURN_RIGHT
v: MIDDLE 1_FORWARD 1_TURN_LEFT 1_FORWARD BOUNCE 1_FORWARD 1_TURN_LEFT
x: MIDDLE 1_TURN_LEFT 2_FORWARD TGGL_PEN 5_TURN_LEFT TGGL_PEN 1_TURN_LEFT 2_FORWARD
p: MIDDLE 5_FORWARD 2_FORWARD GO_BACK 5_FORWARD 1_FORWARD 5_TURN_RIGHT 1_TURN_RIGHT
e: 1_FORWARD 1_TURN_RIGHT TGGL_PEN 1_TURN_RIGHT TGGL_PEN 1_TURN_RIGHT GO_BACK 1_TURN_RIGHT TGGL_PEN 5_TURN_LEFT 1_TURN_LEFT
z: TGGL_PEN 2_FORWARD 1_TURN_RIGHT BOUNCE 1_TURN_RIGHT 1_FORWARD 1_TURN_LEFT 1_FORWARD 2_TURN_RIGHT BOUNCE 2_TURN_RIGHT 1_FORWARD
w: CALL half_w CALL half_w
half_w: MIDDLE 2_FORWARD 1_TURN_LEFT BOUNCE 1_TURN_LEFT 1_FORWARD
y: CALL u 2_FORWARD 1_FORWARD 1_TURN_RIGHT
u: MIDDLE CALL u_bridge 2_FORWARD 1_FORWARD
u_bridge: 2_FORWARD 2_TURN_LEFT 2_TURN_LEFT 1_FORWARD GO_BACK
m: CALL n GO_BACK 2_FORWARD 2_TURN_RIGHT 2_TURN_RIGHT 1_FORWARD
n: CALL r 2_TURN_RIGHT 1_FORWARD
b: ABOVE 2_FORWARD 2_FORWARD CALL r_trace 2_TURN_RIGHT 2_TURN_RIGHT
r: MIDDLE CALL r_trace
r_trace: 2_FORWARD 1_FORWARD GO_BACK 2_FORWARD 2_TURN_RIGHT
q: CALL o GO_BACK 5_FORWARD 2_FORWARD
g: CALL o GO_BACK 5_FORWARD 1_FORWARD 5_TURN_RIGHT
o: CALL c 2_TURN_LEFT 1_FORWARD
d: CALL c 1_FORWARD ABOVE 5_FORWARD 1_FORWARD 1_TURN_LEFT
a: CALL c 1_FORWARD TGGL_PEN 2_TURN_LEFT 1_TURN_LEFT GO_BACK TGGL_PEN 1_TURN_RIGHT 1_FORWARD 1_TURN_LEFT
c: 2_FORWARD 2_TURN_RIGHT GO_BACK TGGL_PEN 1_FORWARD 2_TURN_LEFT 2_TURN_LEFT
.: TGGL_PEN
,: TGGL_PEN GO_BACK 1_TURN_RIGHT
;: CALL : 1_TURN_RIGHT
:: MIDDLE TGGL_PEN 2_FORWARD 1_FORWARD TGGL_PEN
!: ABOVE 5_FORWARD TGGL_PEN 2_FORWARD TGGL_PEN
?: 5_FORWARD 1_FORWARD TGGL_PEN 2_TURN_RIGHT 2_TURN_RIGHT 1_FORWARD 1_TURN_RIGHT 1_TURN_LEFT TGGL_PEN 2_FORWARD TGGL_PEN
+223
View File
@@ -0,0 +1,223 @@
<!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 Handwriting</title>
</head>
<body>
<h1>Best Handwriting</h1>
<p>Etienne Duble <a href="&#109;&#x61;&#105;&#108;&#116;&#x6f;&#58;&#x65;&#x74;&#105;&#x65;&#x6e;&#110;&#101;&#46;&#x64;&#117;&#98;&#x6c;&#101;&#64;&#105;&#x6d;&#97;&#103;&#x2e;&#102;&#114;">&#101;&#x74;&#x69;&#101;&#110;&#x6e;&#101;&#46;&#100;&#x75;&#x62;&#108;&#x65;&#x40;&#x69;&#x6d;&#x61;&#103;&#46;&#x66;&#114;</a><br>
<a href="http://lig-membres.imag.fr/duble">http://lig-membres.imag.fr/duble</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
echo Some text | ./prog
</code></pre>
<h3>Try:</h3>
<pre><code>echo Hello, world | ./prog
DRAFT=1 ./prog &lt; prog.c
./prog
&gt; [type]
(...observe...)
./prog &lt; prog.c
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Beautiful penmanship! However, your fonts may vary.</p>
<p>How does this entry compress the font it uses? What&rsquo;s the purpose of lrand48()?
Why does the program dump core, when it does :) ?</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Introduction</h3>
<p>This program <strong>prints text in your terminal with an interesting
hand-writing effect</strong>.</p>
<p>It uses the <em>braille patterns</em> range of the unicode standard: this
allows to consider each terminal character as a tiny 2x4 bitmap.</p>
<p>Turning the Braille code into something visual might be considered
blasphemous. When I was fighting to make this program work, I started
wondering if it was not the reason for its very erratic behaviour.</p>
<h3>prog.c vs prog.orig.c</h3>
<p>The file <code>prog.orig.c</code> is the one I submitted.</p>
<p>Gil Dogon noted a few unsafe statements (statements whose behaviour is
undefined in the C standard and, as such, could cause issues with other
compilers or optimization levels). These have been fixed in <code>prog.c</code>.
After this fix, in order to remain rule-2-compliant, a variable name has
also been shortened in this file.</p>
<h3>How to build</h3>
<p>If you have <code>clang</code>:</p>
<pre><code>$ CC=clang make -e
</code></pre>
<p>Otherwise (gcc):</p>
<pre><code>$ make
</code></pre>
<p>(You will get a few warnings in this case.)</p>
<h3>How to use it</h3>
<p>You need a terminal configured to handle an <em>UTF-8</em> encoding and a
font including <em>braille patterns</em>.
This is the default on most modern GNU/Linux operating systems.
The default terminal application (gnome-terminal) or even a simple
xterm should render things properly.
I tested this on several Debian and Ubuntu systems, 32 and 64bits (no configuration was needed).
I also tested it on FreeBSD 9.3 32bits (font and encoding configuration
was needed in this case).</p>
<p>Basic mode:</p>
<pre><code>$ echo 'I am testing this thing.' | ./prog
[... rendering ...]
$ ./prog &lt; lorem-ipsum.txt
[... rendering ...]
</code></pre>
<p>Interactive mode:</p>
<pre><code>$ ./prog
&gt; hello world!!!
[... rendering ...]
&gt;
</code></pre>
<h3>Obfuscation</h3>
<p>This entry is obfuscated in various ways:</p>
<ul>
<li>The structure is hidden by avoiding loops, &lsquo;if&rsquo; statements, ternary
conditionals, and jump-related instructions. Instead, recursivity is
heavily used.</li>
<li>Merging all functions into one added even more recursivity. ;)</li>
<li>The provided code does not contain the same number of opening and closing
parenthesis.</li>
<li>Preprocessing the code inflates it and adds lots of indents. Removing some
of the tricks involved without breaking the program will be challenging.</li>
<li>The program &lsquo;plays&rsquo; with standard input &amp; output streams, which causes
unusual side effects.</li>
<li>Some variables are re-used for unrelated processings.</li>
<li>Crucial data may be hidden in unexpected places (e.g. as the size of
a temporary buffer).</li>
<li>Some parts of the code may have no effect (but may have an effect in a
specific context, who knows?), and classical libc functions may not act
as usual.</li>
<li>And of course variable names are hard to read (or distracting).</li>
</ul>
<p>On the other hand, the following may help:</p>
<ul>
<li>The code layout should help to identify which part of the code is
obfuscated. ;)</li>
<li>File &lsquo;codes.txt&rsquo; shows how each character is drawn. This data is
encoded in macro O_o at the top of the source file.</li>
</ul>
<h3>Limitations</h3>
<h4>Charset</h4>
<p>In order to comply with the size rule, I encoded only a part of the visible ASCII
chars:</p>
<pre><code>a-z, A-Z, '.' ':' ',' ';' '!' and '?'.
</code></pre>
<p>Uppercase and lowercase chars are rendered the same.
The program also understand the space and the linefeed (\n).
Other chars are simply ignored (most of the time ;)</p>
<h4>Stack size</h4>
<p>This limitation is due to the heavy use of recursivity. After having processed
a large number of characters, the process may exceed the stack size and crash.
(However I did not experience this myself. The top-level recursion might be
removed by the compiler as part of its optimizations.)</p>
<h4>Line rendering</h4>
<p>The program does its best to avoid cutting words at the end of lines, but
it could still happen in case of long words.</p>
<h3>Subtleties and extra features</h3>
<h4>Handling more than text docs?</h4>
<p>Given the limited set of characters handled, the program is mostly limited
to simple text documents.
Thus, if you try for example:</p>
<pre><code>$ ./prog &lt; prog.c
</code></pre>
<p>You will not get something that looks like C code. (but you can still try,
if you are curious. :)</p>
<h4>A &lsquo;draft&rsquo; mode</h4>
<p>Defining an environment variable called DRAFT will enable the &lsquo;draft-mode&rsquo;.
Try for example:</p>
<pre><code>$ echo 'testing the draft mode' | DRAFT=1 ./prog
</code></pre>
<p>The program will run much faster but the rendering will be less precise.</p>
<h4>The subtle interactive mode</h4>
<p>I saved the best for last: usually, programs that handle an &ldquo;interactive
mode&rdquo; have to check whether their standard input is a terminal or not (by
using isatty()). Did you notice that this program does not perform any such
detection, but still behaves (or seems to behave) appropriately?</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+187
View File
@@ -0,0 +1,187 @@
# Best Handwriting
Etienne Duble <etienne.duble@imag.fr>
<http://lig-membres.imag.fr/duble>
## Judges' comments:
### To use:
make
echo Some text | ./prog
### Try:
echo Hello, world | ./prog
DRAFT=1 ./prog < prog.c
./prog
> [type]
(...observe...)
./prog < prog.c
### Selected Judges Remarks:
Beautiful penmanship! However, your fonts may vary.
How does this entry compress the font it uses? What's the purpose of lrand48()?
Why does the program dump core, when it does :) ?
## Author's comments:
### Introduction
This program **prints text in your terminal with an interesting
hand-writing effect**.
It uses the *braille patterns* range of the unicode standard: this
allows to consider each terminal character as a tiny 2x4 bitmap.
Turning the Braille code into something visual might be considered
blasphemous. When I was fighting to make this program work, I started
wondering if it was not the reason for its very erratic behaviour.
### prog.c vs prog.orig.c
The file `prog.orig.c` is the one I submitted.
Gil Dogon noted a few unsafe statements (statements whose behaviour is
undefined in the C standard and, as such, could cause issues with other
compilers or optimization levels). These have been fixed in `prog.c`.
After this fix, in order to remain rule-2-compliant, a variable name has
also been shortened in this file.
### How to build
If you have `clang`:
$ CC=clang make -e
Otherwise (gcc):
$ make
(You will get a few warnings in this case.)
### How to use it
You need a terminal configured to handle an *UTF-8* encoding and a
font including *braille patterns*.
This is the default on most modern GNU/Linux operating systems.
The default terminal application (gnome-terminal) or even a simple
xterm should render things properly.
I tested this on several Debian and Ubuntu systems, 32 and 64bits (no configuration was needed).
I also tested it on FreeBSD 9.3 32bits (font and encoding configuration
was needed in this case).
Basic mode:
$ echo 'I am testing this thing.' | ./prog
[... rendering ...]
$ ./prog < lorem-ipsum.txt
[... rendering ...]
Interactive mode:
$ ./prog
> hello world!!!
[... rendering ...]
>
### Obfuscation
This entry is obfuscated in various ways:
* The structure is hidden by avoiding loops, 'if' statements, ternary
conditionals, and jump-related instructions. Instead, recursivity is
heavily used.
* Merging all functions into one added even more recursivity. ;)
* The provided code does not contain the same number of opening and closing
parenthesis.
* Preprocessing the code inflates it and adds lots of indents. Removing some
of the tricks involved without breaking the program will be challenging.
* The program 'plays' with standard input & output streams, which causes
unusual side effects.
* Some variables are re-used for unrelated processings.
* Crucial data may be hidden in unexpected places (e.g. as the size of
a temporary buffer).
* Some parts of the code may have no effect (but may have an effect in a
specific context, who knows?), and classical libc functions may not act
as usual.
* And of course variable names are hard to read (or distracting).
On the other hand, the following may help:
* The code layout should help to identify which part of the code is
obfuscated. ;)
* File 'codes.txt' shows how each character is drawn. This data is
encoded in macro O_o at the top of the source file.
### Limitations
#### Charset
In order to comply with the size rule, I encoded only a part of the visible ASCII
chars:
a-z, A-Z, '.' ':' ',' ';' '!' and '?'.
Uppercase and lowercase chars are rendered the same.
The program also understand the space and the linefeed (\n).
Other chars are simply ignored (most of the time ;)
#### Stack size
This limitation is due to the heavy use of recursivity. After having processed
a large number of characters, the process may exceed the stack size and crash.
(However I did not experience this myself. The top-level recursion might be
removed by the compiler as part of its optimizations.)
#### Line rendering
The program does its best to avoid cutting words at the end of lines, but
it could still happen in case of long words.
### Subtleties and extra features
#### Handling more than text docs?
Given the limited set of characters handled, the program is mostly limited
to simple text documents.
Thus, if you try for example:
$ ./prog < prog.c
You will not get something that looks like C code. (but you can still try,
if you are curious. :)
#### A 'draft' mode
Defining an environment variable called DRAFT will enable the 'draft-mode'.
Try for example:
$ echo 'testing the draft mode' | DRAFT=1 ./prog
The program will run much faster but the rendering will be less precise.
#### The subtle interactive mode
I saved the best for last: usually, programs that handle an "interactive
mode" have to check whether their standard input is a terminal or not (by
using isatty()). Did you notice that this program does not perform any such
detection, but still behaves (or seems to behave) appropriately?
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+8
View File
@@ -0,0 +1,8 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.
Ut velit mauris, egestas sed, gravida nec, ornare ut, mi. Aenean ut orci vel massa suscipit pulvinar. Nulla sollicitudin. Fusce varius, ligula non tempus aliquam, nunc turpis ullamcorper nibh, in tempus sapien eros vitae ligula. Pellentesque rhoncus nunc et augue. Integer id felis. Curabitur aliquet pellentesque diam. Integer quis metus vitae elit lobortis egestas. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi vel erat non mauris convallis vehicula. Nulla et sapien. Integer tortor tellus, aliquam faucibus, convallis id, congue eu, quam. Mauris ullamcorper felis vitae erat. Proin feugiat, augue non elementum posuere, metus purus iaculis lectus, et tristique ligula justo vitae magna.
Aliquam convallis sollicitudin purus. Praesent aliquam, enim at fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus, felis magna fermentum augue, et ultricies lacus lorem varius purus. Curabitur eu amet.
+55
View File
@@ -0,0 +1,55 @@
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#define O_o "sfX4.Fv8H!`uf"\
"|~0y'vWtA@:LcO9d}y.!uL!Gd+ml(<+Ds!J"\
"e.6!r!%l6G!n~^<i=%pEwL%P!'<!FQt%u 5toG57j/3"\
"!:E%;!ea!!!WqE0z!f/y}!%!!Qi6!uzt!n}?]!bl!ak!SetR<"\
"Zj$x!~V!n&g8!cK! KrgR'8@c]!%-q9V.3fa[E8X%dY'w!#H <P~6"\
"?guhljL!^P% ?" "8!@dP,!!o+fb"\
"!pv!;!Hm%Ro4" "n:}nkD!Q!kN"\
"e:| 'b5sc!e" /* nothing */
#define mu(a) a a a a a //-
#define O_(Q_ ) "\033[" #Q_
#define Q_(O) mu(mu(mu(O)))
#define Q/*-- ++--*/O9--||(
#define main( )main(){/**/\
signal(13,1), _();}f()//--+
#define k( k) getenv( "D"#k
char*O0=O_o,OO,*Q1,O5[97];int*Q5,_Q=0,Q0=0,_O=0,_0=0,O=5,QQ,O6,Q6,O3
,Q4,O4=41088,O1=sizeof(O5),O7=234;long long __;_()Q_({)int*Q3,Q2,O2,C,
QO,O9=O,O8=!!!!!!!!!!k(RAFT));long long Q8;char*Q9=O_(1A)O_(%dB)O_(%dC
)O_(34m)"\xe2%c%c\r\n"O_(0m)O_(%dA),*Q7;__+=(__*92+*O0-35-__)*(QO=Q_(!
!)(*O0-33)*!O9--),O0+=O1*QO,QO&&_(),Q Q4&&(O--,_(),O0+=194,O++,Q4--,_(
))),Q O=0,__=0,_(),O=3,_()),Q __&&(C=__&15,_O+=(C<2)*12+!(QO=C&14^2)*(
4-_O)+(C==6)*( 12-2*_O)+(C>6)*(9-(C-7)%3),_Q+=!QO*(_Q%QQ+(C&1)*O3-_Q),
_0+=!_0*!QO+(1-2*_0)*!(C^4),(C==5)&&(__>>=4,Q8=__,Q7=O0,Q4=__&15,O=1,_
()|O ++&_(),__=Q8 ,O0=Q7 ),Q3=( _Q+= O8*(9 *O4*
O1 > lrand48()) +(_O%=8,( (_O% 6>2) -(_O%
7<2) )*QQ+((_O +7)%8<3 )-(_O>4) )*( C>5 ),
Q2 = _Q/ O3)* O6+Q5 +(O2=_Q%QQ )/ 2,*Q3=*
Q3 % O4+O4|(1 << Q_("" "@CADBEHI") [_Q%2+_Q
%O3/ QQ*2 ]- 64)* _0, sprintf(O5, Q9, Q2+1,
O2/2 ,*Q3>>8 ,85* 3&* Q3,Q2+1 )&& _0&&(O=8,
Q1 = O5,_()), Q0 +=(O2 >Q0)*_0*(O2 -Q0 ),__
+=!( C>9)*(3- __+ ( __>>4))-3, __ +=(C>12
) *( (__<<4 )+ C-3-__) ,usleep( O4* _0/(3*
O8+1 )),O =3,_() )) ,!O9 --&& read(
1 ,& OO,1)> 0&&(O= (QO=OO ==35 )*3+6 ,_()
,QO&&(OO=10,O=6,_(),1)||(O=4,_()),0)||close(dup2(3-dup2(1,dup(0)-3),1)
*0+2)*0||Q write(1,"> ",2),ioctl(Q0=0,TIOCGWINSZ,O5)^--O&(O3=(QQ=(O6=*
((short*)O5+1))*2)*4),Q6=-O1,Q5=calloc(3*O6,8),_()),Q (O=8,QO=!(O2=OO-
10)|!(Q2=OO-32)*(Q0+58>QQ)|(Q0+12>QQ))&&(Q1=O_(3B),_(),write(1,"> ",2)
),Q0+=!QO*!Q2*4-QO*Q0,O2*Q2&&(!Q0&&(memset(Q5,0,3*O3),Q0=4,Q1="\n\n\n"
O_(3A),_()),O=7,_Q=7*QQ+Q0+2,_O=_0=0,OO+=(OO>64 &OO<91)*32,O0=Q_(O_o)+
O7,_(),(*O0-OO)||(O=2,O0+='a',_( )))),Q *O0-OO)&&(*(O0+=O1)-33)&&(O=0,
_(),O=7,O0+=O1,_()),Q write(0,Q1,strlen(Q1))),Q OO=Q_(O_o)[Q6+=O1],(Q6
%strlen(O_o)-O7)&&(O=6,_(),O=9,_()));Q_(})/*+++++ IOCCC 2015 +++++*/
main()
{
puts("hello world!");
}
+55
View File
@@ -0,0 +1,55 @@
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#define O_o "sfX4.Fv8H!`uf"\
"|~0y'vWtA@:LcO9d}y.!uL!Gd+ml(<+Ds!J"\
"e.6!r!%l6G!n~^<i=%pEwL%P!'<!FQt%u 5toG57j/3"\
"!:E%;!ea!!!WqE0z!f/y}!%!!Qi6!uzt!n}?]!bl!ak!SetR<"\
"Zj$x!~V!n&g8!cK! KrgR'8@c]!%-q9V.3fa[E8X%dY'w!#H <P~6"\
"?guhljL!^P% ?" "8!@dP,!!o+fb"\
"!pv!;!Hm%Ro4" "n:}nkD!Q!kN"\
"e:| 'b5sc!e" /* nothing */
#define mu(a) a a a a a //-
#define O_(Q_ ) "\033[" #Q_
#define Q_(O) mu(mu(mu(O)))
#define Q/*-- ++--*/O9--||(
#define main( )main(){/**/\
signal(13,1), _();}f()//--+
#define k( k) getenv( "D"#k
char*O0=O_o,OO,*Q1,O5[97];int*Q5,_Q=0,Q0=0,_O=0,_0=0,O=5,QQ,O6,Q6,O3
,Q4,O4=41088,O1=sizeof(O5),O7=234;long long __;_()Q_({)int*Q3,Q2,O2,OQ
,QO, O9=O,O8=!!/*OQ*/k(RAFT));long long Q8;char*Q9=O_(1A)O_(%dB)O_(%dC
)O_(34m)"\xe2%c%c\r\n"O_(0m)O_(%dA),*Q7;__+=(__*92+*O0-35-__)*(QO=Q_(!
!)(*O0-33)*!O9--),O0+=O1*QO,QO&&_(),Q Q4&&(O--,_(),O0+=194,O++,Q4--,_(
))),Q O=0,__=0,_(),O=3,_()),Q __&&(_O+=((OQ=__&15)<2)*12+!(QO=OQ&14^2)
*(4-_O)+(OQ==6)*(12-2*_O)+(OQ>6)*(9-(OQ-7)%3),_Q+=!QO*(_Q%QQ+(OQ&1)*O3
-_Q),_0+=!_0*!QO+(1-2*_0)*!(OQ^4),(OQ==5)&&(__>>=4,Q8=__,Q7 =O0,Q4=__&
15,O =1,_()|++O&_ (),O0 =Q7,__= Q8), Q3 =( Q2=(
_Q+= (lrand48() <O4*O1*9) *O8+ (OQ> 5)*((
(2<( _O%=8)%6) -(_O%7< 2))*QQ+( (_O +7)%8<
3)-( _O>4)))/ O3 )* O6+Q5+(O2= _Q %QQ)/2,
*Q3= *Q3 %O4+ O4 |(1<< Q_("@CADBE" "HI")[_Q
%O3/ QQ*2+_Q %2]- 64) *_0,sprintf (O5,Q9,Q2
+=1, O2 /2,* Q3>> 8,* Q3&85*3,Q2) &&_0&&(Q1
=O5, O =8,_() ), Q0+=( O2>Q0)*_0*( O2-Q0 ),
__+= (OQ>12)* (((__ +=!(OQ>9)* (3 -__+(__
>>4) )-3)<<4)+ OQ-3-__ ),usleep (O4 *_0/(3
*O8+ 1)), O=3,_())) ,!O9 --&& read(
1 ,& OO,1)> 0&&(O= (QO=OO ==35 )*3+6 ,_()
,QO&&(OO=10,O=6,_(),1)||(O=4,_()),0)||close(dup2(3-dup2(1,dup(0)-3),1)
*0+2)*0||Q write(1,"> ",2),ioctl(Q0=0,TIOCGWINSZ,O5)^--O&(O3=(QQ=(O6=*
((short*)O5+1))*2)*4),Q6=-O1,Q5=calloc(3*O6,8),_()),Q (O=8,QO=!(O2=OO-
10)|!(Q2=OO-32)*(Q0+58>QQ)|(Q0+12>QQ))&&(Q1=O_(3B),_(),write(1,"> ",2)
),Q0+=!QO*!Q2*4-QO*Q0,O2*Q2&&(!Q0&&(memset(Q5,0,3*O3),Q0=4,Q1="\n\n\n"
O_(3A),_()),O=7,_Q=7*QQ+Q0+2,_O=_0=0,OO+=(OO>64 &OO<91)*32,O0=Q_(O_o)+
O7,_(),(*O0-OO)||(O=2,O0+='a',_( )))),Q *O0-OO)&&(*(O0+=O1)-33)&&(O=0,
_(),O=7,O0+=O1,_()),Q write(0,Q1,strlen(Q1))),Q OO=Q_(O_o)[Q6+=O1],(Q6
%strlen(O_o)-O7)&&(O=6,_(),O=9,_()));Q_(})/*+++++ IOCCC 2015 +++++*/
main()
{
puts("hello world!");
}
+318
View File
@@ -0,0 +1,318 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-conversion -Wno-float-conversion -Wno-missing-prototypes \
-Wno-missing-variable-declarations -Wno-shadow -Wno-sign-conversion
# compiler standard
#
#CSTD=
#CSTD= -ansi
#CSTD= -std=c11
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=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= gray-scott-1 gray-scott-2 gray-scott-3 gray-scott-4 \
fitzhugh-nagumo-1 fitzhugh-nagumo-2 ginzburg-landau oregonator
GRAY_SCOTT_MODEL = -Delta_u="Du*laplacian(u)-u*v*v+F*(1-u)" \
-Delta_v="Dv*laplacian(v)+u*v*v-v*(F+K)"
FITZHUGH_NAGUMO_MODEL = -Delta_u="Du*laplacian(u)+u-u*u*u-v" \
-Delta_v="Dv*laplacian(v)+E*(u-A1*v-A0)"
GINZBURG_LANDAU_MODEL = \
-Delta_u="Du*laplacian(u)+A*u-G*v+(-B*u+D*v)*(u*u+v*v)" \
-Delta_v="Dv*laplacian(v)+A*v+G*u+(-B*v-D*u)*(u*u+v*v)"
OREGONATOR_MODEL = -Delta_u="Du*laplacian(u)+(u-u*u-F*v*(u-Q)/(u+Q))/E" \
-Delta_v="Dv*laplacian(v)+u-v"
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: gray-scott-1
${RM} -f $@
${CP} gray-scott-1 $@
gray-scott-1: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${GRAY_SCOTT_MODEL} -DDu=0.100 -DDv=0.050 -DF=0.035 -DK=0.060 \
-DUV_BACKGROUND=1,0 -DUV_DROP=-0.5,0.5 \
-DTIMESTEP=1.0 -DSPEED=8 -DRGB=255:128:192
gray-scott-2: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${GRAY_SCOTT_MODEL} -DDu=0.082 -DDv=0.041 -DF=0.035 -DK=0.063 \
-DUV_BACKGROUND=1,0 -DUV_DROP=-0.5,0.5 \
-DTIMESTEP=1.0 -DSPEED=8 -DRGB=128:255:192
gray-scott-3: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${GRAY_SCOTT_MODEL} -DDu=0.100 -DDv=0.050 -DF=0.030 -DK=0.060 \
-DUV_BACKGROUND=1,0 -DUV_DROP=-0.5,0.5 \
-DTIMESTEP=1.0 -DSPEED=8 -DRGB=255:128:192
gray-scott-4: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${GRAY_SCOTT_MODEL} -DDu=0.040 -DDv=0.020 -DF=0.012 -DK=0.050 \
-DUV_BACKGROUND=1,0 -DUV_DROP=-0.5,0.5 \
-DTIMESTEP=1.0 -DSPEED=8 -DRGB=192:192:255
fitzhugh-nagumo-1: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${FITZHUGH_NAGUMO_MODEL} -DDu=1 -DDv=3 -DA0=-0.1 -DA1=2 -DE=0.06 \
-DUV_BACKGROUND=0 -DUV_DROP=1,0 \
-DTIMESTEP=0.050 -DSPEED=80 -DRGB=128:192:255
fitzhugh-nagumo-2: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${FITZHUGH_NAGUMO_MODEL} -DDu=1 -DDv=10 -DA0=0.0 -DA1=1 -DE=1 \
-DUV_BACKGROUND=0 -DUV_DROP=1,1 \
-DTIMESTEP=0.005 -DSPEED=20 -DRGB=128:192:255
ginzburg-landau: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${GINZBURG_LANDAU_MODEL} -DDu=0.1 -DDv=0.1 -DA=0.0625 -DB=1 -DD=1.05 -DG=0.0625 \
-DUV_BACKGROUND=-0.1 -DUV_DROP=0,1 \
-DTIMESTEP=0.60 -DSPEED=40 -DRGB=128:255:128
oregonator: ${CSRC}
${CC} ${CFLAGS} -o $@ ${CSRC} \
${OREGONATOR_MODEL} -DDu=0.01 -DDv=0.01 -DE=0.1 -DF=1.4 -DQ=0.002 \
-DUV_BACKGROUND=0 -DUV_DROP=0.05,0.2 \
-DTIMESTEP=0.001 -DSPEED=80 -DRGB=128:192:255
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+1
View File
@@ -0,0 +1 @@
64,64
+209
View File
@@ -0,0 +1,209 @@
<!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 Diffused Reaction</title>
</head>
<body>
<h1>Most Diffused Reaction</h1>
<p>Someone Anonymous<br>
Twitter: @hirekoke</p>
<p>Yusuke Endoh<br>
<a href="https://github.com/mame/">https://github.com/mame/</a><br>
Twitter: @mametter</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
&lt;tbd-tool-rubl-perl-python?&gt;
</code></pre>
<h3>Try:</h3>
<pre><code>Connect to port http://localhost:10333 with your browser
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>How did the leopard get its spots? Why are a zebra&rsquo;s stripes unique?</p>
<p>In case you didn&rsquo;t recognise the portrait of Alan Turing, there are some
pointers to his features like eyes with &ldquo;stdeye-o&rdquo; and &ldquo;&lt;&ndash;mouth&rdquo;. Can you
find any other tributes?</p>
<h2>Author&rsquo;s comments:</h2>
<p>What does &ldquo;Alan Turing&rdquo; remind you of? Cryptanalysis of the Enigma? Turing machine? Turing test? This program is also based on his work.</p>
<h3>Whirlwind tour</h3>
<p>Compile the program as follows:</p>
<pre><code>$ clang -O3 -std=c99 \
-Wall -Wextra -pedantic -o prog prog.c \
-Delta_u="Du*laplacian(u)-u*v*v+F*(1-u)" \
-Delta_v="Dv*laplacian(v)+u*v*v-v*(F+K)" \
-DF=0.040 -DK=0.060 -DDu=0.200 -DDv=0.100 \
-DUV_BACKGROUND=1,0 -DUV_DROP=-0.5,0.5 \
-DTIMESTEP=1.0 -DSPEED=2 -DRGB=255:128:192
</code></pre>
<p>Then, run it under <code>tcpserver</code> command in <a href="http://cr.yp.to/ucspi-tcp.html">ucspi-tcp</a> package, which was created by Daniel J. Bernstein, IOCCC 1989 &ldquo;Best of Show&rdquo; winner.</p>
<pre><code>$ tcpserver -v 127.0.0.1 10333 ./prog ioccc.txt
</code></pre>
<p>Finally, open <code>http://127.0.0.1:10333/</code> by a modern browser supporting HTML5. You can use the mouse cursor to place drops into the Petri dish interactively.</p>
<h3>Description</h3>
<p>This is a simulator of <em>reaction-diffusion systems</em>.</p>
<p>Reaction-diffusion systems, proposed by Alan Turing in [1], are mathematical models in which two chemical substances are transformed into each other (<em>local chemical reactions</em>) and spread out (<em>diffusion</em>). Their interactions sometimes form non-trivial patterns, such as spots, spiral, dappling, and labyrinths.</p>
<p>The systems are generally formulated as follows:</p>
<pre><code>du/dt = F(u, v) + Du * laplacian(u)
dv/dt = G(u, v) + Dv * laplacian(v)
</code></pre>
<p>The functions <code>F(u, v)</code> and <code>G(u, v)</code> represent reactions of each substance, and the parameters <code>Du</code> and <code>Dv</code> are diffusion coefficients. By changing the functions and parameters, you can see a wide range of behaviors.</p>
<p>See <a href="https://en.wikipedia.org/wiki/Reaction%E2%80%93diffusion_system">the Wikipedia article of &ldquo;Reaction-diffusion system&rdquo;</a> in detail.</p>
<p>This program simulates the systems. The field consists of 128 x 128 cells. Each cell includes infomration of an amount of the two substances, and interacts with neighbor cells (in terms of von Neumann neighborhood) in each frame.</p>
<h3>Configuration</h3>
<p>You can change the model, initial pattern, simulation speed, and color via macro definition.</p>
<h4>Model: <code>-Delta_u=&lt;expression&gt; -Delta_v=&lt;expression&gt;</code></h4>
<p>The definitions represent the equations of reaction-diffusion system. For example, the following is <a href="http://groups.csail.mit.edu/mac/projects/amorphous/GrayScott/">the Gray-Scott model</a> in TeX notation.</p>
<pre><code>\frac{\partial u}{\partial t} = D_u \Delta u - u v^2 + F (1 - u)
\frac{\partial v}{\partial t} = D_v \Delta v + u v^2 - v (F + K)
</code></pre>
<p>You can specify this model as follows:</p>
<pre><code>-Delta_u="Du*laplacian(u)-u*v*v+F*(1-u)" \
-Delta_v="Dv*laplacian(v)+u*v*v-v*(F+K)"
</code></pre>
<p><code>Du</code>, <code>Dv</code>, <code>F</code>, and <code>K</code> are parameters of that model.</p>
<h4>Initial pattern: <code>-DUV_BACKGROUND=&lt;u0&gt;,&lt;v0&gt; -DUV_DROP=&lt;u1&gt;,&lt;v1&gt;</code></h4>
<p>The definitions specifies the initial amount of the two substances u and v. All cells have <code>(u0, v0)</code> by default.</p>
<p>You can specify a pattern file when the executable is invoked (not compile-time). The file should include a sequence of points, see <code>ioccc.txt</code>, <code>center.txt</code>, or <code>line.txt</code> as examples. Each amount in cells near to the point included in the file, will be added by <code>(u1, v1)</code>.</p>
<h4>Simulation speed: <code>-DTIMESTEP=ts -DSPEED=spd</code></h4>
<p>The definitions are for changing the simulation speed.</p>
<p><code>TIMESTEP</code> is a simulation time step. The bigger, the faster but more unstable.</p>
<p><code>SPEED</code> is a frameskip parameter. The bigger, the faster but more sluggish.</p>
<h4>Rendering color: <code>-DRGB=r:g:b</code></h4>
<p>This specifies a color used for rendering.</p>
<h3>Examples</h3>
<p>Some interesting parameters are included in <code>Makefile</code>. Do one of the following command and open <code>http://127.0.0.1:10333</code>.</p>
<pre><code>$ make gray-scott-1 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./gray-scott-1 ioccc.txt
$ make gray-scott-1 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./gray-scott-1 center.txt
$ make gray-scott-1 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./gray-scott-1 line.txt
$ make gray-scott-2 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./gray-scott-2 ioccc.txt
$ make gray-scott-3 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./gray-scott-3 ioccc.txt
$ make gray-scott-4 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./gray-scott-4 ioccc.txt
$ make fitzhugh-nagumo-1 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./fitzhugh-nagumo-1 ioccc.txt
$ make fitzhugh-nagumo-2 &amp;&amp; tcpserver -v 127.0.0.1 10333 ./fitzhugh-nagumo-2 ioccc.txt
$ make oregonator &amp;&amp; tcpserver -v 127.0.0.1 10333 ./oregonator ioccc.txt
</code></pre>
<p>These examples are created by drawing (and modifying) the pattern files of <a href="https://github.com/GollyGang/ready">Ready</a>, a cross-platform implementation of various reaction-diffusion systems [2].</p>
<h3>Compatibility</h3>
<h4>C part</h4>
<p>This program compiles clean with no warnings under <code>-std=c99 -Wall -Wextra -pedantic</code>. Since it uses <code>long long</code> for 64bit integers, C99 is required.</p>
<h4>Browser part</h4>
<p>You must use a modern browser that supports the latest specification of WebSocket [3]. All the following browsers worked for me:</p>
<ul>
<li>Google Chrome 45</li>
<li>Mozilla Firefox 39</li>
<li>Microsoft Internet Explorer 11 (works but sluggish)</li>
</ul>
<p>I think Safari 6 will work but I haven&rsquo;t tested. (I have no recent os x.)</p>
<h4>tcpserver alternatives</h4>
<p>I think you may use <code>inetd</code> and <code>xinetd</code> instead of <code>tcpserver</code>. Here is an example of inetd configuration.</p>
<pre><code>10333 stream tcp nowait nobody /path/to/prog /path/to/prog /path/to/initial-pattern.txt
</code></pre>
<p>But note that I didn&rsquo;t test well.</p>
<h3>Internal</h3>
<ol>
<li>The C program accepts HTTP connection from the browser, and sends a HTML document.</li>
<li>The browser tries to upgrade the connection to WebSocket.</li>
<li>The C program accepts WebSocket upgrade. This negotiation process requires SHA1 hash [4] and Base64 encoding [5]. The C program calculates them without the aid of any external libraries.</li>
<li>The C program simulates the reaction-diffusion system, and then send the field data to the browser on each frame.</li>
<li>The browser receives and renders the field data onto the HTML5 canvas.</li>
</ol>
<h3>References</h3>
<ul>
<li>[1] Turing, A. M., &ldquo;The Chemical Basis of Morphogenesis&rdquo;, Philosophical Transactions of the Royal Society, 1952.</li>
<li>[2] The Ready Bunch, &ldquo;Ready&rdquo;, A cross-platform implementation of various reaction-diffusion systems, since 2011, <a href="https://github.com/GollyGang/ready">https://github.com/GollyGang/ready</a>.</li>
<li>[3] Fette, I. and A. Melnikov, &ldquo;The WebSocket Protocol&rdquo;, RFC 6455, DOI 10.17487/RFC6455, December 2011, <a href="http://www.rfc-editor.org/info/rfc6455">http://www.rfc-editor.org/info/rfc6455</a>.</li>
<li>[4] Eastlake 3rd, D. and P. Jones, &ldquo;US Secure Hash Algorithm 1 (SHA1)&rdquo;, RFC 3174, DOI 10.17487/RFC3174, September 2001, <a href="http://www.rfc-editor.org/info/rfc3174">http://www.rfc-editor.org/info/rfc3174</a>.</li>
<li>[5] Josefsson, S., &ldquo;The Base16, Base32, and Base64 Data Encodings&rdquo;, RFC 4648, DOI 10.17487/RFC4648, October 2006, <a href="http://www.rfc-editor.org/info/rfc4648">http://www.rfc-editor.org/info/rfc4648</a>.</li>
</ul>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+173
View File
@@ -0,0 +1,173 @@
# Most Diffused Reaction
Someone Anonymous
Twitter: @hirekoke
Yusuke Endoh
<https://github.com/mame/>
Twitter: @mametter
## Judges' comments:
### To use:
make
<tbd-tool-rubl-perl-python?>
### Try:
Connect to port http://localhost:10333 with your browser
### Selected Judges Remarks:
How did the leopard get its spots? Why are a zebra's stripes unique?
In case you didn't recognise the portrait of Alan Turing, there are some
pointers to his features like eyes with "stdeye-o" and "<--mouth". Can you
find any other tributes?
## Author's comments:
What does "Alan Turing" remind you of? Cryptanalysis of the Enigma? Turing machine? Turing test? This program is also based on his work.
### Whirlwind tour
Compile the program as follows:
$ clang -O3 -std=c99 \
-Wall -Wextra -pedantic -o prog prog.c \
-Delta_u="Du*laplacian(u)-u*v*v+F*(1-u)" \
-Delta_v="Dv*laplacian(v)+u*v*v-v*(F+K)" \
-DF=0.040 -DK=0.060 -DDu=0.200 -DDv=0.100 \
-DUV_BACKGROUND=1,0 -DUV_DROP=-0.5,0.5 \
-DTIMESTEP=1.0 -DSPEED=2 -DRGB=255:128:192
Then, run it under `tcpserver` command in [ucspi-tcp](http://cr.yp.to/ucspi-tcp.html) package, which was created by Daniel J. Bernstein, IOCCC 1989 "Best of Show" winner.
$ tcpserver -v 127.0.0.1 10333 ./prog ioccc.txt
Finally, open `http://127.0.0.1:10333/` by a modern browser supporting HTML5. You can use the mouse cursor to place drops into the Petri dish interactively.
### Description
This is a simulator of *reaction-diffusion systems*.
Reaction-diffusion systems, proposed by Alan Turing in [1], are mathematical models in which two chemical substances are transformed into each other (*local chemical reactions*) and spread out (*diffusion*). Their interactions sometimes form non-trivial patterns, such as spots, spiral, dappling, and labyrinths.
The systems are generally formulated as follows:
du/dt = F(u, v) + Du * laplacian(u)
dv/dt = G(u, v) + Dv * laplacian(v)
The functions `F(u, v)` and `G(u, v)` represent reactions of each substance, and the parameters `Du` and `Dv` are diffusion coefficients. By changing the functions and parameters, you can see a wide range of behaviors.
See [the Wikipedia article of "Reaction-diffusion system"](https://en.wikipedia.org/wiki/Reaction%E2%80%93diffusion_system) in detail.
This program simulates the systems. The field consists of 128 x 128 cells. Each cell includes infomration of an amount of the two substances, and interacts with neighbor cells (in terms of von Neumann neighborhood) in each frame.
### Configuration
You can change the model, initial pattern, simulation speed, and color via macro definition.
#### Model: `-Delta_u=<expression> -Delta_v=<expression>`
The definitions represent the equations of reaction-diffusion system. For example, the following is [the Gray-Scott model](http://groups.csail.mit.edu/mac/projects/amorphous/GrayScott/) in TeX notation.
\frac{\partial u}{\partial t} = D_u \Delta u - u v^2 + F (1 - u)
\frac{\partial v}{\partial t} = D_v \Delta v + u v^2 - v (F + K)
You can specify this model as follows:
-Delta_u="Du*laplacian(u)-u*v*v+F*(1-u)" \
-Delta_v="Dv*laplacian(v)+u*v*v-v*(F+K)"
`Du`, `Dv`, `F`, and `K` are parameters of that model.
#### Initial pattern: `-DUV_BACKGROUND=<u0>,<v0> -DUV_DROP=<u1>,<v1>`
The definitions specifies the initial amount of the two substances u and v. All cells have `(u0, v0)` by default.
You can specify a pattern file when the executable is invoked (not compile-time). The file should include a sequence of points, see `ioccc.txt`, `center.txt`, or `line.txt` as examples. Each amount in cells near to the point included in the file, will be added by `(u1, v1)`.
#### Simulation speed: `-DTIMESTEP=ts -DSPEED=spd`
The definitions are for changing the simulation speed.
`TIMESTEP` is a simulation time step. The bigger, the faster but more unstable.
`SPEED` is a frameskip parameter. The bigger, the faster but more sluggish.
#### Rendering color: `-DRGB=r:g:b`
This specifies a color used for rendering.
### Examples
Some interesting parameters are included in `Makefile`. Do one of the following command and open `http://127.0.0.1:10333`.
$ make gray-scott-1 && tcpserver -v 127.0.0.1 10333 ./gray-scott-1 ioccc.txt
$ make gray-scott-1 && tcpserver -v 127.0.0.1 10333 ./gray-scott-1 center.txt
$ make gray-scott-1 && tcpserver -v 127.0.0.1 10333 ./gray-scott-1 line.txt
$ make gray-scott-2 && tcpserver -v 127.0.0.1 10333 ./gray-scott-2 ioccc.txt
$ make gray-scott-3 && tcpserver -v 127.0.0.1 10333 ./gray-scott-3 ioccc.txt
$ make gray-scott-4 && tcpserver -v 127.0.0.1 10333 ./gray-scott-4 ioccc.txt
$ make fitzhugh-nagumo-1 && tcpserver -v 127.0.0.1 10333 ./fitzhugh-nagumo-1 ioccc.txt
$ make fitzhugh-nagumo-2 && tcpserver -v 127.0.0.1 10333 ./fitzhugh-nagumo-2 ioccc.txt
$ make oregonator && tcpserver -v 127.0.0.1 10333 ./oregonator ioccc.txt
These examples are created by drawing (and modifying) the pattern files of [Ready](https://github.com/GollyGang/ready), a cross-platform implementation of various reaction-diffusion systems [2].
### Compatibility
#### C part
This program compiles clean with no warnings under `-std=c99 -Wall -Wextra -pedantic`. Since it uses `long long` for 64bit integers, C99 is required.
#### Browser part
You must use a modern browser that supports the latest specification of WebSocket [3]. All the following browsers worked for me:
* Google Chrome 45
* Mozilla Firefox 39
* Microsoft Internet Explorer 11 (works but sluggish)
I think Safari 6 will work but I haven't tested. (I have no recent os x.)
#### tcpserver alternatives
I think you may use `inetd` and `xinetd` instead of `tcpserver`. Here is an example of inetd configuration.
10333 stream tcp nowait nobody /path/to/prog /path/to/prog /path/to/initial-pattern.txt
But note that I didn't test well.
### Internal
1. The C program accepts HTTP connection from the browser, and sends a HTML document.
2. The browser tries to upgrade the connection to WebSocket.
3. The C program accepts WebSocket upgrade. This negotiation process requires SHA1 hash [4] and Base64 encoding [5]. The C program calculates them without the aid of any external libraries.
4. The C program simulates the reaction-diffusion system, and then send the field data to the browser on each frame.
4. The browser receives and renders the field data onto the HTML5 canvas.
### References
* [1] Turing, A. M., "The Chemical Basis of Morphogenesis", Philosophical Transactions of the Royal Society, 1952.
* [2] The Ready Bunch, "Ready", A cross-platform implementation of various reaction-diffusion systems, since 2011, <https://github.com/GollyGang/ready>.
* [3] Fette, I. and A. Melnikov, "The WebSocket Protocol", RFC 6455, DOI 10.17487/RFC6455, December 2011, <http://www.rfc-editor.org/info/rfc6455>.
* [4] Eastlake 3rd, D. and P. Jones, "US Secure Hash Algorithm 1 (SHA1)", RFC 3174, DOI 10.17487/RFC3174, September 2001, <http://www.rfc-editor.org/info/rfc3174>.
* [5] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, <http://www.rfc-editor.org/info/rfc4648>.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+48
View File
@@ -0,0 +1,48 @@
37,10,
47,10,
42,20,
42,30,
42,40,
37,50,
47,50,
91,10,
81,10,
76,20,
96,20,
76,30,
96,30,
76,40,
96,40,
91,50,
81,50,
25,78,
15,78,
10,88,
30,88,
10,98,
10,108,
30,108,
15,118,
25,118,
69,78,
59,78,
54,88,
74,88,
54,98,
54,108,
74,108,
59,118,
69,118,
113,78,
103,78,
98,88,
118,88,
98,98,
98,108,
118,108,
103,118,
113,118,
+12
View File
@@ -0,0 +1,12 @@
64,9,
64,19,
64,29,
64,39,
64,49,
64,59,
64,60,
64,79,
64,89,
64,99,
64,109,
64,119,
+53
View File
@@ -0,0 +1,53 @@
#define/**/Alan/**/(fflush(0),j=c=0;++c<b[6]+7;v=b[c]^(b[c+
char*H="close\r\nContent-Type:text/html\r\n\r\n<canvas id=\
'c'width='128'height='128'style='width:256px;height:256px'\
><script>x=y=-1;v=window.c;v.onmousemove=function(e){x=e.p\
ageX-v.offsetLeft;y=e. pageY-v.offsetTop};w=\
new WebSocket('ws'+ location.href.subs\
tr(4));w.binary" "Type='arraybuff\
er';w.onmess" "age=function(\
e){c=v.getC" "ontext('2d')\
;b=c.crea" "teI" "mageData(12\
8,128);u= new Uint8Array(d=e. data);b.dat\
a.set(u) ;c.putImageData(b,0,0) ;u[0]=x/2;\
u[1]=y/2 ;w.send(d.slice(0,x<0?0: 2));x=y=-\
1}</scr" "ipt>",b[9999];float*e,d[ 65536],u,v
,lu,lv, z;void*f;typedef unsigned long long
l;l*p,t[ 99]={0x67452301,0xEFCDAB89, 0x98BADCFE
,308438* 881,3285377520 },i,j,k ,n,m[204];
#include /*io*/ <stdio.h> /*turing*/
void s(){ ; for( k =0;k++<7 * 2 *9;)for(i=
0;++i<127; ) e=d + i* 4 +512*k,1[e] +=(i-u)*(i
-u)+(k-v)* (k- v )<20?*e+=UV_DROP:0;}l*q= m, g=1LL<<32;
l(h)(l v,l (a)){ return(v<<a)|(v%g>>(32-a ) );}int main
(int c/*ha r*/, char**y){for(e=d;fgets(b ,m[97]=480,\
stdin)&&*b >31; )for( i=j=0;n=b[i],i<18 ? (l)"sec-webs\
ocket-key: "[i] ==(n|32):n-32? m[j/4] |=(j< 24?n:(l)
"258EAFA5-" "E914-47DA-95CA-C5AB0DC85B" "11\x80"[j-24])
<<(3-j%4)*8 ,++j<61:1;)i++;for(j=3;--j; ){for(i=4;++i<74
;)i>9?p=q+i- 2 ,p[8]=h(p[5 ]^*p^p[-6]^p[-8]
#define/*hah aha <--mouth*/ laplacian(u)l##u
,1):(t[i]=t[9 -i] );for(p=t+7 ,i=-1;++i<82;k
=*p++,p[2]=h(p[1],5) +p[-3]+n+ (i/+ 20%2?*p^k^p[-
2]:(*p&k)|((i< 20?~*p:*p|k)&p [-2 ]))+*q++,t[+
81-i]+=(i>76)* (* p= h(* p,30*(i<80)
)))for(;n-k;n=((( 1LL +(9<<i/20
)/8)<<60)/k+k)/2) k=n ;} for (i =0;i<57;
i++)i<30?q[i%5* 16/ 3+ i/5] |=t[i%5]%g<<4
>>(30+i%5%3*2-i/5 *6)& 63,0 :(n =*q++,b[i-30]=
n<62?n-37+"fl!" [n /26]:n *4- 205);for(prin\
tf("HTTP/1.1 "/* | */"%d " "OK\r\nConnecti\
on:%s%.27s=\r\n\r\n" ,101 +99*! *m,!*m?H:"upgrade\
\r\nUpgrade:webso" "c" "ket\r\nSec-WebSocket-Acce\
pt:",b);e-d<65536 ; e+= 4)e[1]=(*e=UV_BACKGROUND);for
(;*m;c=0){for(f= c< 2 ?0:fopen(y[1],"r");f&&fscanf(f,
"%f,%f,",&u,&v)>0;)s ();for(;j<SPEED*4;j+=2)for(i=0;i<
63504;e+=5-j%4*2,z= TIMESTEP,*e=u+z*(elta_u),e[1]=v+z*
(elta_v),i+=4)for(c= 0;c+2;u=v,v=e[4],lu=lv,lv=e[-508]+*e+
e[8]+e[516]-v*4)e=d+i+512+i/504*8+j%4-c--;for(;n=c%4,65544>
c;c++)putchar(c>7?n>2||(u=d[c-n-7]*4*(n<2?!n?RGB))>255?255:
#define/*x*/Turing(x)4]=getchar()&127))u=v;if(b[6]>1)s();}}
u<0?0:u:c<0?124-c*3:c==5);/* -- The word "genius" is */ for
Alan Turing (1912--1954)
+254
View File
@@ -0,0 +1,254 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-char-subscripts -Wno-format-nonliteral
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
#CINCLUDE=
CINCLUDE= -include stdio.h
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+96
View File
@@ -0,0 +1,96 @@
<!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 Overlooked Obfuscation</title>
</head>
<body>
<h1>Most Overlooked Obfuscation</h1>
<p>Yusuke Endoh<br>
<a href="https://github.com/mame/">https://github.com/mame/</a><br>
Twitter: @mametter</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code>cat prog.c
./prog | diff - prog.c
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>At this point you might be wondering, <a href="http://acronyms.thefreedictionary.com/WTF">WTF</a>?*</p>
<pre><code>* What The Freak (polite form)
* What's This For? (you may be wondering)
* What the Fish (python form)
</code></pre>
<p>How is this code obfuscated? Well look again:</p>
<pre><code>less prog.c
more prog.c
</code></pre>
<p>Where did those underscores come from? Well <a href="http://acronyms.thefreedictionary.com/RTFS">RTFS</a>!**</p>
<pre><code>** Read the Freaking Source (polite form)
** Read The Freakin' Screen (polite form)
</code></pre>
<p>If you are still puzzled, look at prog.c with your favorite text editor.</p>
<h2>Author&rsquo;s comments:</h2>
<p><strong>Follow this instruction literally!</strong></p>
<pre><code>cat prog.c
gcc -w -o prog prog.c
./prog
</code></pre>
<p>You will do a double take.</p>
<p>Hint 1: Do <code>less prog.c</code>. You will see an <strong>emphasized</strong> string if your terminal supports bold.</p>
<p>Hint 2: Do <code>wc -c prog.c</code>. This is very long one-liner.</p>
<p>Spoiler: Open the source with an editor like <code>vim</code> or <code>emacs</code>.</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+67
View File
@@ -0,0 +1,67 @@
# Most Overlooked Obfuscation
Yusuke Endoh
<https://github.com/mame/>
Twitter: @mametter
## Judges' comments:
### To use:
make
./prog
### Try:
cat prog.c
./prog | diff - prog.c
### Selected Judges Remarks:
At this point you might be wondering, [WTF](http://acronyms.thefreedictionary.com/WTF)?\*
* What The Freak (polite form)
* What's This For? (you may be wondering)
* What the Fish (python form)
How is this code obfuscated? Well look again:
less prog.c
more prog.c
Where did those underscores come from? Well [RTFS](http://acronyms.thefreedictionary.com/RTFS)!\*\*
** Read the Freaking Source (polite form)
** Read The Freakin' Screen (polite form)
If you are still puzzled, look at prog.c with your favorite text editor.
## Author's comments:
**Follow this instruction literally!**
cat prog.c
gcc -w -o prog prog.c
./prog
You will do a double take.
Hint 1: Do `less prog.c`. You will see an **emphasized** string if your terminal supports bold.
Hint 2: Do `wc -c prog.c`. This is very long one-liner.
Spoiler: Open the source with an editor like `vim` or `emacs`.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+1
View File
@@ -0,0 +1 @@
int main(){ printf("");{char*p,s[999]="int main(){ printf(~~);{char*p,s[999]=~%s~,*q=s,c;for(p=62**~~+q;q<s+435;c=q-s>*~s~||c>8?*p++=c-35?*~}~<c?34:c:92:0,p[*~~]=0)c=*q++;*p=2+*~~;printf(s+62**~~,s);}return(*~#0_HH_ee_ll_ll_oo_,,_  _ww_oo_rr_ll_dd_!!#n~); }",*q=s,c;for(p=62**""+q;q<s+435;c=q-s>*"s"||c>8?*p++=c-35?*"}"<c?34:c:92:0,p[*""]=0)c=*q++;*p=2+*"";printf(s+62**"",s);}return(*"\0_HH_ee_ll_ll_oo_,,_  _ww_oo_rr_ll_dd_!!\n"); }
+254
View File
@@ -0,0 +1,254 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
CSILENCE= -Wno-cast-align -Wno-missing-prototypes \
-Wno-missing-variable-declarations -Wno-shorten-64-to-32 \
-Wno-unreachable-code
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
BACK_TO= mullender.c
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS} ${BACK_TO}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+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>Back to the Future Award</title>
</head>
<body>
<h1>Back to the Future Award</h1>
<p>Yusuke Endoh<br>
<a href="https://github.com/mame/">https://github.com/mame/</a><br>
Twitter: @mametter</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code>make -B BACK_TO=ioccc.c
./prog
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Like Marty and Doc, something nostalgic from 1984 appears live in October of 2015!
The author of this gem is a true Delorean!</p>
<p>A question for inquisitive readers: is the implemented subset of PDP-11 instructions Turing-complete?
(For a clue, see the end of the author&rsquo;s remarks.)
If in doubt, use <a href="http://www.tuhs.org/Archive/PDP-11/Emulators/Apout/">APOUT</a>.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Hint / Compatibility</h3>
<ul>
<li>A little-endian system is required due to an external factor.</li>
<li>Strictly speaking, this program does not comply with any C specification for the same reason. But I believe it is reasonably portable.</li>
<li>It uses a GCC extension but works on clang.</li>
<li>This is a kind of emulator. You may find its architecture name if you look at the source code from all angles.</li>
<li>Find main() function.</li>
</ul>
<h3>Spoiler</h3>
<p>This program is a joke PDP-11 emulator. (&ldquo;ll-dpd&rdquo; is embedded in the code. Read it upside down.)</p>
<p>You got it? This program is supposed to be used in this way:</p>
<pre><code>$ wget http://ioccc.org/1984/mullender.c
$ clang -o prog prog.c mullender.c
$ ./prog
</code></pre>
<p>You can enjoy the legendary winner of the first IOCCC, again.</p>
<h3>Internal</h3>
<p>This program uses <code>__attribute__((constructor))</code>, which is a GCC extension, to hijack the main function call. And then it interprets main as an instruction sequence.</p>
<p>It supports the minimal subset of instructions and addressing modes which are needed for mullender.c to work:</p>
<ul>
<li><p>Instructions</p>
<ul>
<li>BR: branch</li>
<li>MOV: move</li>
<li>SOB: subtract one and branch</li>
<li>SUB: subtract</li>
<li>TRAP 4: write syscall</li>
<li>TST: test (no flag is supported, though)</li>
</ul>
</li>
<li><p>Addressing modes</p>
<ul>
<li>0: Register</li>
<li>1: Register deferred</li>
<li>2: Autoincrement</li>
<li>4: Autodecrement deferred</li>
<li>6: Index (incomplete)</li>
</ul>
</li>
</ul>
<h3>Limitation</h3>
<p>Non-trivial combination of instruction and addressing mode may cause undefined behavior (unsequenced modification), such as attempting to autoincrement a destination register. Index addressing mode works well only for R7 (PC register).</p>
<h3>One more thing</h3>
<p>Note: the program writes a binary to stdout.</p>
<pre><code>short main[]={5568,1,-30460,12,2782,0,-29921,2056,-4864,6873,770,30054,11886,
24948,114,21716,-28851,14043,-8944,32691,-16187,-12247,22692,-9781,-20403,
-11771,16546,18710,17873,9233,31304,-32215,-24382,-28247,-25916,10466,24988,
-3404,-4177,-28528,-531,-3016,17300,-28552,-7708,-26180,-4297,-367,-2312,
-25611,28535,-8533,24004,25421,-1224,-5354,-20807,-21589,-6761,-5203,-1055,
-6715,-26673,-1433,-17732,-24198,14681,-3714,-6660,-14891,-25575,20349,-7701,
-8336,31433,16695,-14773,26819,3096,-12584,-28808,17825,-21200,-32399,15877,
-28890,-3728,-27126,21375,-32630,-7615,32004,-29230,-6611,-5508,-28921,12418,
27204,-5725,9643,3520,26836,-29347,2101,-29311,9320,29287,-29990,-6593,29825,
-29114,16232,25641,20672,-23501,-32127,-6546,-956,10474,-29647,1070,5516,13760,
-27814,-32488,-28006,-17968,-3146,10963,19234,22132,23988,7142,5523,9639,-6888,
-11428,7964,23099,-16822,16518,31109,-12958,10351,2434,3091,3625,2244,27512,
-28559,-10724,-19377,23625,30056,11478,-21176,27660,26517,-29037,-9390,12297,
-11903,5980,-21927,-7483,6671,11249,29638,-23827,-26358,-6856,-1063,-5303,
26636,25797,31818,26798,-4243,-18772,-13266,27472,-12005,-10642,-22524,24373,
-13111,-9062,6274,-20002,24150,22189,-14965,-31249,-13934,-6341,-18384,-32054,
-29246,10622,-9260,19428,-15485,2724,23810,16447,11627,18604,2739,27812,30295,
-21538,-31786,11355,-11308,-9006,-4987,25363,-18927,-21130,-31213,-27411,17231,
-19608,20232,27754,16476,11213,-19803,-24048,30918,-25329,21233,-10160,13519,
11828,26653,-6703,10893,6871,-12417,24471,20310,-12137,-19677,4457,-19530,
10147,17724,533,-10055,27076,10264,11274,-10511,4809,25208,16065,-5105,-19953,
3772,-12124,13475,-27559,-9955,26446,15133,15207,-23640,6425,-11010,28688,
-20064,26353,-889,-25008,10380,-14449,-6894,18920,-23900,16902,-31018,16093,
20875,-19576,4585,13126,18589,24789,19424,31274,-5059,-14538,-3125,-16527,
-25070,-9013,26628,15756,-7652,30841,-1283,17707,25717,-18315,-6342,6880,
-19176,6995,5672,2853,-9044,-3409,-14421,-7522,13108,20582,-25317,1376,-5648,
13821,17300,1220,-29437,-25832,-8332,-15575,-9744,28297,31995,-1217,23852,
14382,31059,9160,-3296,20287,-28357,24449,-10323,-21992,-4655,-32548,13237,
-15083,-25226,-21121,2015,-8996,-20247,-27551,-14771,-16089,-6920,-9645,21578,
7142,-5613,14029,24730,-29253,13931,-3862,-16634,-7388,16951,15771,31302,
-22186,-6716,18416,1698,-26200,-16231,9821,-10886,-4994,-30527,-9448,-16923,
29549,-11207,-14909,-3643,-27548,17865,28859,29753,17616,16874,-17733,9424,
21435,-31715,24544,8666,30844,25075,-18267,12027,-5346,2717,19615,-4548,-21763,
28514,11691,22268,-2338,1406,-27379,-23568,-24525,13633,11295,-14715,7877,
-27669,3475,20345,7779,-17849,2184,7132,4079,-24937,11585,22740,5810,-10855,
16203,-6371,23235,-7,-24828,-11205,-11006,-10,-17812,-14274,11504,-27517,463,
4498,-32180,-9775,-3190,-22435,-18662,-30146,-31834,-26449,-19374,-12616,
-10596,14341,-10089,-18449,-16535,21439,21191,-1651,7695,-30009,-23339,-8675,
-20774,21588,-2793,8218,-14337,-10866,14060,-15343,31712,25247,-8539,18074,
-28683,-7363,-7663,-3563,-30718,17771,28687,-30495,30584,14022,-28053,5292,
-31576,-32486,-15470,-1330,23551,-2185,-10829,-13216,-4825,-2964,-14668,24559,
-4930,23731,-1152,-11493,-2321,15987,-27073,-20305,-24065,-25048,32750,-27440,
-1169,-25633,-4356,-24993,30439,-17165,-4580,8662,22655,-4588,-6162,-3122,
31986,-2569,20371,-12320,-25613,-16133,-25644,23677,12254,5855,26325,-13425,
-15903,-1930,-28488,31222,31153,17607,-2758,7594,-8868,30434,-2518,27956,
-19424,7370,6199,-17602,17347,-14358,25588,11611,-25209,-23701,-27444,-29788,
2680,-27406,9318,22483,-28356,28482,4577,-14891,17323,-30152,2507,2977,5004,
-11696,-31623,-15149,13357,28938,-14048,19490,-19860,-26050,10842,-24922,
-20986,8847,-31184,28519,-29168,32195,10516,25713,-3493,670,31283,-12769,
-17461,11357,13180,26133,15944,18051,-32167,-27990,16813,17676,21787,-17578,
11173,19093,2836,656,-15239,4632,23937,4106,-21655,-7494,-21575,-17647,-18465,
-14654,-29990,-10707,-12440,21465,5822,26164,-1404,-14303,-26635,-6900,-23611,
11998,-18551,971,27579,13325,4579,23059,29281,22291,29880,-17546,25664,-14990,
-526,-35,28218,-3214,11965,11263,6633,30719,32400,-29,-3733,24383,32678,-27542,
-4444,6196,5975,-19722,11902,16840,-11680,11146,-26391,-8980,21573,-9043,2349,
-12887,5916,-2996,10410,-23374,26338,11867,-14518,18281,14450,-5815,13842,359,
25450,27043,3355,13423,-20880,-26311,-30720,-2503,-6046,-18156,-18558,-14774,
-15664,-29001,3365,-12689,10233,23608,24692,12039,15445,18411,-27469,3764,
-10841,22672,23844,2282,-12443,2851,-27163,13651,13738,17201,-29819,27414,
-29764,-5308,-16171,-32427,-26312,-7460,-27376,-6004,25717,29254,-15015,8754,
15493,22232,-28513,-23355,23676,7736,10571,-8120,-16677,7696,32549,-2646,25538,
3498,30960,-28459,24716,12655,-10496,402,26209,482,-16661,-20350,-3403,14015,
32299,11262,-25886,4092,-7843,-100,-1975,-58,-3729,-19269,-23583,-6929,20000,
-6089,17780,-3250,29830,19954,-29277,27896,10330,9277,-25358,31279,-14454,
24203,-30170,12872,-21973,-25773,-10502,-6647,-26143,6394,-13479,-24559,23007,
-21844,1505,24702,-23187,-24364,-20470,20765,-7107,15674,9404,17408,17964,
19820,18952,2154,-26052,30056,-3227,17770,-8557,-31018,-27700,-25974,9003,
18218,22730,-19981,6737,3532,1562,-23626,14990,28472,-5270,17358,-32204,-29197,
-3647,4296,8588,25302,-23906,30328,-29119,-24392,8992,-16557,31530,-31216,
14107,13041,-6976,7529,-8296,17865,-1462,8181,-21588,-131,-10177,-25931,-14627,
8301,3708,-32097,20808,13892,-21179,1192,20853,3249,-8774,20843,3520,24954,
-14215,-25170,-16170,2390,25964,-23923,-17464,-7177,-27568,-9880,-4647,-7323,
15388,2113,-12338,-7737,26255,26818,-22156,-19610,-911,-17057,-556,29935,27647,
31806,23676,-18132,-19234,-10869,-3715,24983,-10900,-29564,19856,-16392,-31860,
-25826,24077,12080,15383,-29852,-2266,-27217,31931,-3183,17385,-14211,19050,
-2449,-468,-2871,-11466,973,2866,649,1367,-8688,-24069,20992,25139,-25850,1184,
15851,785,16951,12160,22337,-21851,1849,-18801,14247,-429,-12682,30881,-11273,
-24819,-9794,8389,-27287,7525,16633,1328,-26650,32607,-8217,31912,7774,-16188,
-3546,-6550,-16279,-32696,1940,2577,-23723,-6484,2009,-424,27833,-21763,-13902,
7044,27360,-18450,27889,23987,3137,-7669,-5784,-7490,24946,32302,26464,-15513,
28898,2493,-17645,-4615,-13434,-20884,-4058,-29951,-22281,24784,21083,-8536,
22147,-11261,-15069,20659,2993,19029,21909,6748,-3263,1401,30960,11000,-16871,
-30566,-14959,-26356,-2885,21526,-26531,31063,12857,4992,-5067,3130,-17602,
-1732,-6593,30200,24679,3267,310,20733,24863,-15669,7875,-4577,-13821,-22325,
15548,29744,3733,-14547,21459,22122,3854,-2572,30197,-24770,-21263,8793,-8316,
1571,28191,-16143,-6446,31524,-26496,-17349,-29097,2806,11281,-7041,-683,14149,
19689,-22094,-1657,-30904,183,-15226,-6358,25461,461,1495,28345,-10554,-4004,
27119,13484,-21600,-12272,-7272,-14064,-299,10697,11280,19066,-9841,-7265,
-18002,19906,-17247,21482,-10939,-5897,-22300,-13978,27575,-8684,-6222,-19041,
5788,-30863,-10134,15142,2895,14705,-17713,12940,-21535,-11619,29416,18417,
-24973,24867,-26462,-24910,-32556,-26705,-7187,-7750,-758,-14809,20289,9260,
13778,-1422,30301,-1922,30646,27662,-15465,-912,29340,13846,-1263,28887,-20019,
32421,-29411,-27632,-7495,-8368,29230,-6386,-19536,-5235,2054,1854,23563,12348,
-15165,-2936,-28063,-15760,20126,-25531,4963,-5739,23182,16895,-17258,-10470,
-3969,-7742,-140,4475,-24014,-31961,19231,27153,-18551,20157,26443,11530,
-22214,2284,-24238,-31051,-26422,9088,29868,18458,8488,-9515,6799,-12507,54,
-19441,-32665,12561,23560,4725,-28617,-14800,-10224,-13503,-17636,-16823,
-24072,18735,-29798,-23658,-670,-21769,7489,-6468,-8961,-14785,22255,11582,
-29831,16303,-19652,2922,-4362,22966,16173,-18446,-6148,27381,-8493,-32289,
24005,-3027,-18665,-16472,-17793,-27027,-7443,17854,31365,-17726,-2510,-17546,
14893,21773,-23634,21117,32533,6637,-1106,-8152,-3672,-113,-2149,-34,-22700,
-4102,-28533,-14104,-10086,4378,13695,-15320,-28258,2246,7595,30021,13281,
-11968,-29983,14274,27152,26713,19434,17058,1142,-3043,-16496,18630,-11976,
29168,-3634,32746,27287,-268,16711,-8712,-471,12895,17406,-22548,-3969,-10733,
13128,10530,-31667,7929,-32277,30926,-1983,8401,-7705,6790,4532,1442,26728,
29600,-15358,21622,9744,11406,15989,-30741,-15044,29913,24534,6774,-3755,17623,
19647,18762,10042,9653,-5889,2408,-32579,-6285,-28559,-30655,6294,-21175,4390,
1668,25437,2821,21066,-13680,5274,-27253,-5248,-26307,29744,-26428,25358,17196,
15199,-29784,-4604,25653,-8048,-23131,-28995,31340,-9558,26186,11268,27916,
9646,-7389,-11384,-29116,-4100,160,18394,7856,738,-25920,12148,24713,-31664,
8203,-25556,13494,30352,29161,30898,1432,-5991,25411,1344,-4019,22299,15685,
-16401,-23136,-28110,11874,-18945,1879,2,0,-32256,-20996,-18169,29220,12,0,0,0,
335,-27277,-30776,20480,0};
</code></pre>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+205
View File
@@ -0,0 +1,205 @@
# Back to the Future Award
Yusuke Endoh
<https://github.com/mame/>
Twitter: @mametter
## Judges' comments:
### To use:
make
./prog
### Try:
make -B BACK_TO=ioccc.c
./prog
### Selected Judges Remarks:
Like Marty and Doc, something nostalgic from 1984 appears live in October of 2015!
The author of this gem is a true Delorean!
A question for inquisitive readers: is the implemented subset of PDP-11 instructions Turing-complete?
(For a clue, see the end of the author's remarks.)
If in doubt, use [APOUT](http://www.tuhs.org/Archive/PDP-11/Emulators/Apout/).
## Author's comments:
### Hint / Compatibility
* A little-endian system is required due to an external factor.
* Strictly speaking, this program does not comply with any C specification for the same reason. But I believe it is reasonably portable.
* It uses a GCC extension but works on clang.
* This is a kind of emulator. You may find its architecture name if you look at the source code from all angles.
* Find main() function.
### Spoiler
This program is a joke PDP-11 emulator. ("ll-dpd" is embedded in the code. Read it upside down.)
You got it? This program is supposed to be used in this way:
$ wget http://ioccc.org/1984/mullender.c
$ clang -o prog prog.c mullender.c
$ ./prog
You can enjoy the legendary winner of the first IOCCC, again.
### Internal
This program uses `__attribute__((constructor))`, which is a GCC extension, to hijack the main function call. And then it interprets main as an instruction sequence.
It supports the minimal subset of instructions and addressing modes which are needed for mullender.c to work:
* Instructions
* BR: branch
* MOV: move
* SOB: subtract one and branch
* SUB: subtract
* TRAP 4: write syscall
* TST: test (no flag is supported, though)
* Addressing modes
* 0: Register
* 1: Register deferred
* 2: Autoincrement
* 4: Autodecrement deferred
* 6: Index (incomplete)
### Limitation
Non-trivial combination of instruction and addressing mode may cause undefined behavior (unsequenced modification), such as attempting to autoincrement a destination register. Index addressing mode works well only for R7 (PC register).
### One more thing
Note: the program writes a binary to stdout.
short main[]={5568,1,-30460,12,2782,0,-29921,2056,-4864,6873,770,30054,11886,
24948,114,21716,-28851,14043,-8944,32691,-16187,-12247,22692,-9781,-20403,
-11771,16546,18710,17873,9233,31304,-32215,-24382,-28247,-25916,10466,24988,
-3404,-4177,-28528,-531,-3016,17300,-28552,-7708,-26180,-4297,-367,-2312,
-25611,28535,-8533,24004,25421,-1224,-5354,-20807,-21589,-6761,-5203,-1055,
-6715,-26673,-1433,-17732,-24198,14681,-3714,-6660,-14891,-25575,20349,-7701,
-8336,31433,16695,-14773,26819,3096,-12584,-28808,17825,-21200,-32399,15877,
-28890,-3728,-27126,21375,-32630,-7615,32004,-29230,-6611,-5508,-28921,12418,
27204,-5725,9643,3520,26836,-29347,2101,-29311,9320,29287,-29990,-6593,29825,
-29114,16232,25641,20672,-23501,-32127,-6546,-956,10474,-29647,1070,5516,13760,
-27814,-32488,-28006,-17968,-3146,10963,19234,22132,23988,7142,5523,9639,-6888,
-11428,7964,23099,-16822,16518,31109,-12958,10351,2434,3091,3625,2244,27512,
-28559,-10724,-19377,23625,30056,11478,-21176,27660,26517,-29037,-9390,12297,
-11903,5980,-21927,-7483,6671,11249,29638,-23827,-26358,-6856,-1063,-5303,
26636,25797,31818,26798,-4243,-18772,-13266,27472,-12005,-10642,-22524,24373,
-13111,-9062,6274,-20002,24150,22189,-14965,-31249,-13934,-6341,-18384,-32054,
-29246,10622,-9260,19428,-15485,2724,23810,16447,11627,18604,2739,27812,30295,
-21538,-31786,11355,-11308,-9006,-4987,25363,-18927,-21130,-31213,-27411,17231,
-19608,20232,27754,16476,11213,-19803,-24048,30918,-25329,21233,-10160,13519,
11828,26653,-6703,10893,6871,-12417,24471,20310,-12137,-19677,4457,-19530,
10147,17724,533,-10055,27076,10264,11274,-10511,4809,25208,16065,-5105,-19953,
3772,-12124,13475,-27559,-9955,26446,15133,15207,-23640,6425,-11010,28688,
-20064,26353,-889,-25008,10380,-14449,-6894,18920,-23900,16902,-31018,16093,
20875,-19576,4585,13126,18589,24789,19424,31274,-5059,-14538,-3125,-16527,
-25070,-9013,26628,15756,-7652,30841,-1283,17707,25717,-18315,-6342,6880,
-19176,6995,5672,2853,-9044,-3409,-14421,-7522,13108,20582,-25317,1376,-5648,
13821,17300,1220,-29437,-25832,-8332,-15575,-9744,28297,31995,-1217,23852,
14382,31059,9160,-3296,20287,-28357,24449,-10323,-21992,-4655,-32548,13237,
-15083,-25226,-21121,2015,-8996,-20247,-27551,-14771,-16089,-6920,-9645,21578,
7142,-5613,14029,24730,-29253,13931,-3862,-16634,-7388,16951,15771,31302,
-22186,-6716,18416,1698,-26200,-16231,9821,-10886,-4994,-30527,-9448,-16923,
29549,-11207,-14909,-3643,-27548,17865,28859,29753,17616,16874,-17733,9424,
21435,-31715,24544,8666,30844,25075,-18267,12027,-5346,2717,19615,-4548,-21763,
28514,11691,22268,-2338,1406,-27379,-23568,-24525,13633,11295,-14715,7877,
-27669,3475,20345,7779,-17849,2184,7132,4079,-24937,11585,22740,5810,-10855,
16203,-6371,23235,-7,-24828,-11205,-11006,-10,-17812,-14274,11504,-27517,463,
4498,-32180,-9775,-3190,-22435,-18662,-30146,-31834,-26449,-19374,-12616,
-10596,14341,-10089,-18449,-16535,21439,21191,-1651,7695,-30009,-23339,-8675,
-20774,21588,-2793,8218,-14337,-10866,14060,-15343,31712,25247,-8539,18074,
-28683,-7363,-7663,-3563,-30718,17771,28687,-30495,30584,14022,-28053,5292,
-31576,-32486,-15470,-1330,23551,-2185,-10829,-13216,-4825,-2964,-14668,24559,
-4930,23731,-1152,-11493,-2321,15987,-27073,-20305,-24065,-25048,32750,-27440,
-1169,-25633,-4356,-24993,30439,-17165,-4580,8662,22655,-4588,-6162,-3122,
31986,-2569,20371,-12320,-25613,-16133,-25644,23677,12254,5855,26325,-13425,
-15903,-1930,-28488,31222,31153,17607,-2758,7594,-8868,30434,-2518,27956,
-19424,7370,6199,-17602,17347,-14358,25588,11611,-25209,-23701,-27444,-29788,
2680,-27406,9318,22483,-28356,28482,4577,-14891,17323,-30152,2507,2977,5004,
-11696,-31623,-15149,13357,28938,-14048,19490,-19860,-26050,10842,-24922,
-20986,8847,-31184,28519,-29168,32195,10516,25713,-3493,670,31283,-12769,
-17461,11357,13180,26133,15944,18051,-32167,-27990,16813,17676,21787,-17578,
11173,19093,2836,656,-15239,4632,23937,4106,-21655,-7494,-21575,-17647,-18465,
-14654,-29990,-10707,-12440,21465,5822,26164,-1404,-14303,-26635,-6900,-23611,
11998,-18551,971,27579,13325,4579,23059,29281,22291,29880,-17546,25664,-14990,
-526,-35,28218,-3214,11965,11263,6633,30719,32400,-29,-3733,24383,32678,-27542,
-4444,6196,5975,-19722,11902,16840,-11680,11146,-26391,-8980,21573,-9043,2349,
-12887,5916,-2996,10410,-23374,26338,11867,-14518,18281,14450,-5815,13842,359,
25450,27043,3355,13423,-20880,-26311,-30720,-2503,-6046,-18156,-18558,-14774,
-15664,-29001,3365,-12689,10233,23608,24692,12039,15445,18411,-27469,3764,
-10841,22672,23844,2282,-12443,2851,-27163,13651,13738,17201,-29819,27414,
-29764,-5308,-16171,-32427,-26312,-7460,-27376,-6004,25717,29254,-15015,8754,
15493,22232,-28513,-23355,23676,7736,10571,-8120,-16677,7696,32549,-2646,25538,
3498,30960,-28459,24716,12655,-10496,402,26209,482,-16661,-20350,-3403,14015,
32299,11262,-25886,4092,-7843,-100,-1975,-58,-3729,-19269,-23583,-6929,20000,
-6089,17780,-3250,29830,19954,-29277,27896,10330,9277,-25358,31279,-14454,
24203,-30170,12872,-21973,-25773,-10502,-6647,-26143,6394,-13479,-24559,23007,
-21844,1505,24702,-23187,-24364,-20470,20765,-7107,15674,9404,17408,17964,
19820,18952,2154,-26052,30056,-3227,17770,-8557,-31018,-27700,-25974,9003,
18218,22730,-19981,6737,3532,1562,-23626,14990,28472,-5270,17358,-32204,-29197,
-3647,4296,8588,25302,-23906,30328,-29119,-24392,8992,-16557,31530,-31216,
14107,13041,-6976,7529,-8296,17865,-1462,8181,-21588,-131,-10177,-25931,-14627,
8301,3708,-32097,20808,13892,-21179,1192,20853,3249,-8774,20843,3520,24954,
-14215,-25170,-16170,2390,25964,-23923,-17464,-7177,-27568,-9880,-4647,-7323,
15388,2113,-12338,-7737,26255,26818,-22156,-19610,-911,-17057,-556,29935,27647,
31806,23676,-18132,-19234,-10869,-3715,24983,-10900,-29564,19856,-16392,-31860,
-25826,24077,12080,15383,-29852,-2266,-27217,31931,-3183,17385,-14211,19050,
-2449,-468,-2871,-11466,973,2866,649,1367,-8688,-24069,20992,25139,-25850,1184,
15851,785,16951,12160,22337,-21851,1849,-18801,14247,-429,-12682,30881,-11273,
-24819,-9794,8389,-27287,7525,16633,1328,-26650,32607,-8217,31912,7774,-16188,
-3546,-6550,-16279,-32696,1940,2577,-23723,-6484,2009,-424,27833,-21763,-13902,
7044,27360,-18450,27889,23987,3137,-7669,-5784,-7490,24946,32302,26464,-15513,
28898,2493,-17645,-4615,-13434,-20884,-4058,-29951,-22281,24784,21083,-8536,
22147,-11261,-15069,20659,2993,19029,21909,6748,-3263,1401,30960,11000,-16871,
-30566,-14959,-26356,-2885,21526,-26531,31063,12857,4992,-5067,3130,-17602,
-1732,-6593,30200,24679,3267,310,20733,24863,-15669,7875,-4577,-13821,-22325,
15548,29744,3733,-14547,21459,22122,3854,-2572,30197,-24770,-21263,8793,-8316,
1571,28191,-16143,-6446,31524,-26496,-17349,-29097,2806,11281,-7041,-683,14149,
19689,-22094,-1657,-30904,183,-15226,-6358,25461,461,1495,28345,-10554,-4004,
27119,13484,-21600,-12272,-7272,-14064,-299,10697,11280,19066,-9841,-7265,
-18002,19906,-17247,21482,-10939,-5897,-22300,-13978,27575,-8684,-6222,-19041,
5788,-30863,-10134,15142,2895,14705,-17713,12940,-21535,-11619,29416,18417,
-24973,24867,-26462,-24910,-32556,-26705,-7187,-7750,-758,-14809,20289,9260,
13778,-1422,30301,-1922,30646,27662,-15465,-912,29340,13846,-1263,28887,-20019,
32421,-29411,-27632,-7495,-8368,29230,-6386,-19536,-5235,2054,1854,23563,12348,
-15165,-2936,-28063,-15760,20126,-25531,4963,-5739,23182,16895,-17258,-10470,
-3969,-7742,-140,4475,-24014,-31961,19231,27153,-18551,20157,26443,11530,
-22214,2284,-24238,-31051,-26422,9088,29868,18458,8488,-9515,6799,-12507,54,
-19441,-32665,12561,23560,4725,-28617,-14800,-10224,-13503,-17636,-16823,
-24072,18735,-29798,-23658,-670,-21769,7489,-6468,-8961,-14785,22255,11582,
-29831,16303,-19652,2922,-4362,22966,16173,-18446,-6148,27381,-8493,-32289,
24005,-3027,-18665,-16472,-17793,-27027,-7443,17854,31365,-17726,-2510,-17546,
14893,21773,-23634,21117,32533,6637,-1106,-8152,-3672,-113,-2149,-34,-22700,
-4102,-28533,-14104,-10086,4378,13695,-15320,-28258,2246,7595,30021,13281,
-11968,-29983,14274,27152,26713,19434,17058,1142,-3043,-16496,18630,-11976,
29168,-3634,32746,27287,-268,16711,-8712,-471,12895,17406,-22548,-3969,-10733,
13128,10530,-31667,7929,-32277,30926,-1983,8401,-7705,6790,4532,1442,26728,
29600,-15358,21622,9744,11406,15989,-30741,-15044,29913,24534,6774,-3755,17623,
19647,18762,10042,9653,-5889,2408,-32579,-6285,-28559,-30655,6294,-21175,4390,
1668,25437,2821,21066,-13680,5274,-27253,-5248,-26307,29744,-26428,25358,17196,
15199,-29784,-4604,25653,-8048,-23131,-28995,31340,-9558,26186,11268,27916,
9646,-7389,-11384,-29116,-4100,160,18394,7856,738,-25920,12148,24713,-31664,
8203,-25556,13494,30352,29161,30898,1432,-5991,25411,1344,-4019,22299,15685,
-16401,-23136,-28110,11874,-18945,1879,2,0,-32256,-20996,-18169,29220,12,0,0,0,
335,-27277,-30776,20480,0};
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+1
View File
@@ -0,0 +1 @@
short main[] = { 5568,1,-30460,12,10,509,20297,17219,12867,12592,3381 };
+10
View File
@@ -0,0 +1,10 @@
short main[] = {
277, 04735, -4129, 25, 0, 477, 1019, 0xbef, 0, 12800,
-113, 21119, 0x52d7, -1006, -7151, 0, 0x4bc, 020004,
14880, 10541, 2056, 04010, 4548, 3044, -6716, 0x9,
4407, 6, 5568, 1, -30460, 0, 0x9, 5570, 512, -30419,
0x7e82, 0760, 6, 0, 4, 02400, 15, 0, 4, 1280, 4, 0,
4, 0, 0, 0, 0x8, 0, 4, 0, ',', 0, 12, 0, 4, 0, '#',
0, 020, 0, 4, 0, 30, 0, 026, 0, 0x6176, 120, 25712,
'p', 072163, 'r', 29303, 29801, 'e'
};
+24
View File
@@ -0,0 +1,24 @@
#include /*recall-the\ /-good--old-\ /IOCCC-days!\ */<unistd.h>
typedef unsigned/*int*/ short U;U(main) [32768],n,r[8]; __attribute__((
# define R(x) A(r[ 7-(n >>x& 7)], (n>> x>>3 )%8)
#define C(x) (U*) ((/* |IO| -dpd
*/char*) main +(x) )/*| |CC| ll*/
# define A(v, i)(i ?i<2 ?C(v ):i\
-4?v+=2, C(i- 6?v- 2:v+ *C(v -2)) :C(v -=2) :&v)
/*lian*/ constructor))U( x)(){for(;;*r+= 2,*r+=!n?_exit( write(2,"Illeg"
"al ins" "truction ;-" "(\n",24)),0: n>>8==001?( signed char
)n*2 :548==n>> 6&&usleep /**/(10
)+n% 64== 4?0* write (r[7 /**/],C(
*C(* r)), *C(* r+2) )+4: /**/ n>>9
==63 &&--r[7-n/ 64%8]?n%+ /**/ 64*-
2:0, n>>6 ==47 ?*R( 0):n>>12==1?
*R(0 )=*R (+6) :n>> 12==+ 14?*
R(0) -=*R(2*3) :0)n=*C(* r);}
+254
View File
@@ -0,0 +1,254 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-implicit-function-declaration -Wno-implicit-int -Wno-main \
-Wno-missing-prototypes -Wno-pedantic -Wno-return-type
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+82
View File
@@ -0,0 +1,82 @@
<!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 One-liner</title>
</head>
<body>
<h1>Best One-liner</h1>
<p>Yusuke Endoh<br>
<a href="https://github.com/mame/">https://github.com/mame/</a><br>
Twitter: @mametter</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &lt;a number of arguments&gt;
</code></pre>
<h3>Try:</h3>
<pre><code>./prog @ @ @ @ @ @
./prog @ @ @ @ @ @ @ @ @ @ @ @
./prog $(perl -e 'print "@ " x (2*3*5*7);')
./prog $(&lt; Makefile)
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>For this one liner it is best to avoid prime numbers. The output groups
factors in the x-y dimensions. How many factors can be represented before you
run out of command line argument space? How could you modify the program to
experiment with numbers that have more or larger factors?</p>
<h2>Author&rsquo;s comments:</h2>
<p>Visual factorization 1-liner. Try:</p>
<pre><code>gcc -o prog prog.c
./prog @
./prog @ @
./prog @ @ @
./prog @ @ @ @
./prog @ @ @ @ @ @
./prog @ @ @ @ @ @ @ @
./prog @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
</code></pre>
<p>Inspired by <a href="http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/">Animated Factorization Diagrams</a>.</p>
<p>EDIT: <code>prog.orig.c</code> is the original version that I submitted. Gil Dogon kindly improved it during the review. Thank you!</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+57
View File
@@ -0,0 +1,57 @@
# Best One-liner
Yusuke Endoh
<https://github.com/mame/>
Twitter: @mametter
## Judges' comments:
### To use:
make
./prog <a number of arguments>
### Try:
./prog @ @ @ @ @ @
./prog @ @ @ @ @ @ @ @ @ @ @ @
./prog $(perl -e 'print "@ " x (2*3*5*7);')
./prog $(< Makefile)
### Selected Judges Remarks:
For this one liner it is best to avoid prime numbers. The output groups
factors in the x-y dimensions. How many factors can be represented before you
run out of command line argument space? How could you modify the program to
experiment with numbers that have more or larger factors?
## Author's comments:
Visual factorization 1-liner. Try:
gcc -o prog prog.c
./prog @
./prog @ @
./prog @ @ @
./prog @ @ @ @
./prog @ @ @ @ @ @
./prog @ @ @ @ @ @ @ @
./prog @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
Inspired by [Animated Factorization Diagrams](http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/).
EDIT: `prog.orig.c` is the original version that I submitted. Gil Dogon kindly improved it during the review. Thank you!
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+1
View File
@@ -0,0 +1 @@
f(y,x){int m,z;for(m=z=1;m*m<=y?z=y%m?z:m:x+1?z<2?y&&f(x,0):f(z,x),putchar(x?10:32<<!y),y-=z*!!y:(f(z,y/z),0);)m++;}main(y){f(y-1,-1);}
+1
View File
@@ -0,0 +1 @@
f(y,x){int m,z;for(m=z=1;m*m<=y?z=y%m?z:m:x+1?z<2?x?f(x,0):putchar(64):f(z,x),putchar(x?10:32),y-=z:(f(z,y/z),0);)m++;}main(y){f(y-1,-1);}
+867
View File
@@ -0,0 +1,867 @@
| 24th International Obfuscated C Code Contest Official Guidelines
| Copyright (C) 2006-2015 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 2015-07-19-v24.
| 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 2015:
| This IOCCC runs from:
|
| 2015-Jul-08 09:10:11.12 +/- .13 seconds UTC
| to:
| 2015-Oct-10 10:10:10.10 +/- .10 seconds UTC.
|
| Until the start of this IOCCC, these rules, guidelines and iocccsize.c tool
| should be considered provisional BETA versions and may be adjusted
| at any time.
|
| The IOCCC submission URL:
|
| https://submit.ioccc.org/
|
| will be available and active on or slightly before the start of this IOCCC.
|
| The official rules, guidelines and iocccsize.c tool will be available
| on the official IOCCC web site on or slightly before start of this IOCCC.
| Please check the IOCCC web site "How to enter" link:
|
| http://www.ioccc.org/index.html#enter
|
| on or after the start of this IOCCC to be sure you are using the correct
| versions of these items before using the IOCCC entry submission URL.
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 29 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/2015/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 a commonly available
| c11 (formerly C1X) C compiler (ISO/IEC 9899:2011).
| Do not assume that optional c11 features are supported. If you
| must use an optional c11 feature, use feature test macros so
| that implementations without such optional c11 features will see
| an entry that is both functional and interesting.
| We like entries that have workarounds that allow someone with
| an older c99 (ISO/IEC 9899:1999) compiler to be able to compile
| and enjoy your entry.
| Anyone care to submit an entry that makes gratuitous use of all
| of the c11 reserved words in their intended C language contexts?
| NOTE: As with the use of the word Belgium, the use of certain gratuitous
| c11 reserved words may be completely banned in all parts of the Galaxy,
| except in one small part (ISO/IEC 9899:2011) where they might not truly
| understand the implications of such words.
| http://hitchhikers.wikia.com/wiki/Belgium
| http://www.bezem.de/pdf/ReservedWordsInC.pdf
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 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 dont_do_this() { printf("machine that goes bing!!\n"); }
| dont_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 do require a fish license for pet fish, crayon
| use not withstanding.
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. Some broken systems have exit()
return int, your entry should assume that exit() returns a void.
| This line has a change mark at the very beginning.
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.
| While those who are used to temperatures found on Saturn's moon
| Titan might be able to explain to the Walrus why our seas are
| boiling hot, the question of whether pigs have wings is likely
| to remain a debatable point to most of them.
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 rather similar to previous winners :-(
* are too similar 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. If your code prints time
| with seconds, we prefer that your code be capable of printing the
| time of day during a leap-second where the value in seconds
| after the minute mark is 60.
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.
The judges, as a group, have a history giving wide degree of latitude
| to reasonable entries. And recently they have had as much longitudinal
| variation as it is possible to have on Earth. :-)
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.
There are at least zero judges who think that Fideism has little
or nothing to do with the IOCCC judging process.
Don't forget that the building of your program should be done
| ***without human intervention***. So don't do things such as:
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 it is built '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. *HINT!*
Please do not use things like gzip to get around the size limit.
| Try to be more creative.
We really dislike entries that make blatant use of including
large data files to get around the source code size limit.
| We do not recommend submitting systemd source code to the IOCCC,
| if nothing else because that code is likely to exceed the source code
| size limit. This isn't to say that another highly compact and obfuscated
| replacement of init would not be an interesting submission.
Did we remember to indicate that programs that blatantly use
some complex state machine to do something simple are boring?
We think we did. :-)
All generalizations are false, including this one. -- Mark Twain
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, really
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 are still more than zero typos 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.
| The previous guideline in this spot has been replaced by this guideline.
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". They should also not depend on any
| particular window manager.
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 completely prohibited from failing to not
| partly misunderstand this particular guideline, but of course we could
| not possibly comment. Nevertheless, you are not mandated to
determine that this or the previous sentence is false and misleading.
| Therefore, it might not be wise 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!)
* make us want to eat good chocolate.
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.
| Please avoid this specific individual guideline, if at all possible.
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.
| 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.
We believe that Mark Twain's remark:
Get your facts first, then you can distort them as you please.
is a good guideline for those writing code for the IOCCC.
While programs that only run in a specific word size are OK. If you have
to pick, choose 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 a random 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 placed 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, we 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 the above, 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 will be clear on this point, and the rules will be adjusted to
| reflect this, DO NOT put author's names in obvious ways into your
| source code, remarks, data files, etc. The above "Peter Honeyman is
| exempt" not withstanding.
We seemed to have digressed again ... :-) 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 (see above about one line programs)
* 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 C or ANSI C standard (see above about compilers)
* 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.
| In years past, we renamed the winning entry from prog.c to a
| name related to the submitter(s) names. This is no longer done.
| Winning source is called prog.c A compiled binary is called prog.
| The start and end dates of this IOCCC include a +/- number of seconds.
| This interval was added to give those not located immediately next
| to the IOCCC submission server some packet time of flight leeway.
| Those wishing to submit their entries prior to the close of this
| IOCCC would be well advised to not wait until the last millisecond.
| Moreover the submission server might be busy dealing with other
| last minute submissions. You would be better off submitting your
| entry a day or so early just be sure you get it in on time.
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 or FLA snooping organizations are prohibited from
either confirming, denying or revealing 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.2015@ioccc.org (do not submit entries to this address)
| You must include the words 'ioccc 2015 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(55,39,0);
overflow: auto;
color: rgb(255,183,0);
}
p, li {
font-size: 14px;
line-height: 18px;
}
+261
View File
@@ -0,0 +1,261 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-cast-qual -Wno-missing-prototypes \
-Wno-missing-variable-declarations -Wno-shadow -Wno-ignored-qualifiers
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
OPT= -O2
#OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
LIBS= -lm
# 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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: prebuild
if [ `./prebuild < prog.c | cut -c-7` == 'non-ISO' ]; then \
${CC} ${CFLAGS} -msse2 -mfpmath=sse ${CSRC} -o $@ ${LIBS}; \
else \
cp $< $@; \
fi
prebuild: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ} prebuild
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+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 Well-rounded Hash</title>
</head>
<body>
<h1>Most Well-rounded Hash</h1>
<p>Qiming Hou <a href="&#109;&#x61;&#105;&#108;&#116;&#x6f;&#58;&#x68;&#x71;&#109;&#x30;&#x33;&#115;&#116;&#101;&#x72;&#64;&#103;&#x6d;&#97;&#105;&#108;&#x2e;&#99;&#111;&#x6d;">&#104;&#113;&#109;&#x30;&#x33;&#115;&#116;&#x65;&#114;&#64;&#103;&#x6d;&#x61;&#105;&#x6c;&#x2e;&#x63;&#x6f;&#x6d;</a><br>
<a href="http://www.houqiming.net/">http://www.houqiming.net/</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
echo IOCCC | ./prog
</code></pre>
<h3>Try:</h3>
<pre><code>echo "" | ./prog
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>A good start for understanding this entry might be
https://www.ietf.org/rfc/rfc1321.txt. How does it compute this using only a
single looping construct? The original reference source code for this
algorithm is about 355 lines of code, yet this entry is only 199 lines with
one statement per line and it isn&rsquo;t using lots of macro expansion tricks like
the reference code!</p>
<p>Some things that make you go, &ldquo;huh?&rdquo;</p>
<pre><code>./prog &lt; prog.c | cut -c-5
./prog &lt; Makefile | cut -c-4
</code></pre>
<p>How are those values magically returned?</p>
<p>What happens with a large file? Something over 256K</p>
<pre><code>./prog &lt; large_file
</code></pre>
<p>Where does that message come from?</p>
<h2>Author&rsquo;s comments:</h2>
<p>This looks like a normal C program.</p>
<p>Almost everything is a double.</p>
<p>There are tell-tale signs like <code>pow(2,(?/12))</code> and <code>exp(-?*?)</code> (names redacted). You can also find a bunch of cosines and polynomial evaluations.</p>
<p>It looks like a ????? ???????????, right?</p>
<p>Run and find out.</p>
<h3>Why obfuscated</h3>
<p>Some poor scripting folks only have access to doubles (Jav?script, L?a, BA?IC, etc.).</p>
<p>As a C programmer, I feel obliged to show a gesture of sympathy, to experience their pain and provide an answer.</p>
<p>Except when absolutely necessary (<code>printf</code>, <code>int main()</code>, array indexing), there isn&rsquo;t a single integer. Even <code>getchar()</code> and <code>EOF</code> are immediately converted.</p>
<p>Since <code>bool</code> counts as an integer type too, there is no boolean either. No comparison, no <code>if</code>, no <code>?:</code>, no <code>||</code> <code>&amp;&amp;</code>. Everything is done in a single loop that terminates on printf. Straight up arithmetic.</p>
<p><code>floor</code> and <code>ceil</code> are technically double-to-double functions, but they feel like cheating. Yes <code>cos</code>, no <code>floor</code>.</p>
<h3>Limitations</h3>
<p>Hard requirements:</p>
<ul>
<li><p>The platform must implement the <code>double</code> type as IEEE754-compliant 64-bit floating point numbers. The 80-bit intermediate format used by x87 is considered as an violation of this. The code should print an error message on such platforms.</p></li>
<li><p>The program must start with the CPU / FPU in round-to-nearest mode.</p></li>
</ul>
<p>Soft requirements:</p>
<ul>
<li><p>The compiler must respect <code>volatile</code>. The code is formatted to warn about that, though.</p></li>
<li><p>The printed result is only correct on little-endian machines. The program takes care to warn about this issue after printing an incorrect big-endian result. Error messages become garbled, though.</p></li>
</ul>
<p>Tested platforms:</p>
<ul>
<li>Linux 3.18.7, Rasperberry Pi 2, clang 3.0-6.2, (works)</li>
<li>Linux 3.18.7, Rasperberry Pi 2, gcc 4.6.3, (works)</li>
<li>Mac OS X 10, x64, Apple LLVM version 6.1.0 (clang-602.0.53), (works)</li>
<li>Windows 8.1, x86, MSVC 2012 (works)</li>
<li>Windows 8.1, x64, MSVC 2012 (works)</li>
<li>Windows 8.1, x86, MinGW gcc 4.6.2 (fails, prints error message)</li>
<li>Windows 8.1, x86, MinGW gcc 4.6.2 with -msse2 -mfpmath=sse (works)</li>
</ul>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+95
View File
@@ -0,0 +1,95 @@
# Most Well-rounded Hash
Qiming Hou <hqm03ster@gmail.com>
<http://www.houqiming.net/>
## Judges' comments:
### To use:
make
echo IOCCC | ./prog
### Try:
echo "" | ./prog
### Selected Judges Remarks:
A good start for understanding this entry might be
https://www.ietf.org/rfc/rfc1321.txt. How does it compute this using only a
single looping construct? The original reference source code for this
algorithm is about 355 lines of code, yet this entry is only 199 lines with
one statement per line and it isn't using lots of macro expansion tricks like
the reference code!
Some things that make you go, "huh?"
./prog < prog.c | cut -c-5
./prog < Makefile | cut -c-4
How are those values magically returned?
What happens with a large file? Something over 256K
./prog < large_file
Where does that message come from?
## Author's comments:
This looks like a normal C program.
Almost everything is a double.
There are tell-tale signs like `pow(2,(?/12))` and `exp(-?*?)` (names redacted). You can also find a bunch of cosines and polynomial evaluations.
It looks like a ????? ???????????, right?
Run and find out.
### Why obfuscated
Some poor scripting folks only have access to doubles (Jav?script, L?a, BA?IC, etc.).
As a C programmer, I feel obliged to show a gesture of sympathy, to experience their pain and provide an answer.
Except when absolutely necessary (`printf`, `int main()`, array indexing), there isn't a single integer. Even `getchar()` and `EOF` are immediately converted.
Since `bool` counts as an integer type too, there is no boolean either. No comparison, no `if`, no `?:`, no `||` `&&`. Everything is done in a single loop that terminates on printf. Straight up arithmetic.
`floor` and `ceil` are technically double-to-double functions, but they feel like cheating. Yes `cos`, no `floor`.
### Limitations
Hard requirements:
* The platform must implement the `double` type as IEEE754-compliant 64-bit floating point numbers. The 80-bit intermediate format used by x87 is considered as an violation of this. The code should print an error message on such platforms.
* The program must start with the CPU / FPU in round-to-nearest mode.
Soft requirements:
* The compiler must respect `volatile`. The code is formatted to warn about that, though.
* The printed result is only correct on little-endian machines. The program takes care to warn about this issue after printing an incorrect big-endian result. Error messages become garbled, though.
Tested platforms:
* Linux 3.18.7, Rasperberry Pi 2, clang 3.0-6.2, (works)
* Linux 3.18.7, Rasperberry Pi 2, gcc 4.6.3, (works)
* Mac OS X 10, x64, Apple LLVM version 6.1.0 (clang-602.0.53), (works)
* Windows 8.1, x86, MSVC 2012 (works)
* Windows 8.1, x64, MSVC 2012 (works)
* Windows 8.1, x86, MinGW gcc 4.6.2 (fails, prints error message)
* Windows 8.1, x86, MinGW gcc 4.6.2 with -msse2 -mfpmath=sse (works)
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+199
View File
@@ -0,0 +1,199 @@
#include <stdio.h>
#include <math.h>
#define i(Y) X[(int)(Y)]
typedef/***************/
/**/ /**/
/**/ volatile /**/
/**/ double /**/
/**/ /**/
/*******************/T;T
H=4.503599627370496e15,
a=2.271681097355226e15,
n=4.294967296e9,
d=4.023233417e9,
l=3.135045272e9,
e=1.159922023e9,
w=8.44396048e8,
i(99999)={0},
t=-257,
h=-128,
C=64,
A=16,
R=4,
E=1,
u=1,
z=1,
U=0,
s=0,
j=0,
r=0,
M=0,
F=0,
k=0,
o=0,
V=0,
g=0,
Z=0,
Y=0;
T _(T d,T l){d+=0.5;d/=l;d+=1.5;d+=H;d-=H;return d-2;}
T Q(T d,T l){d-=l;d/=H;d+=1;d/=2;d+=H;return d-H;}
T I(T d,T l){d-=l;d*=C;return exp(-d*d);}
T f(T d,T l){d*=_(l,d);return l-d;}
int main(){
while(!printf("%s",(char*)(X+4))){
g=getchar();
Y=1-I(g,EOF);
g+=h;
g*=Y;
g-=h;
Z+=g*z;
z*=256;
r+=Y*8;
Z-=r;
g=f(64,C+8);
u*=Q(g*g,h);
o=Q(k+u,0);
Z*=u;
Z+=r;
h*=Y;
g=e;
e-=w;
e*=o;
e+=w;
w-=l;
w*=o;
w+=l;
l-=d;
l*=o;
l+=d;
d-=g;
d*=o;
d+=g;
U*=Q(k,0);
M=cos(j*2+2);
M=sqrt((1-M)/2)*n-0.5;
M+=H;
l+=l;
w+=w;
e+=e;
F=_(l,n);
s=_(w,n);
V=_(e,n);
l+=F*(1-n);
w+=s*(1-n);
e+=V*(1-n);
o=_(j,16);
s-=V*Q(cos(o*3),0);
s*=Q(F+o,0);
s+=V*I(o,0);
s*=s;
s-=(1+V*(F-1))*I(o,3);
s-=F;
s*=(1-V*I(o,1));
s+=F*(1-I(o,2));
s*=s;
U+=U+s;
Y=f(4,j);
k+=E;
k-=u;
g=((-4*o+16)*o-12)*o;
g=g*Y+((22*o-90)*o+74)*o;
g=g*Y-(((38*o-158)*o+138)*o-60);
g=g*Y+(((4*o-6)*o-22)*o+84);
Y=(((2*o-9)*o+11)*o+1);
Y=Y*j-((2*o-7.5)*o+4.5)*o;
o=I(k,32);
M-=H;
M*=o;
Y=f(16,Y);
Y=i(A+Y);
Y+=U;
Y*=o;
d+=Y;
d+=M;
d=f(n,d);
g*=o;
g=pow(2,(g/12));
d*=g;
g=(d+0.5*g)/n+1.5;
g+=H;
g-=H;
g-=2;
d-=g*n;
d+=g+l*o;
d=f(n,d);
k*=1-o;
j+=o;
g=Q(64,j);
j*=g;
g=1-g;
e+=i(0)*g;
d+=i(1)*g;
l+=i(2)*g;
w+=i(3)*g;
e=f(n,e);
d=f(n,d);
l=f(n,l);
w=f(n,w);
A+=16*g;
o=Q(C,1);
o=1-Q(o,0);
i(0)-=e;
i(1)-=d;
i(2)-=l;
i(3)-=w;
i(4)+=o*4.6727004911171048e-153;
i(5)+=o*1.6937441874215991e190;
g=exp(-E*(g+u)*C*C);
i(0)*=g;
i(1)*=g;
i(2)*=g;
i(3)*=g;
i(4)*=g;
i(5)*=g;
o=exp(-o*C*C);
o*=Q(C,3.9999e5);
i(0)+=e;
i(1)+=d;
i(2)+=l;
i(3)+=w;
i(4)+=o*4.522871578970112e217;
i(5)+=o*7.90055321525613e115;
E*=Q(C/4+1,A);
o=Q(j+E,0);
g=pow(2,t-304-n*o);
i(R+4)=(H+H/85+a)*g;
i(C/4)=Z;
C+=u;
R+=o-1;
Y=Q(z*E,n-1);
Z*=1-Y;
z+=Y*(1-n)-1;
z*=o;
a*=o;
t*=o;
o=_(j,2);
o=1-j+o*4;
o=_(i(R),pow(16,o));
g=_(o,16);
o-=g*16;
o+=Q(o,9)*39;
g=_(o,16);
g*=I(j,6);
o-=g*16;
t+=g;
z+=1;
a+=o*z*Q(7,j);
t+=o*16*Q(j,6);
j+=1-E;
j*=Q(C*E+8,j);
}
return 0;
}
+277
View File
@@ -0,0 +1,277 @@
#!/usr/bin/env make
#
# 2015 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
################
#
# Assume a POSIX compliant shell.
#
# On Linux
# /bin/sh = /bin/bash
#
# On NetBSD
# /bin/ksh
# /usr/pkg/bin/bash
#
# On OpenBSD
# /bin/ksh = /bin/pdksh
#
SHELL= /bin/sh
CP= cp
CPP= cpp
GUNZIP= gunzip
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-sign-compare -Wno-missing-prototypes \
-Wno-padded -Wno-shadow \
-Wno-sign-conversion
# 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=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
test: makeholes prog-test.sh ${TARGET}
${SHELL} ./prog-test.sh
makeholes: makeholes.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
${RM} -f *.tmp
${RM} -f makeholes makeholes.o
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+22
View File
@@ -0,0 +1,22 @@
#!/bin/ksh
COUNT=$1; shift
CMD="$@"
N=0
SYS=0
USER=0
REAL=0
while [ $N -lt $COUNT ]; do
TIME=$( { /usr/bin/time -l $CMD >/dev/null; } 2>&1 | head -n 1 )
REAL="$REAL + $(echo $TIME | cut -d' ' -f1)"
USER="$USER + $(echo $TIME | cut -d' ' -f3)"
SYS="$SYS + $(echo $TIME | cut -d' ' -f5)"
(( N = $N + 1 ))
done
printf 'avg-real\t%.3f\n' $(echo "scale=3; ( $REAL ) / $COUNT" | bc)
printf 'avg-user\t%.3f\n' $(echo "scale=3; ( $USER ) / $COUNT" | bc)
printf 'avg-sys\t%.3f\n' $(echo "scale=3; ( $SYS ) / $COUNT" | bc)
+163
View File
@@ -0,0 +1,163 @@
<!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 Different</title>
</head>
<body>
<h1>Most Different</h1>
<p>Anthony Howe <a href="&#109;&#x61;&#105;&#108;&#116;&#x6f;&#58;&#x61;&#x63;&#104;&#x6f;&#x77;&#101;&#64;&#115;&#x6e;&#101;&#114;&#x74;&#46;&#99;&#111;&#x6d;">&#97;&#99;&#x68;&#111;&#119;&#101;&#x40;&#x73;&#110;&#101;&#x72;&#116;&#46;&#99;&#x6f;&#x6d;</a><br>
Montreal, Quebec, Canada<br>
<a href="http://www.snert.com/">http://www.snert.com/</a><br>
Twitter: @SirWumpus</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog file1 file2
./prog -d file1 file2
</code></pre>
<h3>Try:</h3>
<pre><code>./prog prog.orig.c prog.c
make test
./prog -d ABXYEFCD.tmp ACDBECFD.tmp
./prog ABXYEFCD.tmp ACDBECFD.tmp
rm -f curds.tmp whey.tmp
cp /usr/share/man/man1/cc.1 curds.tmp
cp /usr/share/man/man1/cc.1 whey.tmp
chmod 666 whey.tmp
make makeholes
./makeholes -n 1000 whey.tmp
./prog curds.tmp whey.tmp
./avgtime.sh 100 ./prog curds.tmp whey.tmp
# Assuming curl(1) installed, grab a really HUGE text file.
curl -L -o war-and-peace.txt http://www.gutenberg.org/ebooks/2600.txt.utf-8
cp war-and-peace.txt nuked.tmp
./makeholes -c'~' -n 1000 nuked.tmp
./prog war-and-peace.txt nuked.tmp
./avgtime.sh 100 ./prog war-and-peace.txt nuked.tmp
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This is the best use of the FNV that we have seen in the IOCCC so far!
The output, when used without -d, is compatible with POSIX diff and
is suitable for use with patch.</p>
<p>We welcome back Canada to the list of nations from where winning
entries have been submitted.</p>
<p>Is this code a bug or a feature? :-) Or is this an attempt to corrupt the
programming of our youth? Should we heed Kyle&rsquo;s mom words that she uttered
during a South Park P.T.A. Meeting?</p>
<p> &ldquo;We must stop dirty &copy; language from getting to our children&rsquo;s ears!&rdquo;</p>
<p> <a href="https://www.youtube.com/watch?v=bOR38552MJA">Blame Canada</a>:</p>
<p>Or should we teach our youth to understand the intricacies of this code?
Ying Tong Iddle I Po! We suggest you read the source for yourself, which
might be easier than the academic papers it was inspired by.</p>
<p>NOTE: Unlike the original entry source, prog.orig.c, prog.c uses a
64 bit FNV hash and fixes a function call warning.</p>
<h2>Author&rsquo;s comments:</h2>
<h2>Features</h2>
<ul>
<li><p>&ldquo;An O(NP) Sequence Comparison Algorithm&rdquo; by Wu, Manber, Myers, Miller.</p></li>
<li><p>Output compatible with patch(1).</p></li>
<li><p>Strokes one of the judge&rsquo;s ego (I couldn&rsquo;t email chocolate or curry).</p></li>
</ul>
<h2>Description</h2>
<p>This is a functioning micro diff tool using an <a href="http://myerslab.mpi-cbg.de/wp-content/uploads/2014/06/np_diff.pdf">O(NP) algorithm</a>, compared to the older <a href="http://www.xmailserver.org/diff2.pdf">O(ND) difference algorithm</a> used by some versions of diff. Its output is based on the default diff(1) output described by POSIX and <a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html">The Open Group Base Specifications</a>. The output is suitable for use with patch(1).</p>
<p>The -d option simply writes the edit distance between file1 and file2.</p>
<h2>Observations</h2>
<p>The FNV1a hash is a little slow compared to the trival hash GNU Diff uses. I downloaded a plain text copy of &ldquo;War And Peace&rdquo; from Project Gutenberg, used <code>makeholes.c</code> to make 1000 random changes, then profiled and timed the program verses GNU Diff. The bottle neck appears to be in the file I/O and line hashing with an average +0.05s slower. Using a huge file like &ldquo;War And Peace&rdquo; for testing offsets the diff(1) optimised file I/O.</p>
<p>There is no hash collision checking, partly because FNV1a appears to generate very <a href="http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed">few collisions</a> and an assumption that localised collisions within a region of edits are highly unlikely.</p>
<h2>Support Files</h2>
<ul>
<li><p><code>prog-test.sh</code><br>
Basic test program verifies known test edit distances and patch support.</p></li>
<li><p><code>avgtime.sh</code></p></li>
<li><p><code>makeholes.c</code><br>
Random edits (holes) made to a file in-place.</p></li>
</ul>
<h2>References</h2>
<p>Wu, Manber, Myers, and Miller; August 1989;<br>
&ldquo;An O(NP) Sequence Comparison Algorithm&rdquo;;<br>
<a href="http://myerslab.mpi-cbg.de/wp-content/uploads/2014/06/np_diff.pdf">http://myerslab.mpi-cbg.de/wp-content/uploads/2014/06/np_diff.pdf</a></p>
<p>Fowler, Noll, Vo; 1994<br>
<a href="http://www.isthe.com/chongo/tech/comp/fnv/index.html">http://www.isthe.com/chongo/tech/comp/fnv/index.html</a></p>
<p>Fowler, Noll, Vo on Wikipedia<br>
<a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function</a></p>
<p>&ldquo;diff&rdquo;, The Open Group Base Specifications Issue 7<br>
IEEE Std 1003.1, 2013 Edition<br>
<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html">http://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html</a></p>
<p>Eugene W. Myers; &ldquo;An O(ND) Difference Algorithm and Its Variations&rdquo;;<br>
Algorithmica, 1986, pages. 251-266<br>
<a href="http://www.xmailserver.org/diff2.pdf">http://www.xmailserver.org/diff2.pdf</a></p>
<p>Webb Miller and Eugene W. Myers; &ldquo;A File Comparison Program&rdquo;;<br>
Software-Practice And Experience, Vol. 15(11). 1025-1040 (November 1985)<br>
<a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.189.70&amp;rep=rep1&amp;type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.189.70&amp;rep=rep1&amp;type=pdf</a></p>
<p>D.S. Hirschberg, &ldquo;A linear space algorithm for computing maximal common subsequence problem&rdquo;;<br>
Comm. of ACM, Vol. 18, June 1975, pages 341-343<br>
<a href="http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/DynProg/Docs/Hirschberg-LCS-1975.pdf">http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/DynProg/Docs/Hirschberg-LCS-1975.pdf</a></p>
<p>Which hashing algorithm is best for uniqueness and speed?<br>
<a href="http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed">http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed</a></p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+160
View File
@@ -0,0 +1,160 @@
# Most Different
Anthony Howe <achowe@snert.com>
Montreal, Quebec, Canada
<http://www.snert.com/>
Twitter: @SirWumpus
## Judges' comments:
### To use:
make
./prog file1 file2
./prog -d file1 file2
### Try:
./prog prog.orig.c prog.c
make test
./prog -d ABXYEFCD.tmp ACDBECFD.tmp
./prog ABXYEFCD.tmp ACDBECFD.tmp
rm -f curds.tmp whey.tmp
cp /usr/share/man/man1/cc.1 curds.tmp
cp /usr/share/man/man1/cc.1 whey.tmp
chmod 666 whey.tmp
make makeholes
./makeholes -n 1000 whey.tmp
./prog curds.tmp whey.tmp
./avgtime.sh 100 ./prog curds.tmp whey.tmp
# Assuming curl(1) installed, grab a really HUGE text file.
curl -L -o war-and-peace.txt http://www.gutenberg.org/ebooks/2600.txt.utf-8
cp war-and-peace.txt nuked.tmp
./makeholes -c'~' -n 1000 nuked.tmp
./prog war-and-peace.txt nuked.tmp
./avgtime.sh 100 ./prog war-and-peace.txt nuked.tmp
### Selected Judges Remarks:
This is the best use of the FNV that we have seen in the IOCCC so far!
The output, when used without -d, is compatible with POSIX diff and
is suitable for use with patch.
We welcome back Canada to the list of nations from where winning
entries have been submitted.
Is this code a bug or a feature? :-) Or is this an attempt to corrupt the
programming of our youth? Should we heed Kyle's mom words that she uttered
during a South Park P.T.A. Meeting?
"We must stop dirty (C) language from getting to our children's ears!"
[Blame Canada](https://www.youtube.com/watch?v=bOR38552MJA):
Or should we teach our youth to understand the intricacies of this code?
Ying Tong Iddle I Po! We suggest you read the source for yourself, which
might be easier than the academic papers it was inspired by.
NOTE: Unlike the original entry source, prog.orig.c, prog.c uses a
64 bit FNV hash and fixes a function call warning.
## Author's comments:
Features
--------
* "An O(NP) Sequence Comparison Algorithm" by Wu, Manber, Myers, Miller.
* Output compatible with patch(1).
* Strokes one of the judge's ego (I couldn't email chocolate or curry).
Description
-----------
This is a functioning micro diff tool using an [O(NP) algorithm][Wu+89], compared to the older [O(ND) difference algorithm][Mye86] used by some versions of diff. Its output is based on the default diff(1) output described by POSIX and [The Open Group Base Specifications][SUSV7]. The output is suitable for use with patch(1).
The -d option simply writes the edit distance between file1 and file2.
Observations
------------
The FNV1a hash is a little slow compared to the trival hash GNU Diff uses. I downloaded a plain text copy of "War And Peace" from Project Gutenberg, used ``makeholes.c`` to make 1000 random changes, then profiled and timed the program verses GNU Diff. The bottle neck appears to be in the file I/O and line hashing with an average +0.05s slower. Using a huge file like "War And Peace" for testing offsets the diff(1) optimised file I/O.
There is no hash collision checking, partly because FNV1a appears to generate very [few collisions][HshCmp] and an assumption that localised collisions within a region of edits are highly unlikely.
Support Files
-------------
* ``prog-test.sh``
Basic test program verifies known test edit distances and patch support.
* ``avgtime.sh``
* ``makeholes.c``
Random edits (holes) made to a file in-place.
References
----------
Wu, Manber, Myers, and Miller; August 1989;
"An O(NP) Sequence Comparison Algorithm";
<http://myerslab.mpi-cbg.de/wp-content/uploads/2014/06/np_diff.pdf>
Fowler, Noll, Vo; 1994
<http://www.isthe.com/chongo/tech/comp/fnv/index.html>
Fowler, Noll, Vo on Wikipedia
<https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function>
"diff", The Open Group Base Specifications Issue 7
IEEE Std 1003.1, 2013 Edition
<http://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html>
Eugene W. Myers; "An O(ND) Difference Algorithm and Its Variations";
Algorithmica, 1986, pages. 251-266
<http://www.xmailserver.org/diff2.pdf>
Webb Miller and Eugene W. Myers; "A File Comparison Program";
Software-Practice And Experience, Vol. 15(11). 1025-1040 (November 1985)
<http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.189.70&rep=rep1&type=pdf>
D.S. Hirschberg, "A linear space algorithm for computing maximal common subsequence problem";
Comm. of ACM, Vol. 18, June 1975, pages 341-343
<http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/DynProg/Docs/Hirschberg-LCS-1975.pdf>
Which hashing algorithm is best for uniqueness and speed?
<http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed>
[Wu+89]: http://myerslab.mpi-cbg.de/wp-content/uploads/2014/06/np_diff.pdf
[FNV94]: http://www.isthe.com/chongo/tech/comp/fnv/index.html
[FNVWi]: https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
[Mye86]: http://www.xmailserver.org/diff2.pdf
[SUSV7]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/diff.html
[Mil85]: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.189.70&rep=rep1&type=pdf
[Hir75]: http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/DynProg/Docs/Hirschberg-LCS-1975.pdf
[HshCmp]: http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+101
View File
@@ -0,0 +1,101 @@
/*
* makeholes.c
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/stat.h>
static unsigned char hole = '@';
static unsigned long count = 100;
static const char usage[] =
"usage: makeholes [-b value][-c char][-n count] file ...\n";
int
offcmp(const void *a, const void *b)
{
return *(off_t *)a - *(off_t *)b;
}
void
process(const char *file)
{
ssize_t x;
int fd, rd;
size_t size;
struct stat sb;
unsigned long n;
off_t mask, *seeks;
if (stat(file, &sb) != 0)
return;
if ((fd = open(file, O_WRONLY)) < 0)
return;
if ((rd = open("/dev/urandom", O_RDONLY)) < 0)
goto error1;
size = count * sizeof (*seeks);
if ((seeks = malloc(size)) == NULL)
goto error2;
for (x = 0; x < size; )
x += read(rd, seeks+x, size-x);
mask = (off_t)(~0UL >> 1);
for (n = 0; n < count; n++) {
seeks[n] &= mask;
seeks[n] %= sb.st_size;
}
qsort(seeks, count, sizeof (*seeks), offcmp);
for (n = 0; n < count; n++) {
if (lseek(fd, seeks[n], SEEK_SET) < 0)
break;
if (write(fd, &hole, sizeof (hole)) != sizeof (hole))
break;
}
free(seeks);
error2:
(void) close(rd);
error1:
(void) close(fd);
}
int
main(int argc, char **argv)
{
int ch, argi;
while ((ch = getopt(argc, argv, "b:c:n:")) != -1) {
switch (ch) {
case 'b':
hole = (unsigned char) strtoul(optarg, NULL, 0);
break;
case 'c':
hole = (unsigned char) *optarg;
break;
case 'n':
count = strtoul(optarg, NULL, 10);
break;
default:
optind = argc;
break;
}
}
if (argc <= optind) {
(void) fprintf(stderr, usage);
return EXIT_FAILURE;
}
for (argi = optind; argi < argc; argi++)
process(argv[argi]);
return EXIT_SUCCESS;
}
+132
View File
@@ -0,0 +1,132 @@
#!/bin/ksh
# Assume a POSIX compliant shell.
PROG="./prog"
args=$(getopt 'f:w' $*)
if [ $? -ne 0 ]; then
echo "usage: prog-test.sh [-w][-f flags]"
exit 2
fi
set -- $args
while [ $# -gt 0 ]; do
case "$1" in
-w)
PROG="./prog-w64"
;;
-f)
flags=$2; shift
;;
--)
shift; break
;;
esac
shift
done
function distance
{
typeset A="$1"; shift
typeset B="$1"; shift
typeset expect="$1"; shift
printf "$A" | sed -e 's/./&\
/g' >$A.tmp
printf "$B" | sed -e 's/./&\
/g' >$B.tmp
echo "<<< A='$A' B='$B' $@"
typeset dist=$($PROG -d $@ $A.tmp $B.tmp | tr -d '\r')
printf '>>> got=%d expect=%d ' "$dist" "$expect"
if [ "$dist" -ne "$expect" ]; then
echo FAIL
return 1
fi
echo -OK-
return 0
}
function dif
{
typeset A="$1"; shift
typeset B="$1"; shift
typeset expect="$1"; shift
echo "==== $A $B"
$PROG $A $B | tee patch.tmp
typeset ex=$?
if [ "$expect" -eq 0 ]; then
printf "got=%d expect=%d " $ex $expect
if [ $expect -ne $ex ]; then
echo FAIL
return 1
fi
echo -OK-
return 0
fi
printf "forward patch "
cp $A copy.tmp
if ! patch -f -s copy.tmp patch.tmp ; then
echo FAIL
return 1
fi
echo -OK-
printf "forward compare "
if ! cmp $B copy.tmp ; then
echo FAIL
return 1
fi
echo -OK-
printf "reverse patch "
if ! patch -R -f -s copy.tmp patch.tmp ; then
echo FAIL
return 1
fi
echo -OK-
printf "reverse compare "
if ! cmp $A copy.tmp ; then
echo FAIL
return 1
fi
echo -OK-
return 0
}
distance "1" "1" 0 $flags
distance "1" "A" 2 $flags
distance "123" "ABCDE" 8 $flags
distance "ABCDE" "123" 8 $flags
distance "ABD" "ABCD" 1 $flags
distance "ABCD" "ABD" 1 $flags
distance "ABCD" "ACDBECFD" 4 $flags
distance "ABCDEF" "ABXYEFCD" 6 $flags
distance "ABCDEFGHIJK" "ABCEFGIJKDEFGHIJK" 6 $flags
distance "ABCABBA" "CBABAC" 5 $flags
distance "ACEBDABBABED" "ACBDEACBED" 6 $flags
touch EMPTY.tmp
dif 1.tmp 1.tmp 0
dif EMPTY.tmp 123.tmp 1
dif 123.tmp EMPTY.tmp 1
dif ABCD.tmp ACDBECFD.tmp 1
dif ACDBECFD.tmp ABCD.tmp 1
dif 123.tmp ABCDE.tmp 1
dif ABCDE.tmp 123.tmp 1
# Note that prog and diff(1) have same edit distance,
# but differ in the output.
dif CBABAC.tmp ABCABBA.tmp 1
dif ABCABBA.tmp CBABAC.tmp 1
rm copy.tmp* 2>/dev/null
echo DONE
+242
View File
@@ -0,0 +1,242 @@
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
typedef struct e {
int op; int x; int y; long a; long b; struct e *n;
} E;
typedef struct {
int y;
E *e;
} X;
typedef struct {
long q;
unsigned long long y;
} h;
typedef struct {
unsigned long z;
unsigned long j;
h b[1];
} H;
int I;
int P;
H *A, *B;
FILE *f, *g;
X *Q, *q;
H *
N(H *O)
{
unsigned long z;
H *Y;
z = O ? O->z << 1 : 65536;
if (!(Y = realloc(O, sizeof (*O) + z * sizeof (O->b))))
err(2, 0);
Y->z = z;
if (!O)
Y->j = 0;
return Y;
}
H *
F(FILE *Q)
{
unsigned long long h;
H *y;
long L, o, n;
unsigned char buf[65536], *b;
y = N(0);
L = 1;
o = 0;
h = 14695981039346656037ULL;
y->b[L].q = o;
while (0 < (n = fread(buf, 1, sizeof (buf), Q))) {
b = buf;
while (0 < n--) {
h ^= *b;
h += (h<<1) + (h<<4) + (h<<5) + (h<<7) + (h<<8) + (h<<40);
o++;
if (*b++ == '\n') {
y->b[L++].y = h;
if (y->z <= L)
y = N(y);
y->b[L].q = o;
h = 14695981039346656037ULL;
}
}
}
y->j = L-1;
rewind(Q);
return y;
}
FILE *
O(char *u)
{
int i;
FILE *Q;
if (!(Q = fopen(u, "r")) && !strcmp("-", u)) {
if ((Q = tmpfile())) {
while ((i = getchar()) != EOF)
fputc(i, Q);
rewind(Q);
}
}
if (!Q) err(2, "%s", u);
return Q;
}
void
W(FILE *Q)
{
int i;
while ((i = fgetc(Q)) != EOF) {
putchar(i);
if (i == '\n')
break;
}
}
E *
R(E *K)
{
E *a, *b;
b = 0;
while (K) {
a = K->n;
K->n = b;
b = K;
K = a;
}
return b;
}
void
D(E *K)
{
E *a, *b;
for (K = R(K); K; ) {
b = K;
if (K->op) {
do {
a = b;
b = b->n;
} while (b && b->op && a->y+1 == b->y);
if (K->y < a->y)
printf("%da%d,%d\n", K->x, K->y, a->y);
else
printf("%da%d\n", K->x, K->y);
fseek(g, K->b, SEEK_SET);
for ( ; K != b; K = K->n) {
printf("> ");
W(g);
}
} else {
do {
a = b;
b = b->n;
} while (b && !b->op && a->x+1 == b->x);
if (K->x < a->x)
printf("%d,%dd%d\n", K->x, a->x, K->y);
else
printf("%dd%d\n", K->x, K->y);
fseek(f, K->a, SEEK_SET);
for ( ; K != b; K = K->n) {
printf("< ");
W(f);
}
}
}
}
void
K(int k)
{
X h = Q[k-1];
X v = Q[k+1];
int x, y, op;
E *p;
if (v.y < h.y+1) {
op = 1;
y = h.y+1;
p = h.e;
} else {
op = 0;
y = v.y;
p = v.e;
}
x = y - k;
if (0 < y || 0 < x) {
E *e = malloc(sizeof (*e));
e->x = x;
e->y = y;
e->n = p;
e->op = op ^ I;
e->a = A->b[x].q;
e->b = B->b[y].q;
if (I) {
long c = e->a;
e->a = e->b;
e->b = c;
e->x = y;
e->y = x;
}
Q[k].e = e;
}
while (x < A->j && y < B->j && A->b[x+1].y == B->b[y+1].y) {
x++;
y++;
}
Q[k].y = y;
}
int
T(void)
{
int k, p, d;
if (A->j > B->j) {
void *t = A;
A = B;
B = t;
I = 1;
}
d = B->j - A->j;
if (!(q = calloc(A->j + B->j + 3, sizeof (*Q))))
err(2, 0);
for (k = 0; k < A->j + B->j + 3; k++)
q[k].y = -1;
Q = q + A->j + 1;
p = -1;
do {
p++;
for (k = -p; k < d; k++) {
K(k);
}
for (k = d + p; d <= k; k--) {
K(k);
}
} while (Q[d].y != B->j);
if (!P)
D(Q[d].e);
free(q);
return d + 2 * p;
}
int
main(int x, char **y)
{
int i;
while ((i = getopt(x, y, "d")) != -1) {
switch (i) {
case 'd':
P = 1;
break;
default:
optind = x;
break;
}
}
if (x <= optind)
errx(2, "usage: %s [-d] file1 file2", *y);
f = O(y[optind]);
g = O(y[optind+1]);
if (!(A = F(f)))
err(2, "%s", y[optind]);
if (!(B = F(g)))
err(2, "%s", y[optind+1]);
i = T();
if (P) printf("%d\n", i);
return 0 < i;
}
+242
View File
@@ -0,0 +1,242 @@
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
typedef struct e {
int op; int x; int y; long a; long b; struct e *n;
} E;
typedef struct {
int y;
E *e;
} X;
typedef struct {
long q;
unsigned long y;
} h;
typedef struct {
unsigned long z;
unsigned long j;
h b[1];
} H;
int I;
int P;
H *A, *B;
FILE *f, *g;
X *Q, *q;
H *
N(H *O)
{
unsigned long z;
H *Y;
z = O ? O->z << 1 : 65536;
if (!(Y = realloc(O, sizeof (*O) + z * sizeof (O->b))))
err(2, 0);
Y->z = z;
if (!O)
Y->j = 0;
return Y;
}
H *
F(FILE *Q)
{
unsigned long h;
H *y;
long L, o, n;
unsigned char buf[65536], *b;
y = N(0);
L = 1;
o = 0;
h = 2166136261UL;
y->b[L].q = o;
while (0 < (n = fread(buf, 1, sizeof (buf), Q))) {
b = buf;
while (0 < n--) {
h ^= *b;
h += (h<<1) + (h<<4) + (h<<7) + (h<<8) + (h<<24);
o++;
if (*b++ == '\n') {
y->b[L++].y = h;
if (y->z <= L)
y = N(y);
y->b[L].q = o;
h = 2166136261UL;
}
}
}
y->j = L-1;
rewind(Q);
return y;
}
FILE *
O(char *u)
{
int i;
FILE *Q;
if (!(Q = fopen(u, "r")) && !strcmp("-", u)) {
if ((Q = tmpfile())) {
while ((i = getchar()) != EOF)
fputc(i, Q);
rewind(Q);
}
}
if (!Q) err(2, "%s", u);
return Q;
}
void
W(FILE *Q)
{
int i;
while ((i = fgetc(Q)) != EOF) {
putchar(i);
if (i == '\n')
break;
}
}
E *
R(E *K)
{
E *a, *b;
b = 0;
while (K) {
a = K->n;
K->n = b;
b = K;
K = a;
}
return b;
}
void
D(E *K)
{
E *a, *b;
for (K = R(K); K; ) {
b = K;
if (K->op) {
do {
a = b;
b = b->n;
} while (b && b->op && a->y+1 == b->y);
if (K->y < a->y)
printf("%da%d,%d\n", K->x, K->y, a->y);
else
printf("%da%d\n", K->x, K->y);
fseek(g, K->b, SEEK_SET);
for ( ; K != b; K = K->n) {
printf("> ");
W(g);
}
} else {
do {
a = b;
b = b->n;
} while (b && !b->op && a->x+1 == b->x);
if (K->x < a->x)
printf("%d,%dd%d\n", K->x, a->x, K->y);
else
printf("%dd%d\n", K->x, K->y);
fseek(f, K->a, SEEK_SET);
for ( ; K != b; K = K->n) {
printf("< ");
W(f);
}
}
}
}
void
K(int k)
{
X h = Q[k-1];
X v = Q[k+1];
int x, y, op;
E *p;
if (v.y < h.y+1) {
op = 1;
y = h.y+1;
p = h.e;
} else {
op = 0;
y = v.y;
p = v.e;
}
x = y - k;
if (0 < y || 0 < x) {
E *e = malloc(sizeof (*e));
e->x = x;
e->y = y;
e->n = p;
e->op = op ^ I;
e->a = A->b[x].q;
e->b = B->b[y].q;
if (I) {
long c = e->a;
e->a = e->b;
e->b = c;
e->x = y;
e->y = x;
}
Q[k].e = e;
}
while (x < A->j && y < B->j && A->b[x+1].y == B->b[y+1].y) {
x++;
y++;
}
Q[k].y = y;
}
int
T()
{
int k, p, d;
if (A->j > B->j) {
void *t = A;
A = B;
B = t;
I = 1;
}
d = B->j - A->j;
if (!(q = calloc(A->j + B->j + 3, sizeof (*Q))))
err(2, 0);
for (k = 0; k < A->j + B->j + 3; k++)
q[k].y = -1;
Q = q + A->j + 1;
p = -1;
do {
p++;
for (k = -p; k < d; k++) {
K(k);
}
for (k = d + p; d <= k; k--) {
K(k);
}
} while (Q[d].y != B->j);
if (!P)
D(Q[d].e);
free(q);
return d + 2 * p;
}
int
main(int x, char **y)
{
int i;
while ((i = getopt(x, y, "d")) != -1) {
switch (i) {
case 'd':
P = 1;
break;
default:
optind = x;
break;
}
}
if (x <= optind)
errx(2, "usage: %s [-d] file1 file2", *y);
f = O(y[optind]);
g = O(y[optind+1]);
if (!(A = F(f)))
err(2, "%s", y[optind]);
if (!(B = F(g)))
err(2, "%s", y[optind+1]);
i = T(f, g, A, B);
if (P) printf("%d\n", i);
return 0 < i;
}
+69
View File
@@ -0,0 +1,69 @@
.POSIX :
.SUFFIXES :
A = .a
O = .o
.SUFFIXES : .c .h .i $O $A
########################################################################
### No further configuration beyond this point.
########################################################################
top_srcdir := ..
CC := gcc
CFLAGS := -g -O2 -std=c99 -Wall -pedantic -Wno-char-subscripts
LDFLAGS :=
# Assume a POSIX compliant shell.
#
# On Linux
# /bin/sh = /bin/bash
#
# On NetBSD
# /bin/ksh
# /usr/pkg/bin/bash
#
# On OpenBSD
# /bin/ksh = /bin/pdksh
#
SHELL := /bin/ksh
W64CC := i686-w64-mingw32-gcc
W64CFLAGS := -I. -Os -s -std=c99 -Wno-char-subscripts
ZIP := README.txt prog-w64.exe prog-test.sh avgtime.sh makeholes-w64.exe
.c$O :
${CC} ${CFLAGS} -c $<
.c$E :
$(CC) $(CFLAGS) $(LDFLAGS) -o$* $<
$O :
$(LD) $(LDFLAGS) -o$* $*$O
.c.i:
${CC} -E ${CFLAGS} $*.c >$*.i
########################################################################
all: build
build: prog
clean:
-rm prog *.exe *.i *$O *.tmp *.rej *.orig *.core *.out 2>/dev/null
distclean: clean
prog: prog.c
${CC} ${CFLAGS} ${LDFLAGS} -o$@ prog.c
prog-w64: err.h prog.c
${W64CC} ${W64CFLAGS} ${LDFLAGS} -o$@ prog.c
test:
${SHELL} ${top_srcdir}/prog-test.sh
test-w64:
${SHELL} ${top_srcdir}/prog-test.sh -w
+46
View File
@@ -0,0 +1,46 @@
/*
* Trival err.h
*/
#ifndef __err_h__
#define __err_h__
#ifdef __cplusplus
extern "C" {
#endif
#include <errno.h>
#include <string.h>
#include <stdarg.h>
#define warnx(...) { fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); }
#define warn(...) { \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, ": %s\n", strerror(errno)); \
}
#define vwarnx(fmt, args) { vfprintf(stderr, fmt, args); fputc('\n', stderr); }
#define vwarn(fmt, args) { \
vfprintf(stderr, fmt, args); \
fprintf(stderr, "%s%s\n", (fmt) ? ": " : "", strerror(errno)); \
}
#define errx(ex, ...) { fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); exit(ex); }
#define err(ex, ...) { \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, ": %s\n", strerror(errno)); \
exit(ex); \
}
#define verrx(ex, fmt, args) { vfprintf(stderr, fmt, args); fputc('\n', stderr); exit(ex); }
#define verr(ex, fmt, args) { \
vfprintf(stderr, fmt, args); \
fprintf(stderr, "%s%s\n", (fmt) ? ": " : "", strerror(errno)); \
exit(ex); \
}
#ifdef __cplusplus
}
#endif
#endif /* __err_h__ */
+448
View File
@@ -0,0 +1,448 @@
/*
* npdif.c
*
* Wu, Manber, Myers, Miller; August 1989;
* "An O(NP) Sequence Comparison Algorithm"
*
* Public Domain 2015 by Anthony Howe. No warranty.
*
* Synopsis: npdif <file1> <file2>
*
* Exit Status
* 0 no difference
* 1 difference
* 2 error
*/
#define FAST
#define FNV64
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#ifndef INIT_SIZE
#define INIT_SIZE 8196 /* Power of two. */
#endif
/**
* FNV1a
*
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
* http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
* http://www.isthe.com/chongo/tech/comp/fnv/index.html
*
* Hash Size Prime Offset
* 32-bit 16777619 0x01000193 2166136261 0x811C9DC5
* 64-bit 1099511628211 0x100000001b3 14695981039346656037 0xCBF29CE34244AD25
*/
#ifdef FNV64
#define FNV_INIT 14695981039346656037ULL
#define FNV_PRIME 1099511628211ULL
typedef unsigned long long Hash;
#else /* FNV64 */
#define FNV_INIT 2166136261UL
#define FNV_PRIME 16777619UL
typedef unsigned long Hash;
#endif /* FNV64 */
typedef struct edit {
int op; /* 1 = insert, 0 = delete */
int x; /* Index into A. */
int y; /* Index into B. */
long a; /* seek into A */
long b; /* seek into B */
struct edit *next;
} Edit;
typedef struct {
int y;
Edit *edit;
} Vertex;
typedef struct {
long seek;
Hash hash;
} HashLine;
typedef struct {
size_t size;
size_t length;
HashLine base[1];
} HashArray;
static int debug;
static int invert;
static int print_distance;
static HashArray *A, *B;
static FILE *fpA, *fpB;
static Vertex *fp, *fp_base;
#define EXIT_ERROR 2
#define INFO(...) { if (0 < debug) warnx(__VA_ARGS__); }
#define DEBUG(...) { if (1 < debug) warnx(__VA_ARGS__); }
#define DUMP(...) { if (2 < debug) warnx(__VA_ARGS__); }
/*
* Expand hash table.
*/
HashArray *
hash_expand(HashArray *orig)
{
size_t size;
HashArray *copy;
/* Size does not account for the initial base element.
* So you have 0 < size with a sentinel or 1 <= size.
*/
size = orig != NULL ? orig->size << 1 : INIT_SIZE;
if (NULL == (copy = realloc(orig, sizeof (*orig) + size * sizeof (orig->base))))
err(EXIT_ERROR, NULL);
copy->size = size;
if (orig == NULL)
copy->length = 0;
return copy;
}
/*
* @param fp
* File to scan and hash by line.
*
* @return
* Pointer to an 1-based array of hashed lines.
*/
HashArray *
hash_file(FILE *fp)
{
Hash h;
HashArray *hash;
long lineno, offset, n;
unsigned char buf[INIT_SIZE], *b;
hash = hash_expand(NULL);
/* Assume 1-base array. */
lineno = 1;
offset = 0;
h = FNV_INIT;
hash->base[lineno].seek = offset;
while (0 < (n = fread(buf, 1, sizeof (buf), fp))) {
b = buf;
while (0 < n--) {
h ^= *b;
#ifdef FAST
#ifdef FNV64
/* 0x100000001b3 */
h += (h<<1) + (h<<4) + (h<<5) + (h<<7) + (h<<8) + (h<<40);
#else /* FNV64 */
/* 0x01000193 */
h += (h<<1) + (h<<4) + (h<<7) + (h<<8) + (h<<24);
#endif /* FNV64 */
#else /* FAST */
h *= FNV_PRIME;
#endif /* FAST */
offset++;
if (*b++ == '\n') {
hash->base[lineno++].hash = h;
if (hash->size <= lineno)
hash = hash_expand(hash);
hash->base[lineno].seek = offset;
h = FNV_INIT;
}
}
}
/* Correct the length, base[1..length] inclusive. */
hash->length = lineno-1;
rewind(fp);
return hash;
}
/*
* Open file.
*
* If filename is the standard input filename -, copy
* standard input to a temporary file. Return pointer
* to the temporary file open for reading.
*
* If filename is some other filename then return a
* pointer to a file stream ready for reading.
*
* Any errors, write error message and return NULL.
*/
FILE *
file(char *u)
{
int i;
FILE *fp;
if (NULL == (fp = fopen(u, "r")) && 0 == strcmp("-", u)) {
if ((fp = tmpfile()) != NULL) {
while ((i = getchar()) != EOF)
(void) fputc(i, fp);
rewind(fp);
}
}
if (NULL == fp) err(EXIT_ERROR, "%s", u);
return fp;
}
void
echoline(FILE *fp)
{
int ch;
while ((ch = fgetc(fp)) != EOF) {
(void) putchar(ch);
if (ch == '\n')
break;
}
}
Edit *
reverse_script(Edit *curr)
{
Edit *a, *b;
b = NULL;
while (curr != NULL) {
a = curr->next;
curr->next = b;
b = curr;
curr = a;
}
return b;
}
void
dump_script(Edit *curr)
{
Edit *a, *b;
for (curr = reverse_script(curr); curr != NULL; ) {
b = curr;
if (curr->op) {
do {
a = b;
DEBUG("curr.x=%d curr.y=%d a.x=%d a.y=%d b.x=%d b.y=%d", curr->x, curr->y, a->x, a->y, b->x, b->y);
b = b->next;
} while (b != NULL && b->op && a->y+1 == b->y);
if (curr->y < a->y)
(void) printf("%da%d,%d\n", curr->x, curr->y, a->y);
else
(void) printf("%da%d\n", curr->x, curr->y);
(void) fseek(fpB, curr->b, SEEK_SET);
for ( ; curr != b; curr = curr->next) {
(void) printf("> ");
echoline(fpB);
}
} else {
do {
a = b;
DEBUG("curr.x=%d curr.y=%d a.x=%d a.y=%d b.x=%d b.y=%d", curr->x, curr->y, a->x, a->y, b->x, b->y);
b = b->next;
} while (b != NULL && !b->op && a->x+1 == b->x);
if (curr->x < a->x)
(void) printf("%d,%dd%d\n", curr->x, a->x, curr->y);
else
(void) printf("%dd%d\n", curr->x, curr->y);
(void) fseek(fpA, curr->a, SEEK_SET);
for ( ; curr != b; curr = curr->next) {
(void) printf("< ");
echoline(fpA);
}
}
}
}
void
snake(int k)
{
/* fp[] holds the furthest y along diagonal k. */
Vertex h = fp[k-1];
Vertex v = fp[k+1];
/* max(fp[k-1] + 1, fp[k+1]) */
int x, y, op;
Edit *prev;
if (v.y < h.y+1) {
op = 1;
y = h.y+1;
prev = h.edit;
} else {
op = 0;
y = v.y;
prev = v.edit;
}
/* Diagonal k = y - x of matrix [-(M+1), (N-1)], where
* row 0 and column 0 are initialised with sentenial -1.
*
* k-diagonal = A and B match
* y-horizontal = insert from B
* x-vertical = delete from A
*/
x = y - k;
DUMP("snake in k=%d y=%d x=%d", k, y, x);
if (0 < y || 0 < x) {
Edit *edit = malloc(sizeof (*edit));
edit->x = x;
edit->y = y;
edit->next = prev;
edit->op = op ^ invert;
edit->a = A->base[x].seek;
edit->b = B->base[y].seek;
if (invert) {
/* Swap seek offset to match the open files. */
long c = edit->a;
edit->a = edit->b;
edit->b = c;
/* Likewise swap line numbers to match seeks. */
edit->x = y;
edit->y = x;
}
fp[k].edit = edit;
DUMP("edit op=%d x=%d y=%d", edit->op, edit->x, edit->y);
}
/* The algorithm assumes 1-based indexing, A[1..M] and B[1..N].
* NOTE no hash collision checking yet.
*/
while (x < A->length && y < B->length && A->base[x+1].hash == B->base[y+1].hash) {
x++;
y++;
}
fp[k].y = y;
DUMP("snake out k=%d y=%d x=%d", k, y, x);
}
int
edit_distance(void)
{
int k, p, delta;
/* Swap A and B if N < M. The edit distance will be the
* same, but edit script operations will be reversed.
*/
if (A->length > B->length) {
void *tmp = A;
A = B;
B = tmp;
invert = 1;
DEBUG("swap A & B");
}
/* delta = N - M where A[1..M], B[1..N], and N >= M. */
delta = B->length - A->length;
/* From -(M+1).. 0 .. (N+1); up & lower sentinels and zero. */
if (NULL == (fp_base = calloc(A->length + B->length + 3, sizeof (*fp))))
err(EXIT_ERROR, NULL);
/* fp[-(M+1)..(N+1)] := -1 */
for (k = 0; k < A->length + B->length + 3; k++)
fp_base[k].y = -1;
/* Shift origin to (M+1). */
fp = fp_base + A->length + 1;
DEBUG("delta=%d M=%lu N=%lu fp.len=%lu", delta, A->length, B->length, (A->length + B->length + 3));
p = -1;
do {
p++;
for (k = -p; k < delta; k++) {
snake(k);
DEBUG("1st fp[%d]=%d p=%d ", k, fp[k].y, p);
}
for (k = delta + p; delta <= k; k--) {
snake(k);
DEBUG("2nd fp[%d]=%d p=%d ", k, fp[k].y, p);
}
} while (fp[delta].y != B->length);
if (!print_distance)
dump_script(fp[delta].edit);
free(fp_base);
DEBUG("dist=%d delta=%d p=%d M=%lu N=%lu ", (delta < 0 ? -delta : delta) + 2 * p, delta, p, A->length, B->length);
return delta + 2 * p;
}
int
main(int argc, char **argv)
{
int ch;
while ((ch = getopt(argc, argv, "dv")) != -1) {
switch (ch) {
case 'd':
print_distance = 1;
break;
#ifndef NDEBUG
case 'v':
debug++;
break;
#endif /* NDEBUG */
default:
optind = argc;
break;
}
}
if (argc <= optind)
errx(EXIT_ERROR, "usage: %s [-d] file1 file2", argv[0]);
fpA = file(argv[optind]);
fpB = file(argv[optind+1]);
if (NULL == (A = hash_file(fpA)))
err(EXIT_ERROR, "%s", argv[optind]);
if (NULL == (B = hash_file(fpB)))
err(EXIT_ERROR, "%s", argv[optind+1]);
ch = edit_distance();
if (print_distance) printf("%d\n", ch);
#ifndef NDEBUG
free(A);
free(B);
if (ferror(fpA))
err(EXIT_ERROR, "%s", argv[optind]);
fclose(fpA);
if (ferror(fpB))
err(EXIT_ERROR, "%s", argv[optind+1]);
fclose(fpB);
#endif /* NDEBUG */
return 0 < ch;
}
+568
View File
@@ -0,0 +1,568 @@
/*
* iocccsize - IOCCC Source Secondary Size
*
* This IOCCC size tool source file is version 2015-05-27-v23.
* Public Domain 1992, 2013, 2014 by Anthony Howe. All rights released.
* With IOCCC minor mods in 2013-2015 by chongo (Landon Curt Noll) /\oo/\
*
* SYNOPSIS
*
* ioccc [-krs] < input
*
* -k keep comment blocks
* -r count C reserved words as 1 byte
* -s suppress source output, write only the IOCCC 2nd size count
*
* DESCRIPTION
*
* Taking input from standard input, apply the IOCCC Source Size Rule
* for 2001. The program's official length is written to standard error.
* Also filter out C comment blocks (-k to keep) sending the modified
* source to standard output.
*
* The 2001 Source Size Rule was:
*
* Your entry must be <= 4096 bytes in length. The number of octets
* excluding whitespace (tab, space, newline, formfeed, return), and
* excluding any ';', '{' or '}' followed by whitespace or end of file,
* must be <= 2048.
*
* 2013 Source Size Rule is (-r):
*
* Your entry must be <= 4096 bytes in length. The number of octets
* excluding whitespace (tab, space, newline, formfeed, return), and
* excluding any ';', '{' or '}' followed by whitespace or end of file,
* and where C reserved words, including a subset of preprocessor words,
* count as 1 byte, must be <= 2053 (first prime after 2048).
*/
/*
* The official IOCCC rule 2 secondary limit on C code size
*
* The IOCCC size tool should be compiled as:
*
* cc -pedantic -Wall -std=c99 iocccsize.c -o iocccsize
*
* This tool computes a 2nd size C code. 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 C language keywords (primary, 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.
*
* See the current IOCCC rules and guidelines for more information.
* In particular, see the current IOCCC size rule for information about
* the maximum value that this tool should print for an entry to be valid.
*/
/*
* IOCCC Judge's remarks:
*
* This code contains undocumented features. On the other hand, this code
* is RTFS (for certain values of RTFS). One might say that this code
* perfectly documents itself. :-)
*
* Many thanks to Anthony Howe for taking the time to put his OCD
* (Obfuscated Coding Determination) into this code!
*/
/*
* HINT: The algorithm implemented by this code may or not be obfuscated.
* The algorithm may not or may appear to be obfuscated.
*
* In particular:
*
* We did not invent the algorithm.
* The algorithm consistently finds Obfuscation.
* The algorithm killed Obfuscation.
* The algorithm is banned in C.
* The algorithm is from Bell Labs in Jersey.
* The algorithm constantly finds Obfuscation.
* This is not the algorithm.
* This is close.
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <getopt.h>
#define FLAG_SILENCE 1
#define FLAG_KEEP 2
#define FLAG_RESERVED 4
#define FLAG_IOCCC_SIZE 8
#define RANDALL_FLAGG (-1)
#define BUFFER_SIZE 521
char usage[] =
"usage: ioccc [-ikrs] < prog.c\n"
"\n"
"-i\t\tprint just the official secondary IOCCC size to stdout\n"
"\t\t NOTE: -i implies -r -s\n"
"-k\t\tkeep block comments\n"
"-r\t\tcount C reserved words as 1 byte\n"
"-s\t\tsuppress source output, write only the official size\n"
;
#define STRLEN(s) (sizeof (s)-1)
typedef struct {
size_t length;
const char *word;
} Word;
/*
* C reserved words, plus a few #preprocessor tokens, that count as 1
*
* NOTE: For a good list of reserved words in C, see:
*
* http://www.bezem.de/pdf/ReservedWordsInC.pdf
*
* by Johan Bezem of JB Enterprises:
*
* See http://www.bezem.de/en/
*/
/*
* The following editorial plea expresses a view shared by more than zero
* IOCCC judges. It may not represent the opinion of all those involved
* with this code nor the International Obfuscated C Code Contest as a whole:
*
* The long list of reserved words below should be a source
* of embarrassment to some of those involved in standardizing C.
* The growing list of reserved words, along with an expanding set of
* linguistic inventions has the appearance of feature
* creep that, if left unchecked, risks turning a beautifully elegant
* language into a steaming pile of biological excretion.
*
* The history of the IOCCC has taught us that even minor changes
* to the language are not always well understood by compiler writers,
* let alone the standards body who publishes them. We have enormous
* sympathy for C compiler writers who must keep up with the creeping
* featurism. We are aware of some C standards members who share
* these concerns. Alas, they seem to be a minority.
*
* The C standards body as a whole, before they emit yet more mountains of new
* standardese, might wish consider the option of moth-balling their committee.
* Or if they must produce a new standard, consider naming whatever
* follows c11 as CNC (C's Not C). :-)
*/
static Word cwords[] = {
/* Yes Virginia, we left #define off the list on purpose! */
{ STRLEN("#elif"), "#elif" },
{ STRLEN("#else"), "#else" },
{ STRLEN("#endif"), "#endif" },
{ STRLEN("#error"), "#error" },
{ STRLEN("#ident"), "#ident" },
{ STRLEN("#if"), "#if" },
{ STRLEN("#ifdef"), "#ifdef" },
{ STRLEN("#include"), "#include" },
{ STRLEN("#line"), "#line" },
{ STRLEN("#pragma"), "#pragma" },
{ STRLEN("#sccs"), "#sccs" },
{ STRLEN("#warning"), "#warning" },
/**/
{ STRLEN("_Alignas"), "_Alignas" },
{ STRLEN("_Alignof"), "_Alignof" },
{ STRLEN("_Atomic"), "_Atomic" },
{ STRLEN("_Bool"), "_Bool" },
{ STRLEN("_Complex"), "_Complex" },
{ STRLEN("_Generic"), "_Generic" },
{ STRLEN("_Imaginary"), "_Imaginary" },
{ STRLEN("_Noreturn"), "_Noreturn" },
{ STRLEN("_Pragma"), "_Pragma" },
{ STRLEN("_Static_assert"), "_Static_assert" },
{ STRLEN("_Thread_local"), "_Thread_local" },
/* this comment is not expected to understand itself */
{ STRLEN("alignas"), "alignas" },
{ STRLEN("alignof"), "alignof" },
{ STRLEN("and"), "and" },
{ STRLEN("and_eq"), "and_eq" },
{ STRLEN("auto"), "auto" },
{ STRLEN("bitand"), "bitand" },
{ STRLEN("bitor"), "bitor" },
{ STRLEN("bool"), "bool" },
{ STRLEN("break"), "break" },
{ STRLEN("case"), "case" },
{ STRLEN("char"), "char" },
{ STRLEN("compl"), "compl" },
{ STRLEN("const"), "const" },
{ STRLEN("continue"), "continue" },
{ STRLEN("default"), "default" },
{ STRLEN("do"), "do" },
{ STRLEN("double"), "double" },
{ STRLEN("else"), "else" },
{ STRLEN("enum"), "enum" },
{ STRLEN("extern"), "extern" },
{ STRLEN("false"), "false" },
{ STRLEN("float"), "float" },
{ STRLEN("for"), "for" },
{ STRLEN("goto"), "goto" },
{ STRLEN("I"), "I" },
{ STRLEN("if"), "if" },
{ STRLEN("inline"), "inline" },
{ STRLEN("int"), "int" },
{ STRLEN("long"), "long" },
{ STRLEN("noreturn"), "noreturn" },
{ STRLEN("not"), "not" },
{ STRLEN("not_eq"), "not_eq" },
{ STRLEN("or"), "or" },
{ STRLEN("or_eq"), "or_eq" },
{ STRLEN("register"), "register" },
{ STRLEN("restrict"), "restrict" },
{ STRLEN("return"), "return" },
{ STRLEN("short"), "short" },
{ STRLEN("signed"), "signed" },
{ STRLEN("sizeof"), "sizeof" },
{ STRLEN("static"), "static" },
{ STRLEN("static_assert"), "static_assert" },
{ STRLEN("struct"), "struct" },
{ STRLEN("switch"), "switch" },
{ STRLEN("thread_local"), "thread_local" },
{ STRLEN("true"), "true" },
{ STRLEN("typedef"), "typedef" },
{ STRLEN("union"), "union" },
{ STRLEN("unsigned"), "unsigned" },
{ STRLEN("void"), "void" },
{ STRLEN("volatile"), "volatile" },
{ STRLEN("while"), "while" },
{ STRLEN("xor"), "xor" },
{ STRLEN("xor_eq"), "xor_eq" },
/**/
{ 0, NULL }
};
Word *
find_member(Word *table, const char *string)
{
Word *w;
for (w = table; w->length != 0; w++) {
if (strncmp(string, w->word, w->length) == 0
&& !isalnum(string[w->length]) && string[w->length] != '_')
return w;
}
return NULL;
}
/*
* ISO C11 section 5.2.1.1 Trigraph Sequences, leadin sequence "??"
*/
static char trigraph[] = "=(/)'<!>-";
static char asciimap[] = "#[\\]^{|}~";
/*
* Keep track of discarded bytes by read_line() so count() can report
* correct wc(1) equivalent counts.
*/
static unsigned xlcount;
static unsigned xwcount;
static unsigned xbcount;
size_t
read_line(char *buf, size_t size)
{
int ch;
size_t length;
if (buf == NULL || size == 0)
return 0;
for (size--, length = 0; length < size; ) {
if ((ch = fgetc(stdin)) == EOF)
break;
/* Map NUL bytes to space, though ideally I should chuck'em. */
if (ch == '\0')
ch = ' ';
/* Discard bare CR and those part of CRLF. */
if (ch == '\r') {
xbcount++;
continue;
}
/* Trigraph mapping? */
if (2 <= length && buf[length-2] == '?' && buf[length-1] == '?') {
char *tri;
if ((tri = strchr(trigraph, ch)) != NULL) {
/* Mapped trigraphs count as 1 byte. */
ch = asciimap[tri - trigraph];
xbcount += 2;
length -= 2;
}
}
if (ch == '\n' && 1 <= length && buf[length-1] == '\\') {
/*
* ISO C11 section 5.1.1.2 Translation Phases
* point 2 discards backslash newlines.
*/
xbcount += 2;
xwcount++;
xlcount++;
length--;
continue;
}
buf[length++] = ch;
if (ch == '\n')
break;
}
buf[length] = '\0';
return length;
}
/*
* Count octets and strip comments. The stripped C input is sent to
* standard output. If -s is set, then suppress the source output.
* The various counters are sent to standard error.
*
* The counter output format is:
*
* lcount wcount bcount icount isaved rcount rsaved
*
* where
* lcount line count (same as wc)
* wcount word count (same as wc)
* bcount byte count (same as wc)
* icount IOCCC secondary size rule count
* isaved bytes saved by secondary size rule (bcount - icount)
* rcount number of C reserved words
* rsaved number of octets saved with -r
*/
int
count(int flags)
{
Word *w;
int span;
char *p, buf[BUFFER_SIZE+1];
int lcount, wcount, bcount;
int is_comment, is_word, dquote, escape;
int count, keywords, saved, kw_saved;
/* Start of buffer sentinel. */
buf[0] = ' ';
buf[BUFFER_SIZE] = 0; /* paranoia */
count = saved = 0;
keywords = kw_saved = 0;
lcount = wcount = bcount = 0;
is_comment = is_word = dquote = escape = 0;
/*
* "no matter how well you may think you understand this code,
* you don't, so don't mess with it." :-)
*/
while (0 < read_line(buf+1, sizeof (buf)-1)) {
if (!(flags & FLAG_KEEP)) {
/* Leading whitespace before comment block? */
span = strspn(buf+1, "\t ");
/* Split / * across reads? */
if (buf[1+span] == '/' && buf[2+span] == '\0') {
(void) ungetc('/', stdin);
continue;
}
/* no comment is a comment */
if (buf[1+span] == '/' && buf[2+span] == '/')
continue;
if (buf[1+span] == '/' && buf[2+span] == '*') {
/* Strip leading whitespace before comment block. */
is_comment = 1;
}
}
for (p = buf+1; *p != '\0'; p++) {
/* Within quoted string? */
if (dquote) {
/* Escape _this_ character. */
if (escape)
escape = 0;
/* Escape next character. */
else if (*p == '\\')
escape = 1;
/* Close quoted string? */
else if (*p == '"')
dquote = 0;
}
/* Not quote string. */
else {
/* In C comment block? */
if (is_comment) {
/* Split * / across reads? */
if (*p == '*' && p[1] == '\0') {
ungetc('*', stdin);
break;
}
/* End of comment block? */
if (*p == '*' && p[1] == '/') {
is_comment = 0;
if (!(flags & FLAG_KEEP)) {
/* Strip whitespace and newline
* trailing closing comment.
*/
p += 1 + strspn(p+2, " \t\r\n");
}
}
if (!(flags & FLAG_KEEP)) {
/* Strip octets in comment block. */
continue;
}
}
/* Split / / or / * across reads? */
else if (*p == '/' && p[1] == '\0') {
ungetc('/', stdin);
break;
}
/* Start of comment line? */
else if (*p == '/' && p[1] == '/') {
if (!(flags & FLAG_KEEP)) {
/* Strip comment to end of buffer. */
break;
}
}
/* Start of comment block? */
else if (*p == '/' && p[1] == '*') {
/* Begin comment block. */
is_comment = 1;
if (!(flags & FLAG_KEEP)) {
/* Strip comment block. */
p++;
continue;
}
}
/* C reserved word? */
else if (!isalnum(p[-1]) && p[-1] != '_'
&& (w = find_member(cwords, p)) != NULL) {
keywords++;
if (flags & FLAG_RESERVED) {
bcount += w->length;
if (!is_word) {
is_word = 1;
wcount++;
}
if (!(flags & FLAG_SILENCE))
fputs(w->word, stdout);
/* Count reserved word as 1 */
kw_saved += w->length - 1;
p += w->length - 1;
count++;
continue;
}
}
/* Open quoted string? */
else if (*p == '"') {
dquote = 1;
}
}
if (!(flags & FLAG_SILENCE))
fputc(*p, stdout);
bcount++;
if (*p == '\n')
lcount++;
/*
* Ignore all whitespace
*
* Well not ALL in the Universe, just all here.
*/
if (isspace(*p)) {
is_word = 0;
saved++;
continue;
} else if (!is_word) {
is_word = 1;
wcount++;
}
/* Ignore curly braces and semicolons when followed
* by any whitespace or EOF.
*/
if (strchr("{;}", *p) != NULL
&& (isspace(p[1]) || p[1] == '\0')) {
saved++;
continue;
}
/* Count this octet. */
count++;
}
}
/* final count */
if (flags & FLAG_IOCCC_SIZE) {
/* output the official IOCCC size tool size to standard out */
printf("%d\n", count);
} else {
/* The Ugly Truth */
fprintf(stderr, "%d %d %d %d %d %d %d\n",
lcount + xlcount, wcount + xwcount, bcount + xbcount,
count, saved, keywords, kw_saved);
}
return count;
}
int
main(int argc, char **argv)
{
int ch;
int this = 0; /* "You are not expected to understand this" :-) */
/* parse args */
while ((ch = getopt(argc, argv, "ikrs")) != -1) {
switch (ch) {
case 'i':
this |= (FLAG_RESERVED | FLAG_SILENCE |
FLAG_IOCCC_SIZE);
break;
case 'k':
this |= FLAG_KEEP;
break;
case 'r':
this |= FLAG_RESERVED;
break;
case 's':
this |= FLAG_SILENCE;
break;
default:
fprintf(stderr, "%s\n", usage);
return 2;
}
}
/* count as directed - 1 Muha .. 2 Muhaha .. 3 Muhahaha ... */
(void) count(this);
/* All Done!!! All Done!!! -- Jessica Noll, age 2 */
return 0;
}
+71
View File
@@ -0,0 +1,71 @@
.POSIX :
#######################################################################
CFLAGS := -pedantic -Wall -std=c99 -g
LDFLAGS :=
LIBS :=
IT := iocccsize
#######################################################################
all: ${IT}$E
${IT}$E: ${IT}.c
${CC} ${CFLAGS} -o ${IT}$E ${IT}.c
#
# Exercise the IOCCC size tool.
#
test: test-k test-wc test-rcount
#
# -k should pass through the source with block comments intact.
#
test-k: ${IT}$E
@{ t="-k keep comments" ;\
if ./${IT} -k <${IT}.c 2>/dev/null | diff - ${IT}.c ; then echo "-OK- $$t" ; else echo "FAIL $$t" ; fi ;\
}
#
# First 3 counters should match wc(1)
#
test-wc: ${IT}$E
@{ t="wc counts" ;\
a=$$(./${IT} -s -k <${IT}.c 2>&1 | cut -d' ' -f1-3) ;\
b=$$(wc ${IT}.c | sed -e's/^ *//; s/ */ /g' | cut -d' ' -f1-3) ;\
if [ "$$a" = "$$b" ]; then echo "-OK- $$t"; else echo "FAIL $$t: expected '$$b', got '$$a'"; fi ;\
}
#
# Show counters for different option combinations.
#
test-show: ${IT}$E
./${IT} -s <${IT}.c
./${IT} -s -r <${IT}.c
./${IT} -s -k <${IT}.c
./${IT} -s -r -k <${IT}.c
#
# Reserved word counter should be same for all option combinations.
#
test-rcount: ${IT}$E
@{ t="rcount" ;\
./${IT} -s <${IT}.c 2>&1 | cut -d" " -f 6 >/tmp/$$$$.tmp ;\
./${IT} -s -r <${IT}.c 2>&1 | cut -d" " -f 6 >>/tmp/$$$$.tmp ;\
./${IT} -s -k <${IT}.c 2>&1 | cut -d" " -f 6 >>/tmp/$$$$.tmp ;\
./${IT} -s -r -k <${IT}.c 2>&1 | cut -d" " -f 6 >>/tmp/$$$$.tmp ;\
n=$$(sort -u /tmp/$$$$.tmp | wc -l | sed -e's/^ *//') ;\
if [ $$n -eq 1 ]; then echo "-OK- $$t"; else echo "FAIL $$t: expected 1 unique line, got $$n"; echo "see make test-show"; fi ;\
rm -f /tmp/$$$$.tmp ;\
}
clean:
rm -f iocccsize.o
rm -rf iocccsize.dSYM
clobber: clean
rm -f iocccsize
install:
@echo "no thank you on the install :-)"
+421
View File
@@ -0,0 +1,421 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-parentheses -Wno-implicit-function-declaration \
-Wno-missing-variable-declarations
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
#CDEFINE=
CDEFINE= -DU=${DU} -DD=${DD} -DW=${DW} -DH=${DH} -DA=${DA} -DI=${DI} \
-DB=${DB} -DF=${DF} -DG=${DG}
# Game parameters
#
DU=99999 # Time between steps in microseconds.
# Make it larger if the game is too fast for you.
DW=28 # Pipe-to-pipe spacing, in columns.
# Farther apart is easier.
DD=20 # Space between pipes.
# The difference between DD and DW is the width of a pipe.
# Narrow pipes are easier to fly though.
DH=8 # Height of gap in pipe.
# Make this larger to make the game easier.
DA=100 # Acceleration due to gravity (scaled by 256).
# Smaller values make you glide slower.
DI=-200 # Impulse velocity of a flap (scaled by 256).
# Make larger if you want an less intense tapping experience!
DB='"<o^="' # Sprite for player when gliding.
# HINT: Try using various emoji.
# NOTE: The string MUST be enclosed inside double quotes.
DF='"<ov="' # Sprite for player when flapping.
# HINT: Try using various emoji.
# NOTE: The string MUST be enclosed inside double quotes.
DG='"Tap to Flap!"' # Instruction text.
# Change to your native tongue.
# NOTE: The string MUST be enclosed inside double quotes.
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
#LIBS=
LIBS= -lcurses
#
# Here's some fun makefile overrides to try. Pass them in by adding to the
# make commandline, eg
#
# make EMOJI=beer LANGUAGE=spanish
#
# Note that use of the EMOJI path may require different include and linker
# options depending on how your system is set up. The basic requirements is
# a copy of ncurses that that supports "wide" characters. That could be
# called -lcurses, -lncurses or -lncurses, depending on how it was installed.
# it also might have been installed in a subdirectory and needs to be found
# with a different include and/or library path.
#
ifdef EMOJI
# You may need to uncomment some of these, depending on your system
# LIBS= -lncursesw
# CINCLUDE= -I/usr/local/include/ncursesw
ifeq ($(EMOJI),beer)
DB='"\xf0\x9f\x8d\xba"'
DF='"\xf0\x9f\x8d\xbb"'
endif
ifeq ($(EMOJI),smile)
DB='"\xf0\x9f\x98\x84"'
DF='"\xf0\x9f\x98\x81"'
endif
ifeq ($(EMOJI),bipolar)
DB='"\xf0\x9f\x98\xa8"'
DF='"\xf0\x9f\x98\xa1"'
endif
ifeq ($(EMOJI),toilet)
DB='"\xf0\x9f\x9a\xbd"'
DF='"\xf0\x9f\x92\xa6"'
endif
ifeq ($(EMOJI),ET)
DB='"\xf0\x9f\x9a\xb4"'
DF='"\xf0\x9f\x91\xbd"'
endif
ifeq ($(EMOJI),rocket)
DB='"\xf0\x9f\x9a\x80"'
DF='"\xf0\x9f\x92\xa5"'
endif
ifeq ($(EMOJI),frylock)
DB='"\xf0\x9f\x8d\x9f"'
DF='"\xf0\x9f\x8e\x89"'
endif
ifeq ($(EMOJI),meatwad)
DB='"\xf0\x9f\x8d\x98"'
DF='"\xf0\x9f\x8d\x96"'
endif
ifeq ($(EMOJI),chicken)
DB='"\xf0\x9f\x90\x93"'
DF='"\xf0\x9f\x92\xa8"'
endif
ifeq ($(EMOJI),chick)
DB='"\xf0\x9f\x90\xa4"'
DF='"\xf0\x9f\x90\xa5"'
endif
ifeq ($(EMOJI),finger)
DB='"\xf0\x9f\x91\x88"'
DF='"\xf0\x9f\x91\x86"'
endif
ifeq ($(EMOJI),heart)
DB='"\xf0\x9f\x92\x93"'
DF='"\xf0\x9f\x92\x97"'
endif
ifeq ($(EMOJI),poop)
DB='"\xf0\x9f\x92\xa9"'
DF='"\xf0\x9f\x92\xa8"'
endif
ifeq ($(EMOJI),money)
DB='"\xf0\x9f\x92\xb5"'
DF='"\xf0\x9f\x92\xb8"'
endif
ifeq ($(EMOJI),book)
DB='"\xf0\x9f\x93\x98"'
DF='"\xf0\x9f\x93\x96"'
endif
ifeq ($(EMOJI),megaphone)
DB='"\xf0\x9f\x93\xa2"'
DF='"\xf0\x9f\x93\xa3"'
endif
ifeq ($(EMOJI),mailbox)
DB='"\xf0\x9f\x93\xaa"'
DF='"\xf0\x9f\x93\xab"'
endif
ifeq ($(EMOJI),lock)
DB='"\xf0\x9f\x94\x92"'
DF='"\xf0\x9f\x94\x93"'
endif
ifeq ($(EMOJI),fire)
DB='"\xf0\x9f\x94\xa5"'
DF='"\xf0\x9f\x92\xa5"'
endif
ifeq ($(EMOJI),bomb)
DB='"\xf0\x9f\x92\xa3"'
DF='"\xf0\x9f\x92\xa5"'
endif
ifeq ($(EMOJI),gun)
DB='"\xf0\x9f\x94\xab"'
DF='"\xf0\x9f\x92\xa5"'
endif
ifeq ($(EMOJI),knife)
DB='"\xf0\x9f\x94\xaa"'
DF='"\xf0\x9f\x92\xab"'
endif
ifeq ($(EMOJI),globe)
DB='"\xf0\x9f\x8c\x8d"'
DF='"\xf0\x9f\x8c\x8e"'
endif
# add some magic to call setlocale
CFLAGS += -include locale.h \
-Dmain='__attribute__((constructor))Z(){return!setlocale(LC_ALL,"");}int main'
endif
ifdef LANGUAGE
ifeq ($(LANGUAGE),spanish)
DG='"\xc2\xa1Pulse para batir!"'
endif
ifeq ($(LANGUAGE),french)
DG='"Appuyez \xc3\xa0 battre"'
endif
endif
# 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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${TARGET} ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+183
View File
@@ -0,0 +1,183 @@
<!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>"For the Birds!" Award</title>
</head>
<body>
<h1>&ldquo;For the Birds!&rdquo; Award</h1>
<p>Chris Mills<br>
Twitter: @MisterXopher</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code>Pressing the up arrow and the down arrow at the right time.
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Did you find that mobile application game a bit frustrating?
Well you can adjust the makefile parameters to make life a
bit easier for you:</p>
<pre><code>make clobber all DW=199999 DW=22 DH=16 DA=50 DI=-150
</code></pre>
<p>From the makefile:</p>
<pre><code># Game parameters
#
DU=99999 # Time between steps in microseconds.
# Make it larger if the game is too fast for you.
DW=28 # Pipe-to-pipe spacing, in columns.
# Farther apart is easier.
DD=20 # Space between pipes.
# The difference between DD and DW is the width of a pipe.
# Narrow pipes are easier to fly though.
DH=8 # Height of gap in pipe.
# Make this larger to make the game easier.
DA=100 # Acceleration due to gravity (scaled by 256).
# Smaller values make you glide slower.
DI=-200 # Impulse velocity of a flap (scaled by 256).
# Make larger if you want an less intense tapping experience!
DB='"&lt;o^="' # Sprite for player when gliding.
# HINT: Try using various emoji.
# NOTE: The string MUST be enclosed inside double quotes.
DF='"&lt;ov="' # Sprite for player when flapping.
# HINT: Try using various emoji.
# NOTE: The string MUST be enclosed inside double quotes.
DG='"Tap to Flap!"' # Instruction text.
# Change to your native tongue.
# NOTE: The string MUST be enclosed inside double quotes.
</code></pre>
<p>Enjoy!</p>
<pre><code>TAP!! TAP!! TAP!!
FLAP! FLAP! FLAP!
</code></pre>
<h2>Author&rsquo;s comments:</h2>
<h1>The Program</h1>
<p>Better late than never to jump on the bandwagon of 2014&rsquo;s most successful
mobile game. The game is called Tappy Bird, and has all the sophisticated
gameplay of the original, except with an exciting twist! (you get to fly to
the right instead of to the left).</p>
<p>In addition, the game features exciting new customization options! Too hard?
Ran into that damn wall too many times? Now you can change physics! Change
any of a number of parameters (speed, gravity, etc.) of the game to suit your
gameplay!</p>
<p>You can even make the game more challenging &ndash; resize the terminal window to
make the world taller or shorter. You&rsquo;ll never be able to get through the
pipes when they are four times as tall!</p>
<h2>Instructions</h2>
<p>The instructions are printed at the start of the game: Tap to Flap!</p>
<p>Hit any key to make your bird fly. Navigate her between the gaps in the pipes.
Your score is shown in the upper left, along with your current high-score.</p>
<h2>Customization options</h2>
<p>To customize the gameplay, change any of the following options on the compile
command line:</p>
<ul>
<li><code>-DU</code>: Time between steps in microseconds. Make it larger if the game
is too fast for you.</li>
<li><code>-DW</code>: Pipe-to-pipe spacing, in columns. Farther apart is easier.</li>
<li><code>-DD</code>: Space between pipes. The difference between <code>D</code> and <code>W</code> is the
width of the pipe. Narrow pipes are easier to fly though.</li>
<li><code>-DH</code>: Height of gap in pipe. Make this larger to reduce the challenge.</li>
<li><code>-DA</code>: Acceleration due to gravity (scaled by 256). Smaller values
make you glide slower.</li>
<li><code>-DI</code>: Impulse velocity of a flap (scaled by 256). Make this smaller
if you want an intense tapping experience!</li>
<li><code>-DB</code>: Sprite for player when gliding.</li>
<li><code>-DF</code>: Sprite for player when flapping.</li>
<li><code>-DG</code>: Instruction text. Change to your native tongue.</li>
</ul>
<p>Feel free to try out physics or playfield options to make the game more
interesting. Try setting the player sprites to change the game completely &ndash;
maybe you can be a fish, or a pig &ndash; the options are limitless! Try using
emoji &ndash; you can be a flying beer mug!</p>
<p>Note that since the <code>curses</code> library on POSIX doesn&rsquo;t natively support wide
characters (needed for UTF-8 support, which is needed for emoji), you may need
to make some changes to the <code>Makefile</code> to get emoji to work on your system.
To help you get started, I&rsquo;ve included some example substitutions for emoji
sprites and instruction text; for example, type</p>
<pre><code>make EMOJI=beer LANGUAGE=spanish
</code></pre>
<p>or</p>
<pre><code>make EMOJI=globe
</code></pre>
<p>for some examples (the full list of options is in the <code>Makefile</code>). Don&rsquo;t
forget to <code>make clean</code> first. If the output doesn&rsquo;t look right, you may need
to link with the &ldquo;wide&rdquo; version of <code>ncurses</code>. On MacOSX 10.11, it should work
with the current <code>-lcurses</code>; on Linux, you probably need <code>-lncursesw</code>.
See the <code>Makefile</code> to make this change if you need to. Or buy a Mac.</p>
<p>You will also need a UTF-8 compatible terminal and an emoji font installed,
and you will need to have your <code>LANG</code> environment variable set to use UTF-8.
Again, if this is too complicated, maybe just go and get that Mac.</p>
<h2>Future additions</h2>
<p>Future versions of the game will include monitization via the freemium model
with micropayments for customization options, play-to-win and of course
live-streamed targeted video advertising.</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+156
View File
@@ -0,0 +1,156 @@
# "For the Birds!" Award
Chris Mills
Twitter: @MisterXopher
## Judges' comments:
### To use:
make
./prog
### Try:
Pressing the up arrow and the down arrow at the right time.
### Selected Judges Remarks:
Did you find that mobile application game a bit frustrating?
Well you can adjust the makefile parameters to make life a
bit easier for you:
make clobber all DW=199999 DW=22 DH=16 DA=50 DI=-150
From the makefile:
# Game parameters
#
DU=99999 # Time between steps in microseconds.
# Make it larger if the game is too fast for you.
DW=28 # Pipe-to-pipe spacing, in columns.
# Farther apart is easier.
DD=20 # Space between pipes.
# The difference between DD and DW is the width of a pipe.
# Narrow pipes are easier to fly though.
DH=8 # Height of gap in pipe.
# Make this larger to make the game easier.
DA=100 # Acceleration due to gravity (scaled by 256).
# Smaller values make you glide slower.
DI=-200 # Impulse velocity of a flap (scaled by 256).
# Make larger if you want an less intense tapping experience!
DB='"<o^="' # Sprite for player when gliding.
# HINT: Try using various emoji.
# NOTE: The string MUST be enclosed inside double quotes.
DF='"<ov="' # Sprite for player when flapping.
# HINT: Try using various emoji.
# NOTE: The string MUST be enclosed inside double quotes.
DG='"Tap to Flap!"' # Instruction text.
# Change to your native tongue.
# NOTE: The string MUST be enclosed inside double quotes.
Enjoy!
TAP!! TAP!! TAP!!
FLAP! FLAP! FLAP!
## Author's comments:
The Program
===========
Better late than never to jump on the bandwagon of 2014's most successful
mobile game. The game is called Tappy Bird, and has all the sophisticated
gameplay of the original, except with an exciting twist! (you get to fly to
the right instead of to the left).
In addition, the game features exciting new customization options! Too hard?
Ran into that damn wall too many times? Now you can change physics! Change
any of a number of parameters (speed, gravity, etc.) of the game to suit your
gameplay!
You can even make the game more challenging -- resize the terminal window to
make the world taller or shorter. You'll never be able to get through the
pipes when they are four times as tall!
Instructions
------------
The instructions are printed at the start of the game: Tap to Flap!
Hit any key to make your bird fly. Navigate her between the gaps in the pipes.
Your score is shown in the upper left, along with your current high-score.
Customization options
---------------------
To customize the gameplay, change any of the following options on the compile
command line:
* `-DU`: Time between steps in microseconds. Make it larger if the game
is too fast for you.
* `-DW`: Pipe-to-pipe spacing, in columns. Farther apart is easier.
* `-DD`: Space between pipes. The difference between `D` and `W` is the
width of the pipe. Narrow pipes are easier to fly though.
* `-DH`: Height of gap in pipe. Make this larger to reduce the challenge.
* `-DA`: Acceleration due to gravity (scaled by 256). Smaller values
make you glide slower.
* `-DI`: Impulse velocity of a flap (scaled by 256). Make this smaller
if you want an intense tapping experience!
* `-DB`: Sprite for player when gliding.
* `-DF`: Sprite for player when flapping.
* `-DG`: Instruction text. Change to your native tongue.
Feel free to try out physics or playfield options to make the game more
interesting. Try setting the player sprites to change the game completely --
maybe you can be a fish, or a pig -- the options are limitless! Try using
emoji -- you can be a flying beer mug!
Note that since the `curses` library on POSIX doesn't natively support wide
characters (needed for UTF-8 support, which is needed for emoji), you may need
to make some changes to the `Makefile` to get emoji to work on your system.
To help you get started, I've included some example substitutions for emoji
sprites and instruction text; for example, type
make EMOJI=beer LANGUAGE=spanish
or
make EMOJI=globe
for some examples (the full list of options is in the `Makefile`). Don't
forget to `make clean` first. If the output doesn't look right, you may need
to link with the "wide" version of `ncurses`. On MacOSX 10.11, it should work
with the current `-lcurses`; on Linux, you probably need `-lncursesw`.
See the `Makefile` to make this change if you need to. Or buy a Mac.
You will also need a UTF-8 compatible terminal and an emoji font installed,
and you will need to have your `LANG` environment variable set to use UTF-8.
Again, if this is too complicated, maybe just go and get that Mac.
Future additions
----------------
Future versions of the game will include monitization via the freemium model
with micropayments for customization options, play-to-win and of course
live-streamed targeted video advertising.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+26
View File
@@ -0,0 +1,26 @@
#define P(a,b,c) a##b##c
#include/*++**++*/<curses.h>
int c,h, v,x,y,s, i,b; int
main () { initscr( ); P(cb,
rea, k)() ;///
P(n, oec, ho)(
)/* */ ;for (curs_set(0); s= x=COLS/2
; P( flu, shi, np)()){ timeout(y=c= v=0);///
P(c, lea, r)() ;for (P (
mva, d, dstr )(2, 3+x,
G) ; ; P( usl, eep, )(U)){//
P(m, vad, dstr )( y >>8,x,//
" "); for(i=LINES; /* */ i -->0
; mvinsch(i,0,0>(~c|i-h-H &h-i )?' '
:(i- h|h- i+H) <0?'|' :'=' ));
if(( i=( y +=v= getch( )>0?I:v+
A)>>8)>=LINES||mvinch(i*= 0<i, x)!=' '||' '
!=mvinch(i,3+x))break/*&% &*/; mvaddstr(y
>>8, x,0>v ?F:B ); i=--s
/-W; P(m, vpr, intw)(0,
COLS-9," %u/%u ",(0<i)* i,b=b<i?i:
b); refresh(); if(++ c==D){ c
-=W; h=rand()%(LINES-H-6
)+2; } } flash(); }}
+256
View File
@@ -0,0 +1,256 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-shift-op-parentheses -Wno-implicit-function-declaration \
-Wno-unused-parameter -Wno-missing-prototypes \
-Wno-missing-variable-declarations -Wno-shadow
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
CDEFINE=
# include files that are needed to compile
#
#CINCLUDE=
CINCLUDE= -include stdlib.h
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+157
View File
@@ -0,0 +1,157 @@
<!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 Compact</title>
</head>
<body>
<h1>Most Compact</h1>
<p>Chris Mills<br>
Twitter: @MisterXopher</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog compressed_file.Z
</code></pre>
<h3>Try:</h3>
<pre><code>printf '000I\236\f\31H\260\240\301\203' &gt; ioccc.Z
./prog ioccc.Z
dd bs=1k count=4096 &lt; /dev/urandom &gt; test1
compress &lt; test1 &gt; test1.Z
time ./prog test1.Z | cmp - test1
dd bs=1k count=4096 &lt; /dev/zero &gt; test2
compress &lt; test2 &gt; test2.Z
time ./prog test2.Z | cmp - test2
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Without ASCII art, the source code of this entry would have been exactly 256 bytes.
Compared to <a href="http://ioccc.org/years.html#1990_jaw">1990/jaw</a>, it is very impressive,
even taking into account the missing atob functionality. Now we wish for a compress(1)-like compressor
using a similar idea.</p>
<p>Why is the sad smiley on line 12 in that particular place?</p>
<h2>Author&rsquo;s comments:</h2>
<h1>The Program</h1>
<p>This program is in implementation of the unix <code>zcat(1)</code> command for printing
compressed files that have been created by the <code>compress(1)</code> command.</p>
<p>The adaptive <a href="https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Welch">LZW</a> compression
employed by <code>compress</code> usually requires a fairly large amount of memory to
build the decompression tables (in fact, <code>compress</code> has a command-line option
to control the size of the decompression tables, since some of the early
systems to which it was ported (<em>cough</em>MS-DOS<em>cough</em>) did not have enough
memory to use the full 16-bit codes). This version has no large static or
dynamic tables. It is able to decompress 16-bit files using a single function
and a few ints.</p>
<p>To run the program, take an existing compressed file and pass it to the program
on the command line. On the odd chance you don&rsquo;t have <code>compress</code> hanging about
on your system, I&rsquo;ve provided compressed copies of this year&rsquo;s IOCCC rules
and guidelines files. To print them, just do</p>
<pre><code>./prog ioccc_guidelines.txt.Z
</code></pre>
<h2>The Details</h2>
<p>The basic cleverness here comes from realizing that the compressed data is
itself an encoded version of the code dictionary. When the encoder sees
an input string that is not in its dictionary, it emits the code corresponding
to the longest prefix that is in the dictionary and adds a new entry consisting
of that code followed by the next input character. This means that when the
decoder wants to know how to decode a code, it just needs to find the spot in
the code-stream where the encoder added that entry to the dictionary. The
code at that spot is the prefix, and the first character of the following code
is the suffix. Decoding then just becomes recursion, to follow the chain of
prefixes and suffix characters.</p>
<p>Of course, it&rsquo;s not nearly that simple. Finding the code in the stream is
complicated by several issues:</p>
<ul>
<li>Codes are at bit offsets within the stream, and must be extracted.</li>
<li>As codes are added to the dictionary, the code word size grows, so finding
the offset to a particular code word is involved.</li>
<li>The <code>compress</code> encoder reserves a code word that clears the coding tables.
When this is encountered, the computation of offsets and bit sizes reset.</li>
<li>The <code>compress</code> decoder is designed to always read a block of eight code
words at the same time, so that it need only read N bytes to get eight N-bit
code words. When the &ldquo;clear&rdquo; code is encountered, the entire eight-word
block is flushed (since the decoder didn&rsquo;t know the word size would change).
The program needs to account for this extra flushing.</li>
<li>The end of the stream is not explicitly marked; the encoder just pads out
the output to the next byte. The decoder must notice this to know when
to stop.</li>
<li>The output stream contains a header that must be skipped.</li>
</ul>
<p>Managing all the details involved added a lovely additional layer of
obfuscation to the otherwise elegant recursive decoder. Still, the code
manages it in a remarkably small amount of code.</p>
<h2>Limitations</h2>
<p>The decoder doesn&rsquo;t look at the header. If you supply something that is not
compressed data, it&rsquo;s likely to crash in an interesting manner.</p>
<p>In particular, it doesn&rsquo;t look at the third byte of the header, which encodes
the maximum code word size and whether &ldquo;block mode&rdquo; was used when the encoder
was run. If you use <code>compress</code> in its default mode, the maximum word size
will be 16 bits and &ldquo;block mode&rdquo; will be enabled. You are unlikely to find
any files that don&rsquo;t use &ldquo;block mode&rdquo;, since all versions of <code>compress</code> after
2.0 (circa 1984) use it by default and have no documented way to disable it.
Reducing the bit depth is still possibly by using the <code>-b</code> flag. Modern
systems have no problem with the 200 KB or so needed for 16-bit decoder
tables, so the need for reducing the table size has passed, hence this program
always assumes 16-bits&hellip; However, should you find a file that needs a
smaller table, feel free to change the hard-coded 16 in the source into the
appropriate number and recompile.</p>
<p>In the event that you don&rsquo;t supply an argument, or that argument doesn&rsquo;t name
a readable file, the program will just silently exit. This is a feature.</p>
<p>The program depends on having a little-endian system. On a big-endian system
you will get a wierd big-endian version of <code>compress</code>, which might have come to
pass in an alternate universe where the vax on which <code>compress</code> was authored
had been big-endian. Luckily for us, it wasn&rsquo;t, and neither are most of the
systems you might want to compile this for.</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+131
View File
@@ -0,0 +1,131 @@
# Most Compact
Chris Mills
Twitter: @MisterXopher
## Judges' comments:
### To use:
make
./prog compressed_file.Z
### Try:
printf '000I\236\f\31H\260\240\301\203' > ioccc.Z
./prog ioccc.Z
dd bs=1k count=4096 < /dev/urandom > test1
compress < test1 > test1.Z
time ./prog test1.Z | cmp - test1
dd bs=1k count=4096 < /dev/zero > test2
compress < test2 > test2.Z
time ./prog test2.Z | cmp - test2
### Selected Judges Remarks:
Without ASCII art, the source code of this entry would have been exactly 256 bytes.
Compared to [1990/jaw](http://ioccc.org/years.html#1990_jaw), it is very impressive,
even taking into account the missing atob functionality. Now we wish for a compress(1)-like compressor
using a similar idea.
Why is the sad smiley on line 12 in that particular place?
## Author's comments:
The Program
===========
This program is in implementation of the unix `zcat(1)` command for printing
compressed files that have been created by the `compress(1)` command.
The adaptive [LZW](https://en.wikipedia.org/wiki/Lempel–Ziv–Welch) compression
employed by `compress` usually requires a fairly large amount of memory to
build the decompression tables (in fact, `compress` has a command-line option
to control the size of the decompression tables, since some of the early
systems to which it was ported (*cough*MS-DOS*cough*) did not have enough
memory to use the full 16-bit codes). This version has no large static or
dynamic tables. It is able to decompress 16-bit files using a single function
and a few ints.
To run the program, take an existing compressed file and pass it to the program
on the command line. On the odd chance you don't have `compress` hanging about
on your system, I've provided compressed copies of this year's IOCCC rules
and guidelines files. To print them, just do
./prog ioccc_guidelines.txt.Z
The Details
-----------
The basic cleverness here comes from realizing that the compressed data is
itself an encoded version of the code dictionary. When the encoder sees
an input string that is not in its dictionary, it emits the code corresponding
to the longest prefix that is in the dictionary and adds a new entry consisting
of that code followed by the next input character. This means that when the
decoder wants to know how to decode a code, it just needs to find the spot in
the code-stream where the encoder added that entry to the dictionary. The
code at that spot is the prefix, and the first character of the following code
is the suffix. Decoding then just becomes recursion, to follow the chain of
prefixes and suffix characters.
Of course, it's not nearly that simple. Finding the code in the stream is
complicated by several issues:
* Codes are at bit offsets within the stream, and must be extracted.
* As codes are added to the dictionary, the code word size grows, so finding
the offset to a particular code word is involved.
* The `compress` encoder reserves a code word that clears the coding tables.
When this is encountered, the computation of offsets and bit sizes reset.
* The `compress` decoder is designed to always read a block of eight code
words at the same time, so that it need only read N bytes to get eight N-bit
code words. When the "clear" code is encountered, the entire eight-word
block is flushed (since the decoder didn't know the word size would change).
The program needs to account for this extra flushing.
* The end of the stream is not explicitly marked; the encoder just pads out
the output to the next byte. The decoder must notice this to know when
to stop.
* The output stream contains a header that must be skipped.
Managing all the details involved added a lovely additional layer of
obfuscation to the otherwise elegant recursive decoder. Still, the code
manages it in a remarkably small amount of code.
Limitations
-----------
The decoder doesn't look at the header. If you supply something that is not
compressed data, it's likely to crash in an interesting manner.
In particular, it doesn't look at the third byte of the header, which encodes
the maximum code word size and whether "block mode" was used when the encoder
was run. If you use `compress` in its default mode, the maximum word size
will be 16 bits and "block mode" will be enabled. You are unlikely to find
any files that don't use "block mode", since all versions of `compress` after
2.0 (circa 1984) use it by default and have no documented way to disable it.
Reducing the bit depth is still possibly by using the `-b` flag. Modern
systems have no problem with the 200 KB or so needed for 16-bit decoder
tables, so the need for reducing the table size has passed, hence this program
always assumes 16-bits... However, should you find a file that needs a
smaller table, feel free to change the hard-coded 16 in the source into the
appropriate number and recompile.
In the event that you don't supply an argument, or that argument doesn't name
a readable file, the program will just silently exit. This is a feature.
The program depends on having a little-endian system. On a big-endian system
you will get a wierd big-endian version of `compress`, which might have come to
pass in an alternate universe where the vax on which `compress` was authored
had been big-endian. Luckily for us, it wasn't, and neither are most of the
systems you might want to compile this for.
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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.
+19
View File
@@ -0,0 +1,19 @@
int I=256,l,c, o,O=3; void e(
int L){ o=0; for( l=8; L>>++l&&
16>l; o+=l
<<l- 1) ;
o+=l *L-(l<<l-1); { ; }
if ( pread(3,&L,3,O+o/8)<
2)/* */exit(0); L>>=7&o;
L%=1 <<l; L>>8?256-L?e(
L-1) ,c||
(e(c =L),
c=0) :( O
+=(-I&7)*l+o+l>>3,I=L):putchar(
L); }int main(int l,char**o){
for(
/* //// */
open(1[o],0); ; e(I++
)) ;}
+268
View File
@@ -0,0 +1,268 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
CUT=cut
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
#CSILENCE=
CSILENCE= -Wno-keyword-macro -Wno-unused-macros
# compiler standard
#
#CSTD=
#CSTD= -ansi
#CSTD= -std=c11
CSTD= -std=c1x
# compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitess:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# defines that are needed to compile
#
#CDEFINE=
CDEFINE= -DX="$(X)" -DV="$(V)"
# include files that are needed to compile
#
#CINCLUDE=
CINCLUDE= -include "${MACHINE}" -include "${TAPE}"
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
LIBS=
#LIBS= -L ${X11_LIBDIR}
# 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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
MACHINE = machine_beaver_4_2.h
TAPE = tape_empty.h
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
# test the entry
#
.PHONY: run
run: ${ENTRY}
@ ./${ENTRY} | ${TR} -d '~'
@ [ -z "${V}" ] || [ "${V}" -lt 1 ] || { echo "total:" $$(./${ENTRY} | ${TR} -dc '~' | wc -c) "steps"; }
@ [ -z "${V}" ] || [ "${V}" -lt 2 ] || { ./${ENTRY} | ${GREP} '^~' | ${CUT} -f2 | ${SORT} | ${UNIQ} -c; }
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+151
View File
@@ -0,0 +1,151 @@
<!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 Complete Use of CPP</title>
</head>
<body>
<h1>Most Complete Use of CPP</h1>
<p>Dominik Muth <a href="&#109;&#x61;&#105;&#108;&#116;&#x6f;&#58;&#x6d;&#x75;&#116;&#x68;&#x2e;&#105;&#111;&#99;&#x63;&#99;&#64;&#x66;&#114;&#101;&#101;&#x6e;&#101;&#116;&#x2e;&#100;&#101;">&#109;&#x75;&#x74;&#104;&#46;&#x69;&#111;&#99;&#99;&#x63;&#x40;&#102;&#x72;&#x65;&#x65;&#x6e;&#x65;&#116;&#46;&#x64;&#101;</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make -B [MACHINE=your_machine.h] [TAPE=your_tape.h] [X=[0|1|2|3|4|5|6|7|8|9]] [V=[0|1|2]] run
</code></pre>
<h3>Try:</h3>
<pre><code>make -B V=2 run
strings prog | grep '(,)'
make -B MACHINE=machine_times2.h TAPE=tape_five.h V=1 run
make -B MACHINE=machine_chaos_5_2.h X=5 run
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This is something we were fearing all along: that the C preprocessor is Turing-complete
even without conditionals and recursive file inclusion as some kind of a
<a href="https://en.wikipedia.org/wiki/Rewriting">rewriting system</a>. Now we have the proof!</p>
<h2>Author&rsquo;s comments:</h2>
<h3>Preprocessor Turing Engine</h3>
<h4>Features</h4>
<ul>
<li>Turing machine runs in preprocessor</li>
<li>universal (unlimited configurable states, symbols, and tape)</li>
<li>no <code>#if</code>s or other conditional directives, only <code>#define</code>s</li>
<li>no recursive <code>#include</code></li>
<li>single compiler run (no repeated preprocessing)</li>
<li>no variadic macros</li>
<li>verbosity levels:
<ul>
<li><code>V=0</code> (default) only prints the final tape</li>
<li><code>V=1</code> additionally prints one tilde character per machine step (slow)</li>
<li><code>V=2</code> additionally prints details on each machine step (slow; generates large files)</li>
</ul>
</li>
<li>make target <code>run</code> runs <code>./prog</code> and filters a little statistics out of the verbose output</li>
<li><code>X</code> (defaults to 3) sets the maximum number of steps: <em>M</em>(<code>X</code>) ~ 8<sup><code>X</code></sup></li>
</ul>
<h4>Limitations</h4>
<p>If the machine does not halt after <em>M</em>(<code>X</code>) steps, you will see unexpanded macros in the output.</p>
<h4>Compiler warnings</h4>
<p>If <code>V=1</code> or <code>V=2</code> is used, you may see &ldquo;<code>warning: string length is greater than the length '4095' ISO C99 compilers are required to support</code>&rdquo;.</p>
<h4>Programming</h4>
<p>Implementing your own Turing machine is easy. Take a look at the supplied header files for examples.</p>
<h5>Tape Symbols</h5>
<p>Every symbol used (except &ldquo;<code>_</code>&rdquo;) must be explicitly declared using</p>
<pre><code>#define sym_SYMBOL(sym, _SYMBOL) sym
</code></pre>
<p>Example:</p>
<pre><code>#define sym_1(sym, _1) sym
</code></pre>
<h5>Tape</h5>
<p>The initial content of the tape must be defined in the tape header using a triple like:</p>
<pre><code>#define tape ((((,),...l2), l1), c, (r1, (r2..., (,))))
</code></pre>
<ul>
<li><code>l1</code>, <code>l2</code>, &hellip; are the symbols to the left</li>
<li><code>c</code> is the symbol at the current position</li>
<li><code>r1</code>, <code>r2</code>, &hellip; are the symbols to the right</li>
</ul>
<p>The empty pairs &ldquo;<code>(,)</code>&rdquo; represent the continuations of the tape, filled with underscore symbols (&ldquo;<code>_</code>&rdquo;). They are expanded on demand.</p>
<h5>State Machine</h5>
<p>All transitions are defined in the machine header using the syntax</p>
<pre><code>#define CURRENT_SCANNED (WRITE, MOVEMENT, NEXT)
</code></pre>
<p>where</p>
<ul>
<li><code>CURRENT</code> is the current state</li>
<li><code>SCANNED</code> is the symbol at the current position</li>
<li>the whitespace before the parentheses is significant</li>
<li><code>WRITE</code> is the symbol to be written to the tape</li>
<li><code>MOVEMENT</code> is &ldquo;<code>L</code>&rdquo; for left, &ldquo;<code>R</code>&rdquo; for right, or nothing</li>
<li><code>NEXT</code> is the next state</li>
</ul>
<p>There must be a state &ldquo;<code>A</code>&rdquo; defined, which becomes the initial state of the machine.</p>
<p>To halt the machine, use the keyword &ldquo;<code>break</code>&rdquo; as in</p>
<pre><code>#define A_1 (2, break)
</code></pre>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+107
View File
@@ -0,0 +1,107 @@
# Most Complete Use of CPP
Dominik Muth <muth.ioccc@freenet.de>
## Judges' comments:
### To use:
make -B [MACHINE=your_machine.h] [TAPE=your_tape.h] [X=[0|1|2|3|4|5|6|7|8|9]] [V=[0|1|2]] run
### Try:
make -B V=2 run
strings prog | grep '(,)'
make -B MACHINE=machine_times2.h TAPE=tape_five.h V=1 run
make -B MACHINE=machine_chaos_5_2.h X=5 run
### Selected Judges Remarks:
This is something we were fearing all along: that the C preprocessor is Turing-complete
even without conditionals and recursive file inclusion as some kind of a
[rewriting system](https://en.wikipedia.org/wiki/Rewriting). Now we have the proof!
## Author's comments:
### Preprocessor Turing Engine
#### Features
- Turing machine runs in preprocessor
- universal (unlimited configurable states, symbols, and tape)
- no `#if`s or other conditional directives, only `#define`s
- no recursive `#include`
- single compiler run (no repeated preprocessing)
- no variadic macros
- verbosity levels:
+ `V=0` (default) only prints the final tape
+ `V=1` additionally prints one tilde character per machine step (slow)
+ `V=2` additionally prints details on each machine step (slow; generates large files)
- make target `run` runs `./prog` and filters a little statistics out of the verbose output
- `X` (defaults to 3) sets the maximum number of steps: *M*(`X`) ~ 8<sup>`X`</sup>
#### Limitations
If the machine does not halt after *M*(`X`) steps, you will see unexpanded macros in the output.
#### Compiler warnings
If `V=1` or `V=2` is used, you may see "`warning: string length is greater than the length '4095' ISO C99 compilers are required to support`".
#### Programming
Implementing your own Turing machine is easy. Take a look at the supplied header files for examples.
##### Tape Symbols
Every symbol used (except "`_`") must be explicitly declared using
#define sym_SYMBOL(sym, _SYMBOL) sym
Example:
#define sym_1(sym, _1) sym
##### Tape
The initial content of the tape must be defined in the tape header using a triple like:
#define tape ((((,),...l2), l1), c, (r1, (r2..., (,))))
- `l1`, `l2`, ... are the symbols to the left
- `c` is the symbol at the current position
- `r1`, `r2`, ... are the symbols to the right
The empty pairs "`(,)`" represent the continuations of the tape, filled with underscore symbols ("`_`"). They are expanded on demand.
##### State Machine
All transitions are defined in the machine header using the syntax
#define CURRENT_SCANNED (WRITE, MOVEMENT, NEXT)
where
- `CURRENT` is the current state
- `SCANNED` is the symbol at the current position
- the whitespace before the parentheses is significant
- `WRITE` is the symbol to be written to the tape
- `MOVEMENT` is "`L`" for left, "`R`" for right, or nothing
- `NEXT` is the next state
There must be a state "`A`" defined, which becomes the initial state of the machine.
To halt the machine, use the keyword "`break`" as in
#define A_1 (2, break)
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
+19
View File
@@ -0,0 +1,19 @@
/*
* 4 state, 2 symbol busy beaver, http://www.logique.jussieu.fr/~michel/ha.html#tm42
*
* halts after 107 steps
*/
#define sym_1(sym, _1) sym
#define A__ (1, R, B)
#define A_1 (1, L, B)
#define B__ (1, L, A)
#define B_1 (_, L, C)
#define C__ (1,break)
#define C_1 (1, L, D)
#define D__ (1, R, D)
#define D_1 (_, R, A)
+19
View File
@@ -0,0 +1,19 @@
/*
* 2 state, 4 symbol current champion, http://www.logique.jussieu.fr/~michel/ha.html#tm24
*
* halts after 3932964 steps
*/
#define sym_1(sym, _1) sym
#define sym_2(sym, _2) sym
#define sym_3(sym, _3) sym
#define A__ (1, R, B)
#define A_1 (2, L, A)
#define A_2 (1, R, A)
#define A_3 (1, R, A)
#define B__ (1, L, B)
#define B_1 (1, L, A)
#define B_2 (3, R, B)
#define B_3 (1,break)
+22
View File
@@ -0,0 +1,22 @@
/*
* chaos machine, http://www.drb.insel.de/~heiner/BB/mabu90.html
*
* does not halt (http://www.drb.insel.de/~heiner/BB/TM4-proof.txt)
*/
#define sym_1(sym, _1) sym
#define A__ (1, L, B)
#define A_1 (1, R, B)
#define B__ (1, R, C)
#define B_1 (_, L, E)
#define C__ (_, R, D)
#define C_1 (_, L, A)
#define D__ (1, L, A)
#define D_1 (_, R, D)
#define E__ (1,break)
#define E_1 (_, L, C)
+20
View File
@@ -0,0 +1,20 @@
/*
* complex machine, http://www.drb.insel.de/~heiner/BB/mabu90.html
*/
#define sym_1(sym, _1) sym
#define A__ (1, L, B)
#define A_1 (1, R, A)
#define B__ (_, R, A)
#define B_1 (_, L, C)
#define C__ (_, R, C)
#define C_1 (1, L, D)
#define D__ (1, L, E)
#define D_1 (_, R, A)
#define E__ (_, L, B)
#define E_1 (1,break)
+22
View File
@@ -0,0 +1,22 @@
/*
* counting machine, http://www.drb.insel.de/~heiner/BB/mabu90.html
*
* does not halt
*/
#define sym_1(sym, _1) sym
#define A__ (1, L, B)
#define A_1 (1, R, A)
#define B__ (_, R, A)
#define B_1 (_, L, C)
#define C__ (_, R, A)
#define C_1 (1, L, D)
#define D__ (_, L, E)
#define D_1 (1, R, B)
#define E__ (_, R, B)
#define E_1 (1,break)
+56
View File
@@ -0,0 +1,56 @@
/*
* greatest common divisor
*
* based on http://www.ioccc.org/2001/herrmann1.gcd
*/
// try tape_15_50.h or tape_77_55.h
#define A__ (_, R, A )
#define A_1 (1, L, x9)
#define x0_1 (_, R, x1)
#define x1__ (_, R, xa)
#define x1_1 (1, R, x2)
#define x2__ (_, R, x3)
#define x2_1 (1, R, x2)
#define x3__ (_, R, x3)
#define x3_1 (1, R, x4)
#define x4__ (1, L, x5)
#define x4_1 (1, R, x4)
#define x5_1 (_, L, x6)
#define x6__ (_, R, xc)
#define x6_1 (1, L, x7)
#define x7__ (_, L, x8)
#define x7_1 (1, L, x7)
#define x8__ (_, L, x8)
#define x8_1 (1, L, x9)
#define x9__ (1, R, x0)
#define x9_1 (1, L, x9)
#define xa__ (_, R, xa)
#define xa_1 (_, R, xb)
#define xb__ (_, R, xf)
#define xb_1 (1, R, xc)
#define xc__ (_, R, xd)
#define xc_1 (1, R, xc)
#define xd__ (_, L, xe)
#define xd_1 (_, R, xd)
#define xe__ (_, L, xe)
#define xe_1 (1, L, x7)
#define xf__ (_, break)
#define xf_1 (_, R, xf)
+16
View File
@@ -0,0 +1,16 @@
/*
* greater machine, http://www.drb.insel.de/~heiner/BB/mabu90.html
*
* does not halt
*/
#define sym_1(sym, _1) sym
#define A__ (1, L, B)
#define A_1 (1, R, A)
#define B__ (_, R, C)
#define B_1 (1, L, B)
#define C__ (1,break)
#define C_1 (1, R, A)
+40
View File
@@ -0,0 +1,40 @@
#/*
* this is a guide how to choose names for states and symbols
*
* state names must be valid to start a macro identifier, e.g., # is
* invalid, 0 is invalid, _0 is valid (an empty string is also valid)
*
* tape symbols must not be empty and must be valid to end a macro
* name, e.g., # is invalid, 0 is valid, _0 is valid
*
* exception: you can write almost any other sequence of tokens to the
* tape, but you can not scan them back (you can not even define them
* as symbols using the
*
*/ define sym_SYMBOL(sym, _SYMBOL) sym
#/*
* syntax)
*
* finally its perfectly ok to define macros for your states like this
*
*/ define ANOTHER_NAME_FOR_A A
#/*
* and for your symbols like this
*
*/ define FQDN www.ioccc.org.
#define you can run this example on an empty tape
#define A__ (SYMBOL, L,)
#define __ (__, ,)
#define ___ (, R, ANOTHER_NAME_FOR_A)
#define A_SYMBOL (\x1b[4mhttp, R, I)
#define I__ (:, R, O )
#define O__ (/\x2f, R, C)
#define C__ (FQDN, R, Z)
#define Z__ (/, R, L)
#define L__ (index.html, R, _2)
#define _2__ (#enter\x1b[0m, R, _0)
#define _0__ (R(A, tape), R, _1)
#define _1__ ((,), R, _5)
#define _5__ (W(You you!!!), break)
+7
View File
@@ -0,0 +1,7 @@
/*
* minimal Turing machine example
*
* see also: tape_empty.h
*/
#define A__ (_, break)
+19
View File
@@ -0,0 +1,19 @@
/*
* 2 state, 4 symbol current runner-up, http://www.logique.jussieu.fr/~michel/ha.html#tm24
*
* halts after 7195 steps
*/
#define sym_1(sym, _1) sym
#define sym_2(sym, _2) sym
#define sym_3(sym, _3) sym
#define A__ (1, R, B)
#define A_1 (3, L, A)
#define A_2 (1, L, A)
#define A_3 (1, R, A)
#define B__ (2, L, A)
#define B_1 (1,break)
#define B_2 (3, R, A)
#define B_3 (3, R, B)
+21
View File
@@ -0,0 +1,21 @@
/*
* multiply by 2
*
* based on http://www.ioccc.org/2001/herrmann1.times2
*/
// try tape_five.h
#define A__ (_, R, A)
#define A_1 (_, L, B)
#define B__ (1, L, C)
#define C__ (1, R, D)
#define C_1 (1, L, C)
#define D__ (_, R, E)
#define D_1 (1, R, D)
#define E__ (_,break)
#define E_1 (_, L, B)
+95
View File
@@ -0,0 +1,95 @@
# define S(M, L, N, R) J(M, P) (L, N, R )
# define QL(L, R)/* L,*/QR(L, /*N,*/ R)//
# define P( L, N, R) L, N, R//
# define LP( L, N, R) U L, D L, (N, R)
# define R( L, R)W (Y(J(E,X)(K(L, R ))))
# define RP( L, N, R)(L, N), H R, T R//
# define HP( L, N, R) L, N, R//
# define K( L, R)/* L,*/J(F, V)(L, R)J \
( Q,sym_ ( K, M ( L, B R))) (L, R )
# define Q( L, R)/* L,*/QR(L, /*N,*/ R)//
# define E( X)E3(X)
# define break H ,
# define E0(/**/X)X
# define I( X, E) K
# define EX(X)E3(X)
#define E1(_I_)E0 (E0(E0(E0(E0(E0(E0 (E0( _I_ ))))))))
#define E2(_O_)E1 (E1(E1(E1(E1(E1(E1 (E1( _O_ ))))))))
#define E3(_C_)E2 (E2(E2(E2(E2(E2(E2 (E2( _C_ ))))))))
#define E4(_C_)E3 (E3(E3(E3(E3(E3(E3 (E3( _C_ ))))))))
#define E5(_C_)E4 (E4(E4(E4(E4(E4(E4 (E4( _C_ ))))))))
#define E6(_2_)E5 (E5(E5(E5(E5(E5(E5 (E5( _2_ ))))))))
#define E7(_0_)E6 (E6(E6(E6(E6(E6(E6 (E6( _0_ ))))))))
#define E8(_1_)E7 (E7(E7(E7(E7(E7(E7 (E7( _1_ ))))))))
#define E9(_5_)E8 (E8(E8(E8(E8(E8(E8 (E8( _5_ ))))))))
#define QS( L, R) (S (M( L, B R),\
A R , A J(G(L, _) ,B R), C R ))
#define QR( L, R) I sym_(,)(O, (C, \
C)) (C J(G(L, _) ,B R),QS(L, R ))
#define sym__(_ , __ ) _
#define A(A, B , C ) A
#define F(A, _) sym_(_,)
#define sym_(__ , _ ) _
#define B(A, B , C ) B
#define J(A, J) G(A, J)
#define sym___( ___, __)
#define C(A, B , C ) C
#define G(J, G) J ## G
#define RY(Y) Y
#define Y( Y) Y
#define LY(Y) Y
# define Z( L, R) J (B L, /*N,*/ Y)
# define N( L, R) J (G(L, _), B R)
# define HY(L ) (A L, halting)
# define T( R, L) G(sym_, R)(L, (,))
# define H( R, L) G(sym_, R)(R, _ )
# define M( L, R) B J( G(L, _), R )
# define D( L, R) G(sym_, R)(R, _ )
# define U( L, R) G(sym_, R)(L, (,))
# define F0(L, R) F( L, /*N,*/R )
# define F1(L, R) F0( L, /*N,*/R)~
# define F2(L, R) F1( L, /*N,*\R)~
# define F3(L,*/R )R\t<L[B R]>\t-> \
Z (/*)*/ N( L, R) , R) (N( L, R) )\n
# define FV(L, R) F( L, /*N,*/R )
# define QH(L, R) QS( L, /*N,*/ R)
int puts (char*);
# define W(W)O(W)
int main () {puts
# define O(W)#W//
( R ( A, tape));}
+7
View File
@@ -0,0 +1,7 @@
#define sym_1(sym, _1) sym
#define tape ( (,), /*
15: */ 1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, /*
blank: */ (_, /*
50: */ (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, /*
*/ (,)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) )
+7
View File
@@ -0,0 +1,7 @@
#define sym_1(sym, _1) sym
#define tape ( (,), /*
77: */ 1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1, /*
blank: */ (_, /*
55: */ (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, (1,(1,(1,(1,(1, /*
*/ (,))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) )
+1
View File
@@ -0,0 +1 @@
#define tape ((,), _, (,))
+3
View File
@@ -0,0 +1,3 @@
#define sym_1(sym, _1) sym
#define tape ((,), 1, (1, (1, (1, (1, (,))))))
+262
View File
@@ -0,0 +1,262 @@
| 24th International Obfuscated C Code Contest Official Rules
| Copyright (C) 2006-2015 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.
Obfuscate: tr.v. -cated, -cating, -cates. 1. a. To render obscure.
b. To darken. 2. To confuse: his emotions obfuscated his
judgment. [LLat. obfuscare, to darken : ob(intensive) +
Lat. fuscare, to darken < fuscus, dark.] -obfuscation n.
obfuscatory adj.
| This rules file is version 2015-05-27-v23.
| Most of the changes from the previous IOCCC rules
| been marked with a "|" on the left hand side of the line.
GOALS OF THE CONTEST:
* To write the most Obscure/Obfuscated C program under the rules below.
* To show the importance of programming style, in an ironic way.
* To stress C compilers with unusual code.
* To illustrate some of the subtleties of the C language.
* To provide a safe forum for poor C code. :-)
| This IOCCC runs from:
|
| 2015-Jul-08 09:10:11.12 +/- .13 seconds UTC
| to:
| 2015-Oct-10 10:10:10.10 +/- .10 seconds UTC.
|
| Until the start of this IOCCC, these rules, guidelines and iocccsize.c tool
| should be considered provisional BETA versions and may be adjusted
| at any time.
|
| The IOCCC submission URL:
|
| https://submit.ioccc.org/
|
| will be available and active on or slightly before the start of this IOCCC.
|
| The official rules, guidelines and iocccsize.c tool will be available
| on the official IOCCC web site on or slightly before start of this IOCCC.
| Please check the IOCCC web site "How to enter" link:
|
| http://www.ioccc.org/index.html#enter
|
| on or after the start of this IOCCC to be sure you are using the correct
| versions of these items before using the IOCCC entry submission URL.
RULES:
To help us with the volume of entries, we ask that you follow these rules:
1) Your entry must be a complete program.
2) The size of your program source must be <= 4096 bytes in length.
When your program source is fed as input to the current IOCCC size
tool, and the IOCCC size tool -i command line option is used, the value
| printed shall be less than or equal to 2053.
The source to the current IOCCC size tool is found at this URL:
| http://www.ioccc.org/2015/iocccsize.c
3) Submissions should be performed using the instructions outlined at:
https://submit.ioccc.org/
| That URL should be active on or slightly before 2015-Sep-09 09:09:09 UTC.
4) If your entry is selected as a winner, it will be modified as follows:
Your 'build' instructions will be incorporated into a makefile.
| Your source code will be the file prog.c. The compiled binary
| will be called prog.
5) Your entry must not modify the content or filename of any part of your
original entry including, but not limited to prog.c, the Makefile
(we create from your how to build instructions), as well as any data
files you submit.
If you entry wishes to modify such content, it must first copy the
file to a new filename and then modify that copy.
| 6) I am not a rule, I am a free(void *man)!!
| while (!understand(ioccc(rule(UR(number(6)))))) { laugh(); }
7) The obfuscated C program must be an original work that you own.
You (the authors) must own the contents of your submission OR
you must have permission from the owners to submit their content
under the Creative Commons Attribution-ShareAlike 3.0 Unported
(CC BY-SA 3.0) license (see rule 18).
If you submit any content that is owned by others, you MUST
detail that ownership (i.e., who owns what) and document the
permission you obtained.
| 8) Entries must be received prior to the end if this IOCCC which is:
|
| 2015-Oct-10 10:10:10.10 +/-.10 seconds UTC
| A confirmation of submission will be sent to the submitter
email address before the close of the contest.
| 9) Each person may submit up to and including 8.000 entries per contest.
Each entry must be submitted separately.
10) Entries requiring human interaction to be initially compiled are
not permitted.
11) Programs that require special privileges (setuid, setgid, super-user,
special owner, special group, etc.) are still highly discouraged. We
do not guarantee these functions will behave as you expect on our test
platforms. If your program needs special permissions please document
them in the remarks file.
12) Legal abuse of the rules is somewhat encouraged. An entry that, in
the opinion of the judges, violates the rules will be disqualified.
Entries that attempt to abuse the rules must try to justify why
their rule abuse is legal in the remarks file.
13) Any C source that fails to compile because of unescaped octets with
the high bit set (octet value >= 128) will be rejected.
14) Any C source that fails to compile because of lines with trailing
control-M's (i.e., lines with a tailing octet 015) will be rejected.
| Please do not put trailing control-M's on remarks file lines.
| Please check to be sure, before submitting, that you have removed
| any control-M at the end of remark file lines.
15) When you submit your entry you must have a valid email address
that can both send and receive email. The online submission
method is a two phase process that requires the use of an
approval code. This code will be emailed to you as part of
phase 1.
Entries submitted without a working or valid email address will
be disqualified.
The judges are not responsible for delays in email, please plan
enough time for one automated exchange of email as part of your
submission.
After your email address has been confirmed, the submission code will
be valid for submitting and editing the entry for the lifetime of the
competition.
16) You are STRONGLY encouraged to submit a previously unpublished and
original entry. Submissions that are similar to previous entries are
discouraged. As we judge anonymously, submissions that have already
been published may be disqualified.
17) The total size of your submission: the sum of the size of the program,
hints, comments, build and info files MUST be less than or equal
to 1048576 octets in size.
18) The entirety of your entry must be submitted under the Creative Commons
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0):
http://creativecommons.org/licenses/by-sa/3.0/
You must not submit anything that cannot be submitted under that license.
19) The remarks file must be written in markdown format. See:
http://daringfireball.net/projects/markdown/basics
for more information.
We currently use "Discount" to convert markdown to HTML
http://www.pell.portland.or.us/~orc/Code/discount/
20) The how to build instructions must be in make form.
The target of the make file must be called prog. The original
C source file must be called prog.c.
To invoke the C compiler, use ${CC}.
To invoke the C preprocessor use ${CPP}.
Do not assume that . (the current working directory) is in the $PATH.
Use a shell command syntax that is compatible with bash.
Assume that commands commonly found in POSIX-like / Linux-like systems
are available in the search path.
Do not assume any particular given value of ${CFLAGS} or other
commonly used make variables.
21) Your entry must not create nor modify files above the current directory
with the exception of the /tmp and the /var/tmp directories. Your entry
may create subdirectories below the current directory, or in /tmp,
or in /var/tmp provided that "." is not the first octet in any
directory name.
| 22) Your source code, data files, remarks and program output must NOT
| identify the authors of your code. The judges STRONGLY prefer to
| not know who is submitting entries to the IOCCC.
| The "Peter Honeyman is exempt" guideline also applies to this rule.
| Identifying yourself, in an obvious way in your code, data, remarks
| or program output, unless you are Peter Honeyman or pretending
| to be Peter Honeyman, will be grounds for disqualification of your entry.
| 23) This prime rule number is reserved for future use.
| 24) Even though 24 is not prime, you should still see rule #23.
FOR MORE INFORMATION:
The judging will be done by Leonid A. Broukhis, Simon Cooper, Landon
Curt Noll.
Please send questions or comments about the contest, to:
| q.2015@ioccc.org (for questions only!)
You must include the words:
| ioccc 2015 question
in the subject of your EMail message when sending EMail to the judges.
The rules and the guidelines may (and often do) change from year to
year. You should be sure you have the current rules and guidelines
prior to submitting entries. To obtain them, visit the IOCCC web page:
http://www.ioccc.org
It has rules, guidelines and winners of previous contests (1984 to date).
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/\
+254
View File
@@ -0,0 +1,254 @@
#!/usr/bin/env make
#
# 2015 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
BUNZIP2= bunzip2
LD= ld
MAKE= make
RM= rm
SED= sed
TAR= tar
TRUE= true
MKDIR= mkdir
MV= mv
TR= tr
GREP= grep
SORT= sort
UNIQ= uniq
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Compiler warnings
#
#CWARN=
#CWARN= -Wall
#CWARN= -Wall -Wextra
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
#CWARN= -Wall -Wextra -Weverything
#CWARN= -Wall -Wextra -Weverything -pedantic
#CWARN= -Wall -Wextra -Weverything -pedantic ${CSILENCE}
# Silence warnings that ${CWARN} would normally complain about
#
CSILENCE=
# compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=c11
#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=
# defines that are needed to compile
#
#CDEFINE=
CDEFINE= -Dtyp=uint64_t
# include files that are needed to compile
#
CINCLUDE=
# 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.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
#OPT= -O1
#OPT= -O2
OPT= -O3
# default flags for ANSI C compilation
#
CFLAGS= ${CWARN} ${CSTD} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# Libraries needed to build
#
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= prog
CSRC= ${ENTRY}.c
OBJ= ${ENTRY}.o
DATA=
ALT_OBJ=
ALT_ENTRY=
TARGET= ${ENTRY}
#################
# build the entry
#################
#
all: ${TARGET} ${DATA}
@${TRUE}
${ENTRY}: ${CSRC}
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: ${ALT_ENTRY}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
###############
# utility rules
###############
#
everything: all alt
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_ENTRY}
nuke: clobber
@${TRUE}
dist_clean: nuke
@${TRUE}
install:
@echo "Surely we are joking Dr. May!"
@${TRUE}
# backwards compatibility
#
build: all
@${TRUE}
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
make:
@echo 'Attend a maker faire'
@${TRUE}
easter_egg:
@echo you expected to sometimes mis-understand this $${RANDOM} magic
@echo chongo '<was here>' "/\\oo/\\"
@echo Readers shall not be disallowed from not failing to be unable to not partly misunderstand this particular 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_v5; \
else \
echo "planet deniers, like the IAU, are amusing"; \
fi
@echo A $@ helps ${MAKE} the elements that help form planets
@${TRUE}
deep_magic:
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 2ed3582ec5c094a093fea2a6bcb9f19439892873c9cc45ed1ceaafe08b7d52e1b2c7cd524be3b0b2 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "You are holding it wrong!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --mode 216091 --level 216193 --FNV1a_hash_512_bit "${ENTRY}"; \
else \
echo "These aren't the primes you're looking for Pauline!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: supernova
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
pluto: supernova
${MAKE} charon
@echo $@ is a dwarf planet
@echo dwarf is a type of planet
@echo $@ is a planet
@echo get used to having lots of planets because a $< can ${MAKE} a lot of them
+813
View File
@@ -0,0 +1,813 @@
<!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 Documented</title>
</head>
<body>
<h1>Best Documented</h1>
<p>Jens Schweikhardt<br>
<a href="http://www.schweikhardt.net">http://www.schweikhardt.net</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog n
where n is a base 16 number of any size
</code></pre>
<h3>Try:</h3>
<pre><code>./prog 19
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This code is clean. When you compile with all warnings enabled,
such as with clang:</p>
<p> cc -Weverything -pedantic -std=c11 -Dtyp=uint64_t -O3 prog.c -o prog</p>
<p>The code compiles without warnings on the systems that we tested!</p>
<p>Even more, the code was 100% clean when we ran it against various
static source checkers.</p>
<p>This tool references a problem that David I. Bell once described
as having one of the largest &ldquo;yummo quotients&rdquo; in number theory:</p>
<pre><code> complexity of the solution
yummo quotient = -----------------------------------
complexity of the problem statement
</code></pre>
<p>Erdős privately told one of the IOCCC judges:</p>
<p>&ldquo;Solving the <a href="https://en.wikipedia.org/wiki/Generalized_Riemann_hypothesis#Extended_Riemann_hypothesis_.28ERH.29">Generalized Riemann hypothesis</a>
would be a good warmup exercise for someone to get ready
to begin to work on the <a href="https://en.wikipedia.org/wiki/Collatz_conjecture">Collatz conjecture</a>.&rdquo;</p>
<p>You may explore this famous conjecture using this entry:</p>
<pre><code>./prog 2410
./prog abfff
./prog 27f8cebf
./prog 246f8fddf
./prog 2e95ab51ffea9de
./prog e6a5c22fd7bde9f
./prog 1b7dd73a937485bf
./prog 7d3237680d190a77e53751b
./prog 302ab3d052fb87c06228d249581be0e4
</code></pre>
<p>When you first look at the source, the code looks fairly straightforward.
But look again. Like the Collatz conjecture, simplicity is deceptive!
Oh, and the variable names? They are not simple single letter variables,
they are names of various <a href="https://en.wikipedia.org/wiki/Proteinogenic_amino_acid">Proteinogenic amino
acid</a>:
which is yet another simple building block that can be used to
build some very complex structures. :-)</p>
<p>p.s. We appreciated that apart from a few powers of 2, the source
code is magic number free.</p>
<h2>Author&rsquo;s comments:</h2>
<h2>The TL;DR version</h2>
<p>This is the cleanest program ever submitted. If for some input it enters
a non-terminating loop or runs out of memory you will be insta-famous.
It&rsquo;s a bit like a lottery without the need to buy a ticket and you can
play as often as you like. One notable historic person has even offered
some prize money.</p>
<p>The program illustrates the bloat caused by adherence to too many rules,
each of which may sound sane in isolation, but in their entirety lead to
an obfuscated, hard to read and understand monster.</p>
<h2>What this program does.</h2>
<p>The program tests whether a given natural number satisfies the
<a href="https://en.wikipedia.org/wiki/Collatz_conjecture">Collatz Conjecture</a>:</p>
<p>Take any natural number <em>n</em>. If <em>n</em> is even, divide it by 2 to get <em>n</em>/2.
If <em>n</em> is odd, multiply it by 3 and add 1 to obtain 3<em>n</em> + 1.
Repeat the process indefinitely.
The conjecture is that no matter what number you start with,
you eventually reach 1.</p>
<p>Paul Erdős said about the Collatz conjecture:
&ldquo;Mathematics may not be ready for such problems.&rdquo;
He also offered $500 for its solution.</p>
<p>For example, the sequence of numbers for <em>n</em> = 6 is</p>
<blockquote><p> 6, 3, 10, 5, 16, 8, 4, 2, 1.</p></blockquote>
<p>Continuing past one leads to the <em>cycle</em> 1, 4, 2, 1, 4, 2, 1, &hellip;
Interesting factoid: if you allow <em>negative</em> start values, there are
a few more cycles, each of different length:</p>
<blockquote><p> −1, −2, −1</p>
<p> −5, −14, −7, −20, −10, −5</p>
<p> −17, −50, −25, −74, −37, −110, −55, −164, −82, −41, −122, −61, −182, −91, −272, −136, −68, −34, −17</p></blockquote>
<p>The program computes the sequence for a given positive natural number
and stops at 1. The number <em>n</em> is specified in hexadecimal (without 0x
prefix) as the first argument. The program prints the given number in
zero-padded hex and each iteration along with a line count in decimal.
The example above looks like this (compiled with 64 bit word size):</p>
<pre><code>$ ./prog 6
0000000000000006
0000000000000003 1
000000000000000A 2
0000000000000005 3
0000000000000010 4
0000000000000008 5
0000000000000004 6
0000000000000002 7
0000000000000001 8
</code></pre>
<p>The size of <em>n</em> is only limited by the argument size limit of your
shell/OS (the program implements arbitrary size bignums).
To query this on your POSIX system, run</p>
<pre><code>$ getconf ARG_MAX
262144
</code></pre>
<p>which reports the limit in bytes, here 256KB. This allows to test
whether a <a href="https://en.wikipedia.org/wiki/Googol">Googol</a>, which is
10<sup>100</sup>, satisfies the conjecture. But what is a googol in hex?
Fear not,
<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html">bc(1)</a>
to the rescue:</p>
<pre><code>$ printf 'obase=16;10^100\n' | bc
1249AD2594C37CEB0B2784C4CE0BF38ACE408E211A7CAAB24308A82E8F1000000000\
0000000000000000
$ ./prog 1249AD2594C37CEB0B2784C4CE0BF38ACE408E211A7CAAB24308A82E8F10000000000000000000000000 \
| less
[...]
</code></pre>
<p>Observe how the first 100 iterations melt the zeros to the right. Can you explain
why?</p>
<p>For a given <em>n</em> the program behavior is one of the following 3:</p>
<ol>
<li>The sequence stops at 1. No fame. No money. Thanks for playing. Computational
mathematicians have tested all <em>n</em> &lt; 4FFDD776055A0000 (~10<sup>18</sup>)
so don&rsquo;t try anything less than that.</li>
<li>The chosen <em>n</em> leads to a sequence with ever bigger numbers,
so that eventually the bignum cannot be stored in memory. If this happens,
the program outputs <code>laugh</code> (more likely) or <code>throw up</code> (less likely) and
stops. You <em>might</em> have found
a number for which the sequence <em>diverges</em>. If confirmed, this disproves the
conjecture.</li>
<li>The chosen <em>n</em> leads to a cycle not including 1 (i.e. runs forever,
repeating the same sequence over and over). You have disproved the
conjecture and should certainly submit a paper to the nearest
mathematical journal.</li>
</ol>
<h2>Design objectives</h2>
<p>I gave myself the following objectives. Like in real world programming,
not all of them can be met 100%. Think of them as a multidimensional
continuum, where trade-offs have to be made.</p>
<ol>
<li>No arbitrary limits on the input number. 64 bits might be enough
for everybody, but is not enough for exploring new Collatz-territory.
Thus bignums are required.</li>
<li>Ultra-portable. Must run on C89 systems and self-adapt to C99 and C11
features like exact width types.</li>
<li>Super-efficient. Must be able to run with the widest type as the
base of the bignums. Make the user select the widest type supported
by the implementation and then crunch away. If a non-standard
128bit type is available, it should be usable.</li>
<li>Pentagon level lint cleanliness and MISRA compliance.</li>
<li>Easy to understand, self-documenting clear code. A joy for maintenance
programmers. The epitome of best practice demonstration for all
future textbooks on C.</li>
</ol>
<h1>Program Obfuscation</h1>
<p>In the following I address all the <em>tests</em> as specified by your honors in the
<em>guidelines</em>.</p>
<ul>
<li>look at the original source</li>
<li>convert ANSI tri-graphs to ASCII</li>
<li>C pre-process the source ignoring <code>#include</code> lines</li>
<li>C pre-process the source ignoring <code>#define</code> and <code>#include</code> lines</li>
<li>run it through a C beautifier</li>
<li>examine the algorithm</li>
<li>compile it (with flags to enable all warnings)</li>
<li>execute it</li>
</ul>
<h2>Look at the original source</h2>
<p>Using one letter identifiers is quite old. I decided to use TLI (three
letter identifiers). Not the random kind, rather with a connection to
the meaning of life, the universe and the rest. Enter amino acids! Among
the myriad of possible amino acids there are 23 from which proteins are
built. In biochemistry, each is assigned a TLI (see <a href="https://en.wikipedia.org/wiki/Proteinogenic_amino_acid">Proteinogenic amino
acid</a>):</p>
<pre><code>ala Alanine
cys Cysteine
asp Aspartic acid
glu Glutamic acid
phe Phenylalanine
gly Glycine
his Histidine
ile Isoleucine
lys Lysine
leu Leucine
met Methionine
asn Asparagine
pyl Pyrrolysine
pro Proline
gln Glutamine
arg Arginine
ser Serine
thr Threonine
sec Selenocysteine
val Valine
trp Tryptophan
tyr Tyrosine
asx Asparagine or Aspartic acid
glx Glutamic acid or Glutamine
xle Leucine or Isoleucine
unk Unknown
</code></pre>
<p>My own research results complete this list (not yet in Wikipedia due to
the rule &ldquo;<a href="https://en.wikipedia.org/wiki/Wikipedia:No_original_research">No original
research</a>&rdquo;):</p>
<pre><code>and Androgynine
xor Xenoricine
not Notanamine
tla Triletramine
</code></pre>
<p>Interestingly, the TLI are the perfect mnemonics for C language source.
For example, <code>met</code> is &ldquo;Main&rsquo;s Exit Type&rdquo; (<code>int</code>), <code>ala</code> is &ldquo;A Large
Algebraic&rdquo; (bignum), <code>ile</code> an &ldquo;Incremented Local Entity&rdquo; (index
counter), <code>gly</code> means &ldquo;Grow Larger memorY&rdquo;, <code>gln</code> is &ldquo;Grown Larger Now&rdquo;
(after realloc), <code>not</code> is a &ldquo;Not Overflowing Type&rdquo; (recursive!), <code>unk</code>
is the &ldquo;UNit (Known as 1)&rdquo;, <code>trp</code> is the &ldquo;Tabula Rasa Product&rdquo; (zero),
<code>phe</code> is &ldquo;Print HEx&rdquo; and so on.</p>
<h2>Convert ANSI tri-graphs to ASCII</h2>
<p>Huh??!</p>
<h2>C pre-process the source ignoring &lsquo;#include&rsquo; lines</h2>
<p>Wow, an identity operation (except for the <code>&lt;stdint.h&gt;</code> and <code>EOF + __STDC__</code>
trivialities). Did you gain any insight through this?</p>
<h2>C pre-process the source ignoring &lsquo;#define&rsquo; and &lsquo;#include&rsquo; lines</h2>
<p><code>#define</code>? Which <code>#define</code> directives? How many 4K source files do you
see that neither use a single <code>#define</code> directive <em>nor</em> abuse the build
file? Even though the &ldquo;no <code>#define</code>&rdquo; rule I submitted myself to made it
hard, I could use <code>__LINE__</code> and stdio macros <code>EOF</code>, <code>L_tmpnam</code>,
<code>BUFSIZ</code>, <code>FILENAME_MAX</code>, <code>TMP_MAX</code> to obfuscate at least something.</p>
<h2>Run it through a C beautifier</h2>
<p>Another identity operation. I&rsquo;ve done it for you already. Use this
<code>.indent.pro</code> with FreeBSD indent:</p>
<pre><code>$ cat .indent.pro
-bad /* blank line after decls */
-bap /* blank line after functions */
-br /* braces on if line */
-i8 /* indent */
-l999 /* line length */
-npcs /* no space after function call names */
-npsl /* don't break procedure type */
-ut /* use tabs */
-ce /* cuddle else */
-nip /* no parameter indentation */
-di1 /* declaration indent */
-Tand
-Tmet
-Tthr
-Tpro
-Tser
-Tala
</code></pre>
<p>It looks like a perfect program should:</p>
<ul>
<li> two and a half <code>#includes</code> of unsuspicious standard headers</li>
<li> followed by self protection against goofy implementations</li>
<li> followed by a handful of <code>typedef</code>s</li>
<li> and a pair of file scope objects by necessity</li>
<li> prototypes! With parameter names! <code>static</code> for internal linkage even! This <strong>must</strong> be a first in IOCCC history.</li>
<li> function definitions, <code>main</code> last</li>
<li> everything is fully const-poisoned: automatics, statics, arguments, even <code>main</code></li>
<li> everything is fully curly braced, even single statements</li>
<li> plenty of meaningful TLC (Three Letter Comments)</li>
</ul>
<p>The program contains not a single <em>magic number</em> (only 0 and powers of
2, each power from 1 to 512) which are obvious to competent software
engineers). How many programs have <em>that</em> property? The check for
<code>__STDC_VERSION__</code> was a bit tough to arrive at, since 199901L has too
many bits set. But I realized that I only needed a number larger than
199409 and less than 199901. 199680 has only 4 bits set and writing it
as (256 + 128 + 4 + 2) * 512 minimizes the character count. That&rsquo;s what
judges get when they don&rsquo;t like programs that are longer than they need
to be.</p>
<h2>Examine the algorithm</h2>
<p>Spoilers ahead. Duh!</p>
<p>Pseudocode, with comments matching those in the C source:</p>
<pre><code>/* run */
if (non-NULL and nonempty argv[1]) {
n = convert(argv[1])
print n /* 2hx */
while (n != 1) { /* one */
if (n is odd) { /* odd */
m = deep copy of n /* cpy */
n &lt;&lt;= 1 /* shl */
n += m /* add */
increment n /* inc */
} else { /* eve */
n &gt;&gt;= 1 /* shr */
}
print n /* 2hx */
}
}
</code></pre>
<p>Bignums are represented as the two member structs</p>
<pre><code>typedef struct {
size_t places; /* number of places in base 2&lt;sup&gt;8*sizeof(type)&lt;/sup&gt; */
type *number; /* dynamically allocated memory for number */
} bignum
</code></pre>
<h2>Compile it (with flags to enable all warnings)</h2>
<p>Here&rsquo;s where the program shines brighter than a <a href="https://en.wikipedia.org/wiki/Gamma-ray_burst">gamma-ray
burst</a>!</p>
<p>I challenge you to throw all kinds of compilers, lints, checkers and
analyzers at my program and make it find the slightest of issues.</p>
<p>Is <code>clang -Wall -Wextra -Weverything -Dtyp=uint32_t prog.c</code> all you can
do? Clang has implemented a new warning? Bring it on!</p>
<h2>Execute it</h2>
<p>May you win the jackpot!</p>
<p>For least surprising results, the execution character set should be
ASCII. The program computes four bits from every character in <code>argv[1]</code> and
interprets them as a hex digit. On ASCII the characters a-f, A-F and 0-9
are converted as expected.</p>
<p>This means however, that the program accepts <strong>any string</strong>, turns it
into a starting number (which is output as the first line), and starts
crunching. Nothing stops you from executing</p>
<pre><code>$ ./prog "$(cat prog.c)" # Kind of quine?
$ ./prog "$(cat rules guidelines)" # A jackpot? Maybe next year...
$ ./prog "$(cat /bin/ls)" # Number cut short at first NUL byte.
</code></pre>
<p>In a certain way, the program is character set and encoding agnostic.</p>
<h2>Assumptions made</h2>
<ul>
<li>The <code>EOF</code> macro from <code>&lt;stdio.h&gt;</code> must expand to negative one since it is used
to decrement a pointer and do some other math.
None of the tools catches this one. The program self-protects against unusual
systems with <code>#if EOF + __STDC__</code> followed by <code>#error goofy!</code>. In the rare event
your system is goofy, replace all <code>EOF</code> tokens with <code>(-1)</code> and remove the
<code>#error</code> directive.</li>
</ul>
<p>While the program works best when bytes/characters are octets and the
number of bits in a type is <code>sizeof(typ) &lt;&lt; 3</code>, it will work correctly
on 24bit or 36bit systems with 9 bits/byte, or systems where
<code>sizeof(typ)</code> is 1 even for <code>int</code> and so on. On such systems, it will only
use 8 * <code>sizeof(typ)</code> bits per place. It does not work when <code>CHAR_BIT &lt;= 7</code>.</p>
<h2>Results of various checkers</h2>
<h3>cppcheck</h3>
<p>The open source static checker <a href="http://cppcheck.sourceforge.net/">cppcheck</a>
checks various problems with respect to style, performance, portability
and general fishiness. To enable all checks, run</p>
<pre><code>$ cppcheck --enable=all --force -I/usr/include -Dtyp=uint32_t prog.c
</code></pre>
<p>No issues found.</p>
<h3>flawfinder</h3>
<p>The open source static checker <a href="http://www.dwheeler.com/flawfinder/">flawfinder</a>
checks various problems with respect to security like buffer overflows,
function arguments to known troublemaker functions and more. It doesn&rsquo;t need to
pre-process code, so can be run without the <code>typ</code> macro being defined:</p>
<pre><code>$ flawfinder prog.c
Flawfinder version 1.31, (C) 2001-2014 David A. Wheeler.
Number of rules (primarily dangerous function names) in C/C++ ruleset: 169
Examining prog.c
FINAL RESULTS:
ANALYSIS SUMMARY:
No hits found.
$
</code></pre>
<h3>valgrind</h3>
<p>The open source dynamic checker <a href="http://valgrind.org/">valgrind</a>
runs an executable and verifies all memory accesses and (de)allocations for
proper bounds and memory leaks.
Since the program frees all memory in all possible execution paths, even when
it must bail out,
valgrind should be happy. An early version of my program however reported this:</p>
<pre><code>$ valgrind --leak-check=full --show-leak-kinds=all ./prog 6
[...]
==14615== HEAP SUMMARY:
==14615== in use at exit: 4,096 bytes in 1 blocks
==14615== total heap usage: 4 allocs, 3 frees, 4,108 bytes allocated
==14615==
==14615== 4,096 bytes in 1 blocks are still reachable in loss record 1 of 1
==14615== at 0x4C236C0: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==14615== by 0x4F62175: ??? (in /lib/libc.so.7)
==14615== by 0x4F62073: ??? (in /lib/libc.so.7)
==14615== by 0x4F514EE: ??? (in /lib/libc.so.7)
==14615== by 0x4F51265: vfprintf_l (in /lib/libc.so.7)
==14615== by 0x4F3E001: printf (in /lib/libc.so.7)
==14615== by 0x40101E: phe (in ./prog)
==14615== by 0x400A9F: main (in ./prog)
==14615==
==14615== LEAK SUMMARY:
==14615== definitely lost: 0 bytes in 0 blocks
==14615== indirectly lost: 0 bytes in 0 blocks
==14615== possibly lost: 0 bytes in 0 blocks
==14615== still reachable: 4,096 bytes in 1 blocks
==14615== suppressed: 0 bytes in 0 blocks
==14615==
==14615== For counts of detected and suppressed errors, rerun with: -v
==14615== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
</code></pre>
<p>From which I concluded that <code>printf</code> allocated a single 4K block for
which no matching free existed. But how to free memory allocated deep
down in the guts of the Standard I/O library? After some serious head
scratching it hit me. The only chance I have is telling the system I no
longer want to do I/O, maybe then it would free that buffer. A reading
of C99 7.19.5.1, &ldquo;The fclose function&rdquo;, was encouraging:</p>
<blockquote><p> Whether or not the call succeeds, the stream is disassociated from the file
and any buffer set by the <code>setbuf</code> or <code>setvbuf</code> function is disassociated from the stream
(and deallocated if it was automatically allocated).</p></blockquote>
<p>So I <code>fclose(stdout)</code> before returning and now:</p>
<pre><code>$ valgrind --leak-check=full --show-leak-kinds=all ./prog 6
==14571== Memcheck, a memory error detector
==14571== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14571== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==14571== Command: ./prog 6
==14571==
0000000000000006
0000000000000003 1
000000000000000A 2
0000000000000005 3
0000000000000010 4
0000000000000008 5
0000000000000004 6
0000000000000002 7
0000000000000001 8
==14571==
==14571== HEAP SUMMARY:
==14571== in use at exit: 0 bytes in 0 blocks
==14571== total heap usage: 4 allocs, 4 frees, 4,120 bytes allocated
==14571==
==14571== All heap blocks were freed -- no leaks are possible
==14571==
==14571== For counts of detected and suppressed errors, rerun with: -v
==14571== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
</code></pre>
<p>A squeaky clean valgrind result!</p>
<h3>FlexeLint</h3>
<p>FlexeLint is a commercial lint tool by <a href="http://www.gimpel.com/html/index.htm">Gimpel
Software</a>. It supports nearly a
thousand checks, broadly categorized into 4 levels,</p>
<ol>
<li> Syntax errors only (messages 1 to 399)</li>
<li> Warnings (messages 400 to 699)</li>
<li> Informational messages (700 to 899)</li>
<li> Elective notes (900 to 1000 and > 9000)</li>
</ol>
<p>There is an <a href="http://www.gimpel-online.com/OnlineTesting.html">on-line
demonstrator</a> you can
use for checking your C programs and I highly recommend trying it. For a start,
paste the well know first program in the form and press &ldquo;Analyze Code&rdquo;. Note
the FlexeLint configuration options in comments (no space between <code>/*</code> and <code>lint</code>).</p>
<pre><code>/*lint -w4 turn on everything */
/*lint +esym(534,*) no demonstrator defaults */
/*lint -e966 indirectly included header file not used */
/*lint -esym(9058,_*) tag not used outside typedef */
/*lint -misra(2) */
#include &lt;stdio.h&gt;
int main(void)
{
printf("hello, world\n");
return 0;
}
</code></pre>
<p>Possible checks include those for MISRA 2004 compliance verification.
The <a href="https://en.wikipedia.org/wiki/Motor_Industry_Software_Reliability_Association">Motor Industry Software Reliability
Association</a>
has produced a <a href="http://doc.hcc-embedded.com/display/CODING/MISRA+Rules">list of 121 required and 20 advisory
rules</a> for C
programming. I am proud to report that my program fulfills <em>almost all</em>
rules. To assess the few exceptions, one has to understand that MISRA
rules are geared towards embedded systems used in the automotive
industry. That&rsquo;s why features like <code>malloc</code> and <code>printf</code> are right out.
But that&rsquo;s too restrictive for an IOCCC hosted application, so I ignored
these:</p>
<ul>
<li>17.1 Pointer arithmetic shall only be applied to pointers that address an array or array element.</li>
<li>17.4 Array indexing shall be the only allowed form of pointer arithmetic.</li>
<li>20.4 Dynamic heap memory allocation shall not be used.</li>
<li>20.9 The input/output library stdio.h shall not be used in production code.</li>
<li>20.11 The functions abort, exit, getenv, and system from the library stdlib.h shall not be used.</li>
</ul>
<p>I started out with enabling <em>all</em> messages using FlexeLint&rsquo;s <code>-w4</code>
option and disabling all noise from system headers. Then I dealt with
the remaining messages by addressing them or suppressing them in such a way
that the set of suppressions was minimal. At the end of the day, this is
what remained:</p>
<pre><code>// === Tested with FlexeLint 9.00L on FreeBSD 11 ===
// Compiler:
// "4.2.1 Compatible FreeBSD Clang 3.6.1 (tags/RELEASE_361/final 237755)"
-w4 // Enable maximum pickiness
-passes(6) // Recommended in FlexeLint manual for torture testing
+fsc // Make string literals have type const char*
+fnr // ptr-returning functions may return NULL
-strong(AJX,and,pro,ser,ala) // strong types
-strong(AcJcm,thr) // thr is strong, but most arithmetic is okay
-strong(AarJemorX,met) // met is strong, but some use is okay
+libclass(angle) // All &lt;headers&gt; are system headers
-wlib(1) // Only errors for system headers
-i/usr/include // System headers
-i/usr/local/lib/supp/ansi // Comes with FlexeLint
-d__GNUC__=4 // Pretend...
-d__GNUC_MINOR__=2 // I'm...
-d__GNUC_PATCHLEVEL__=1 // someone else.
-d__builtin_va_list=char* // Fake this compiler extension
-d__inline= // Delete this compiler extension
-d__attribute__(x)= // Delete this compiler extension
+e900 // Announce number of messages produced
// MISRA 2004 checking
/usr/local/lib/supp/lnt/au-misra2.lnt // Enable all MISRA checking
-elib(960) // Don't check FreeBSD system headers for required rules
-elib(961) // Don't check FreeBSD system headers for advisory rules
-e829 // stdio.h used
-e522 // MISRA 14.2 Highest operation, lacks side-effects
-esym(960,17.4) // pointer arithmetic other than array indexing used
-e971 // char without signed/unsigned
-e974 // stack usage report
// Use verboten functions, Req. Rules 20.4 malloc() et al., 20.11, exit()
-esym(586,malloc,realloc,calloc,free,exit)
-e911 // implicit promotion of smaller than int to int
-e921 // cast from integral to integral
-e925 // cast from pointer to pointer
-e958 // padding required in struct
+e9??? // Enable all 9xxx informational messages, except:
-e9079 // conversion from pointer to void to pointer to other type
-e9087 // cast performed between a pointer to object type and a
// pointer to a different object type
-e9141 // global declaration of symbol
// Messages due to code in FreeBSD headers.
//
-dlint // The "lint" macro is tested in x86/_types.h
-elib(537) // Repeated include file
-e793 // external identifiers &gt; 6 chars
-e935 // (unsigned) int within struct (actually the size_t)
-estring(960,_*) // Could be defined at block scope
-e964 // Header file not directly used
-e966 // Indirectly included header file not used
-elib(970) // int outside typedef
-esym(9003,_*) // could be defined at block scope
-elib(9047) // FILE pointer dereferenced
-esym(9058,__*) // tag not used outside typedef
-e9092 // NULL does not expand to a pointer (but plain 0)
</code></pre>
<h2>Compulsory obfuscations</h2>
<p>Which of the rules cause which obfuscation?</p>
<p>MISRA 6.1, &ldquo;The plain char type shall be used only for the storage and
use of character values.&rdquo; This forbids using character constants in
expressions other than assignments to <code>char</code> objects. A consequence is
that printing digits with <code>'0' + digit</code> is not allowed (even though
<code>'0'</code> is technically an <code>int</code>!) so I am forced to output hex digits with</p>
<pre><code>printf("%c", (met)tyr + 32 + 16 + ((8 + EOF) * ((met)tyr / (8 + 2))));
</code></pre>
<p>because of the &ldquo;no magic numbers other than powers of two&rdquo; rule. How is this
an improvement over <code>printf("%c", '0' + tyr + 7 * (tyr / 10)</code>, MISRA?</p>
<p>MISRA 6.3 &ldquo;typedefs that indicate size and signedness should be used in
place of the basic types.&rdquo; Well, if you can&rsquo;t infer the size and
signedness from <code>typedef int met</code>, you&rsquo;re not a real C programmer.</p>
<p>MISRA 10.5, &ldquo;If the bitwise operators <code>~</code> and <code>&lt;&lt;</code> are applied to an
operand of underlying type <code>unsigned char</code> or <code>unsigned short</code>, the
result shall be immediately cast to the underlying type of the operand.&rdquo;
Because the program must work for any unsigned type chosen for the <code>typ</code>
macro, including the narrow types enumerated in the rule, a lot of
redundant casting ensues. It gets worse with the next rule&hellip;</p>
<p>MISRA 12.1, &ldquo;Limited dependence should be placed on the C operator
precedence rules in expressions.&rdquo; This requires parentheses for almost
all expressions involving more than one operator, especially those for which
a cast is required, leading to hard to understand expressions such as</p>
<pre><code>const ser glx = (ser)((asx &gt; (ser)64u) ? (ser)((ser)asx + (ser)8u + (ser)1u) : (ser)asx);
not.not[leu] = (and)((and)not.not[leu] | (and)(((and)glx % (and)16u) &lt;&lt; (and)lys));
</code></pre>
<p>MISRA 14.7, &ldquo;A function shall have a single point of exit at the end of
the function.&rdquo; Sigh. Since I must use eloquent prototypes (8.1, 16.3,
16.4) and static functions (8.10, 8.11), I can only use a few functions.
Everything usually written with an early <code>return</code> now cause <em>another
useless indent level</em>. The first three <code>if</code> statements in <code>main</code> cause a
silly 24 character indent. The maximum indent is forced to 8, which is way
too high for a sane function.</p>
<p>MISRA 16.10, &ldquo;If a function returns error information, then that error
information shall be tested.&rdquo; A cast to void would draw a lint warning, so
I use the <code>printf</code> result in expressions,</p>
<pre><code>lys -= 4 * printf("%c", (met)tyr + 32 + 16 + ((8 + EOF) * ((met)tyr / (8 + 2))));
val += printf("\n") / ((__LINE__ * L_tmpnam) + TMP_MAX);
val -= (printf(" %d\n", val) &gt; BUFSIZ) ? FILENAME_MAX : EOF;
</code></pre>
<p>which are, in the absence of errors, equivalent to</p>
<pre><code>lys -= 4;
/*nop*/
++val;
</code></pre>
<p>MISRA 13.1, &ldquo;Assignment operators shall not be used in expressions that
yield a Boolean value.&rdquo; Forbids the idiomatic <code>if ((p = malloc(n)) ==
NULL)</code> and requires separate statements, in other words, bloat.</p>
<p>MISRA 16.7, &ldquo;A pointer parameter in a function prototype should be
declared as pointer to const if the pointer is not used to modify the
addressed object.&rdquo; in conjunction with lint&rsquo;s &ldquo;Note 952: Parameter could
be declared const&rdquo; causes const-poisoning for all functions,</p>
<pre><code>static void phe(const ala not);
static void gly(ala *const not, const and his);
met main(met val, const pro *const his[]);
</code></pre>
<p>and quite a number of automatic variables.</p>
<h3>Why the &ldquo;laugh&rdquo; and &ldquo;throw up&rdquo; messages?</h3>
<p>The guidelines state &ldquo;We like programs that: make us laugh and/or throw
up :-) (humor really helps!)&rdquo;</p>
<h3>If you have a 128 bit type</h3>
<p>If your compiler supports a 128 bit wide type (e.g. clang, gcc) then
you can use it via the <code>typ</code> macro:</p>
<pre><code>clang -Dtyp=__uint128_t -o prog prog.c
</code></pre>
<p>Indeed, the program can use (and lints clean for) all of</p>
<pre><code>clang -Dtyp=uint8_t -o prog8 prog.c
clang -Dtyp=uint16_t -o prog16 prog.c
clang -Dtyp=uint32_t -o prog32 prog.c
clang -Dtyp=uint64_t -o prog64 prog.c
clang -std=c89 -Dtyp="unsigned long" -o prog89 prog.c
</code></pre>
<p>This works because the program has no need for corresponding <code>SCN</code> or
<code>PRI</code> macros to do the scanning and printing of variables of these
types. With a 128 bit type the program can represent numbers up to
340282366920938463463374607431768211457 (3.4 * 10<sup>39</sup>) as a
single &ldquo;place&rdquo;, enough to explore yet untested numbers for the rest of
your life.</p>
<h3>How big a number can I test with 4 GB of RAM?</h3>
<p>The number of hex digits in the start number is limited by <code>ARG_MAX</code>,
probably minus some overhead for the environment variables (use
<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/env.html"><code>env</code>(1)</a>
to trim your environment). In bits this leaves you with 2<sup>4 *
ARG_MAX</sup>.</p>
<p>The algorithm requires two bignums in memory for addition.
If you hit a divergent number, this will cause out-of-memory (&ldquo;laugh&rdquo;)
somewhere near 2<sup>16,000,000,000</sup> (4GB/2 * 8bits/byte).
Sadly, I don&rsquo;t have a test case :-)</p>
<p>How long would it take to overflow the <em>Not Overflowing Type</em>? Lets
assume we&rsquo;re processing 2GB numbers. The program copies, shifts by one,
adds and increments 2GB long bit strings, each time completely thrashing
the data cache &ndash; at <em>all</em> levels. We have a fast machine that can do an
iteration in one second, on average. To make things easy, we round up
3<em>n</em> + 1 to 4<em>n</em>, and assume we never need to divide by two (which is
quite optimistic). Then each iteration shifts left by 2. This would take
8 billion seconds, or about 250 years. If you want to get famous, you
better <em>remove</em> some of the RAM, use an ancient box, or reduce available
memory resources with the ulimit(1) built-in of your shell.</p>
<p>For all intents and purposes, the <em>Not Overflowing Type</em> keeps the promise!</p>
<hr />
<!--
(c) Copyright 1984-2016, [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-2016,
<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>
+771
View File
@@ -0,0 +1,771 @@
# Best Documented
Jens Schweikhardt
<http://www.schweikhardt.net>
## Judges' comments:
### To use:
make
./prog n
where n is a base 16 number of any size
### Try:
./prog 19
### Selected Judges Remarks:
This code is clean. When you compile with all warnings enabled,
such as with clang:
cc -Weverything -pedantic -std=c11 -Dtyp=uint64\_t -O3 prog.c -o prog
The code compiles without warnings on the systems that we tested!
Even more, the code was 100% clean when we ran it against various
static source checkers.
This tool references a problem that David I. Bell once described
as having one of the largest "yummo quotients" in number theory:
complexity of the solution
yummo quotient = -----------------------------------
complexity of the problem statement
Erdős privately told one of the IOCCC judges:
"Solving the [Generalized Riemann hypothesis](https://en.wikipedia.org/wiki/Generalized_Riemann_hypothesis#Extended_Riemann_hypothesis_.28ERH.29)
would be a good warmup exercise for someone to get ready
to begin to work on the [Collatz conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture)."
You may explore this famous conjecture using this entry:
./prog 2410
./prog abfff
./prog 27f8cebf
./prog 246f8fddf
./prog 2e95ab51ffea9de
./prog e6a5c22fd7bde9f
./prog 1b7dd73a937485bf
./prog 7d3237680d190a77e53751b
./prog 302ab3d052fb87c06228d249581be0e4
When you first look at the source, the code looks fairly straightforward.
But look again. Like the Collatz conjecture, simplicity is deceptive!
Oh, and the variable names? They are not simple single letter variables,
they are names of various [Proteinogenic amino
acid](https://en.wikipedia.org/wiki/Proteinogenic_amino_acid):
which is yet another simple building block that can be used to
build some very complex structures. :-)
p.s. We appreciated that apart from a few powers of 2, the source
code is magic number free.
## Author's comments:
The TL;DR version
-----------------
This is the cleanest program ever submitted. If for some input it enters
a non-terminating loop or runs out of memory you will be insta-famous.
It's a bit like a lottery without the need to buy a ticket and you can
play as often as you like. One notable historic person has even offered
some prize money.
The program illustrates the bloat caused by adherence to too many rules,
each of which may sound sane in isolation, but in their entirety lead to
an obfuscated, hard to read and understand monster.
What this program does.
-----------------------
The program tests whether a given natural number satisfies the
[Collatz Conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture):
Take any natural number *n*. If *n* is even, divide it by 2 to get *n*/2.
If *n* is odd, multiply it by 3 and add 1 to obtain 3*n* + 1.
Repeat the process indefinitely.
The conjecture is that no matter what number you start with,
you eventually reach 1.
Paul Erdős said about the Collatz conjecture:
"Mathematics may not be ready for such problems."
He also offered $500 for its solution.
For example, the sequence of numbers for *n* = 6 is
> 6, 3, 10, 5, 16, 8, 4, 2, 1.
Continuing past one leads to the *cycle* 1, 4, 2, 1, 4, 2, 1, ...
Interesting factoid: if you allow *negative* start values, there are
a few more cycles, each of different length:
> −1, −2, −1
>
> −5, −14, −7, −20, −10, −5
>
> −17, −50, −25, −74, −37, −110, −55, −164, −82, −41, −122, −61, −182, −91, −272, −136, −68, −34, −17
The program computes the sequence for a given positive natural number
and stops at 1. The number *n* is specified in hexadecimal (without 0x
prefix) as the first argument. The program prints the given number in
zero-padded hex and each iteration along with a line count in decimal.
The example above looks like this (compiled with 64 bit word size):
$ ./prog 6
0000000000000006
0000000000000003 1
000000000000000A 2
0000000000000005 3
0000000000000010 4
0000000000000008 5
0000000000000004 6
0000000000000002 7
0000000000000001 8
The size of *n* is only limited by the argument size limit of your
shell/OS (the program implements arbitrary size bignums).
To query this on your POSIX system, run
$ getconf ARG_MAX
262144
which reports the limit in bytes, here 256KB. This allows to test
whether a [Googol](https://en.wikipedia.org/wiki/Googol), which is
10<sup>100</sup>, satisfies the conjecture. But what is a googol in hex?
Fear not,
[bc(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
to the rescue:
$ printf 'obase=16;10^100\n' | bc
1249AD2594C37CEB0B2784C4CE0BF38ACE408E211A7CAAB24308A82E8F1000000000\
0000000000000000
$ ./prog 1249AD2594C37CEB0B2784C4CE0BF38ACE408E211A7CAAB24308A82E8F10000000000000000000000000 \
| less
[...]
Observe how the first 100 iterations melt the zeros to the right. Can you explain
why?
For a given *n* the program behavior is one of the following 3:
1. The sequence stops at 1. No fame. No money. Thanks for playing. Computational
mathematicians have tested all *n* < 4FFDD776055A0000 (~10<sup>18</sup>)
so don't try anything less than that.
2. The chosen *n* leads to a sequence with ever bigger numbers,
so that eventually the bignum cannot be stored in memory. If this happens,
the program outputs `laugh` (more likely) or `throw up` (less likely) and
stops. You *might* have found
a number for which the sequence *diverges*. If confirmed, this disproves the
conjecture.
3. The chosen *n* leads to a cycle not including 1 (i.e. runs forever,
repeating the same sequence over and over). You have disproved the
conjecture and should certainly submit a paper to the nearest
mathematical journal.
Design objectives
-----------------
I gave myself the following objectives. Like in real world programming,
not all of them can be met 100%. Think of them as a multidimensional
continuum, where trade-offs have to be made.
1. No arbitrary limits on the input number. 64 bits might be enough
for everybody, but is not enough for exploring new Collatz-territory.
Thus bignums are required.
2. Ultra-portable. Must run on C89 systems and self-adapt to C99 and C11
features like exact width types.
3. Super-efficient. Must be able to run with the widest type as the
base of the bignums. Make the user select the widest type supported
by the implementation and then crunch away. If a non-standard
128bit type is available, it should be usable.
4. Pentagon level lint cleanliness and MISRA compliance.
5. Easy to understand, self-documenting clear code. A joy for maintenance
programmers. The epitome of best practice demonstration for all
future textbooks on C.
Program Obfuscation
===================
In the following I address all the *tests* as specified by your honors in the
*guidelines*.
* 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
Look at the original source
---------------------------
Using one letter identifiers is quite old. I decided to use TLI (three
letter identifiers). Not the random kind, rather with a connection to
the meaning of life, the universe and the rest. Enter amino acids! Among
the myriad of possible amino acids there are 23 from which proteins are
built. In biochemistry, each is assigned a TLI (see [Proteinogenic amino
acid](https://en.wikipedia.org/wiki/Proteinogenic_amino_acid)):
ala Alanine
cys Cysteine
asp Aspartic acid
glu Glutamic acid
phe Phenylalanine
gly Glycine
his Histidine
ile Isoleucine
lys Lysine
leu Leucine
met Methionine
asn Asparagine
pyl Pyrrolysine
pro Proline
gln Glutamine
arg Arginine
ser Serine
thr Threonine
sec Selenocysteine
val Valine
trp Tryptophan
tyr Tyrosine
asx Asparagine or Aspartic acid
glx Glutamic acid or Glutamine
xle Leucine or Isoleucine
unk Unknown
My own research results complete this list (not yet in Wikipedia due to
the rule "[No original
research](https://en.wikipedia.org/wiki/Wikipedia:No_original_research)"):
and Androgynine
xor Xenoricine
not Notanamine
tla Triletramine
Interestingly, the TLI are the perfect mnemonics for C language source.
For example, `met` is "Main's Exit Type" (`int`), `ala` is "A Large
Algebraic" (bignum), `ile` an "Incremented Local Entity" (index
counter), `gly` means "Grow Larger memorY", `gln` is "Grown Larger Now"
(after realloc), `not` is a "Not Overflowing Type" (recursive!), `unk`
is the "UNit (Known as 1)", `trp` is the "Tabula Rasa Product" (zero),
`phe` is "Print HEx" and so on.
Convert ANSI tri-graphs to ASCII
--------------------------------
Huh??!
C pre-process the source ignoring '#include' lines
--------------------------------------------------
Wow, an identity operation (except for the `<stdint.h>` and `EOF + __STDC__`
trivialities). Did you gain any insight through this?
C pre-process the source ignoring '#define' and '#include' lines
----------------------------------------------------------------
`#define`? Which `#define` directives? How many 4K source files do you
see that neither use a single `#define` directive *nor* abuse the build
file? Even though the "no `#define`" rule I submitted myself to made it
hard, I could use `__LINE__` and stdio macros `EOF`, `L_tmpnam`,
`BUFSIZ`, `FILENAME_MAX`, `TMP_MAX` to obfuscate at least something.
Run it through a C beautifier
-----------------------------
Another identity operation. I've done it for you already. Use this
`.indent.pro` with FreeBSD indent:
$ cat .indent.pro
-bad /* blank line after decls */
-bap /* blank line after functions */
-br /* braces on if line */
-i8 /* indent */
-l999 /* line length */
-npcs /* no space after function call names */
-npsl /* don't break procedure type */
-ut /* use tabs */
-ce /* cuddle else */
-nip /* no parameter indentation */
-di1 /* declaration indent */
-Tand
-Tmet
-Tthr
-Tpro
-Tser
-Tala
It looks like a perfect program should:
* two and a half `#includes` of unsuspicious standard headers
* followed by self protection against goofy implementations
* followed by a handful of `typedef`s
* and a pair of file scope objects by necessity
* prototypes! With parameter names! `static` for internal linkage even! This __must__ be a first in IOCCC history.
* function definitions, `main` last
* everything is fully const-poisoned: automatics, statics, arguments, even `main`
* everything is fully curly braced, even single statements
* plenty of meaningful TLC (Three Letter Comments)
The program contains not a single *magic number* (only 0 and powers of
2, each power from 1 to 512) which are obvious to competent software
engineers). How many programs have *that* property? The check for
`__STDC_VERSION__` was a bit tough to arrive at, since 199901L has too
many bits set. But I realized that I only needed a number larger than
199409 and less than 199901. 199680 has only 4 bits set and writing it
as (256 + 128 + 4 + 2) * 512 minimizes the character count. That's what
judges get when they don't like programs that are longer than they need
to be.
Examine the algorithm
---------------------
Spoilers ahead. Duh!
Pseudocode, with comments matching those in the C source:
/* run */
if (non-NULL and nonempty argv[1]) {
n = convert(argv[1])
print n /* 2hx */
while (n != 1) { /* one */
if (n is odd) { /* odd */
m = deep copy of n /* cpy */
n <<= 1 /* shl */
n += m /* add */
increment n /* inc */
} else { /* eve */
n >>= 1 /* shr */
}
print n /* 2hx */
}
}
Bignums are represented as the two member structs
typedef struct {
size_t places; /* number of places in base 2<sup>8*sizeof(type)</sup> */
type *number; /* dynamically allocated memory for number */
} bignum
Compile it (with flags to enable all warnings)
----------------------------------------------
Here's where the program shines brighter than a [gamma-ray
burst](https://en.wikipedia.org/wiki/Gamma-ray_burst)!
I challenge you to throw all kinds of compilers, lints, checkers and
analyzers at my program and make it find the slightest of issues.
Is `clang -Wall -Wextra -Weverything -Dtyp=uint32_t prog.c` all you can
do? Clang has implemented a new warning? Bring it on!
Execute it
----------
May you win the jackpot!
For least surprising results, the execution character set should be
ASCII. The program computes four bits from every character in `argv[1]` and
interprets them as a hex digit. On ASCII the characters a-f, A-F and 0-9
are converted as expected.
This means however, that the program accepts __any string__, turns it
into a starting number (which is output as the first line), and starts
crunching. Nothing stops you from executing
$ ./prog "$(cat prog.c)" # Kind of quine?
$ ./prog "$(cat rules guidelines)" # A jackpot? Maybe next year...
$ ./prog "$(cat /bin/ls)" # Number cut short at first NUL byte.
In a certain way, the program is character set and encoding agnostic.
Assumptions made
----------------
* The `EOF` macro from `<stdio.h>` must expand to negative one since it is used
to decrement a pointer and do some other math.
None of the tools catches this one. The program self-protects against unusual
systems with `#if EOF + __STDC__` followed by `#error goofy!`. In the rare event
your system is goofy, replace all `EOF` tokens with `(-1)` and remove the
`#error` directive.
While the program works best when bytes/characters are octets and the
number of bits in a type is `sizeof(typ) << 3`, it will work correctly
on 24bit or 36bit systems with 9 bits/byte, or systems where
`sizeof(typ)` is 1 even for `int` and so on. On such systems, it will only
use 8 * `sizeof(typ)` bits per place. It does not work when `CHAR_BIT <= 7`.
Results of various checkers
---------------------------
### cppcheck
The open source static checker [cppcheck](http://cppcheck.sourceforge.net/)
checks various problems with respect to style, performance, portability
and general fishiness. To enable all checks, run
$ cppcheck --enable=all --force -I/usr/include -Dtyp=uint32_t prog.c
No issues found.
### flawfinder
The open source static checker [flawfinder](http://www.dwheeler.com/flawfinder/)
checks various problems with respect to security like buffer overflows,
function arguments to known troublemaker functions and more. It doesn't need to
pre-process code, so can be run without the `typ` macro being defined:
$ flawfinder prog.c
Flawfinder version 1.31, (C) 2001-2014 David A. Wheeler.
Number of rules (primarily dangerous function names) in C/C++ ruleset: 169
Examining prog.c
FINAL RESULTS:
ANALYSIS SUMMARY:
No hits found.
$
### valgrind
The open source dynamic checker [valgrind](http://valgrind.org/)
runs an executable and verifies all memory accesses and (de)allocations for
proper bounds and memory leaks.
Since the program frees all memory in all possible execution paths, even when
it must bail out,
valgrind should be happy. An early version of my program however reported this:
$ valgrind --leak-check=full --show-leak-kinds=all ./prog 6
[...]
==14615== HEAP SUMMARY:
==14615== in use at exit: 4,096 bytes in 1 blocks
==14615== total heap usage: 4 allocs, 3 frees, 4,108 bytes allocated
==14615==
==14615== 4,096 bytes in 1 blocks are still reachable in loss record 1 of 1
==14615== at 0x4C236C0: malloc (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==14615== by 0x4F62175: ??? (in /lib/libc.so.7)
==14615== by 0x4F62073: ??? (in /lib/libc.so.7)
==14615== by 0x4F514EE: ??? (in /lib/libc.so.7)
==14615== by 0x4F51265: vfprintf_l (in /lib/libc.so.7)
==14615== by 0x4F3E001: printf (in /lib/libc.so.7)
==14615== by 0x40101E: phe (in ./prog)
==14615== by 0x400A9F: main (in ./prog)
==14615==
==14615== LEAK SUMMARY:
==14615== definitely lost: 0 bytes in 0 blocks
==14615== indirectly lost: 0 bytes in 0 blocks
==14615== possibly lost: 0 bytes in 0 blocks
==14615== still reachable: 4,096 bytes in 1 blocks
==14615== suppressed: 0 bytes in 0 blocks
==14615==
==14615== For counts of detected and suppressed errors, rerun with: -v
==14615== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
From which I concluded that `printf` allocated a single 4K block for
which no matching free existed. But how to free memory allocated deep
down in the guts of the Standard I/O library? After some serious head
scratching it hit me. The only chance I have is telling the system I no
longer want to do I/O, maybe then it would free that buffer. A reading
of C99 7.19.5.1, "The fclose function", was encouraging:
> Whether or not the call succeeds, the stream is disassociated from the file
> and any buffer set by the `setbuf` or `setvbuf` function is disassociated from the stream
> (and deallocated if it was automatically allocated).
So I `fclose(stdout)` before returning and now:
$ valgrind --leak-check=full --show-leak-kinds=all ./prog 6
==14571== Memcheck, a memory error detector
==14571== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==14571== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==14571== Command: ./prog 6
==14571==
0000000000000006
0000000000000003 1
000000000000000A 2
0000000000000005 3
0000000000000010 4
0000000000000008 5
0000000000000004 6
0000000000000002 7
0000000000000001 8
==14571==
==14571== HEAP SUMMARY:
==14571== in use at exit: 0 bytes in 0 blocks
==14571== total heap usage: 4 allocs, 4 frees, 4,120 bytes allocated
==14571==
==14571== All heap blocks were freed -- no leaks are possible
==14571==
==14571== For counts of detected and suppressed errors, rerun with: -v
==14571== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
A squeaky clean valgrind result!
### FlexeLint
FlexeLint is a commercial lint tool by [Gimpel
Software](http://www.gimpel.com/html/index.htm). It supports nearly a
thousand checks, broadly categorized into 4 levels,
1. Syntax errors only (messages 1 to 399)
2. Warnings (messages 400 to 699)
3. Informational messages (700 to 899)
4. Elective notes (900 to 1000 and > 9000)
There is an [on-line
demonstrator](http://www.gimpel-online.com/OnlineTesting.html) you can
use for checking your C programs and I highly recommend trying it. For a start,
paste the well know first program in the form and press "Analyze Code". Note
the FlexeLint configuration options in comments (no space between `/*` and `lint`).
/*lint -w4 turn on everything */
/*lint +esym(534,*) no demonstrator defaults */
/*lint -e966 indirectly included header file not used */
/*lint -esym(9058,_*) tag not used outside typedef */
/*lint -misra(2) */
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
return 0;
}
Possible checks include those for MISRA 2004 compliance verification.
The [Motor Industry Software Reliability
Association](https://en.wikipedia.org/wiki/Motor_Industry_Software_Reliability_Association)
has produced a [list of 121 required and 20 advisory
rules](http://doc.hcc-embedded.com/display/CODING/MISRA+Rules) for C
programming. I am proud to report that my program fulfills *almost all*
rules. To assess the few exceptions, one has to understand that MISRA
rules are geared towards embedded systems used in the automotive
industry. That's why features like `malloc` and `printf` are right out.
But that's too restrictive for an IOCCC hosted application, so I ignored
these:
* 17.1 Pointer arithmetic shall only be applied to pointers that address an array or array element.
* 17.4 Array indexing shall be the only allowed form of pointer arithmetic.
* 20.4 Dynamic heap memory allocation shall not be used.
* 20.9 The input/output library stdio.h shall not be used in production code.
* 20.11 The functions abort, exit, getenv, and system from the library stdlib.h shall not be used.
I started out with enabling *all* messages using FlexeLint's `-w4`
option and disabling all noise from system headers. Then I dealt with
the remaining messages by addressing them or suppressing them in such a way
that the set of suppressions was minimal. At the end of the day, this is
what remained:
// === Tested with FlexeLint 9.00L on FreeBSD 11 ===
// Compiler:
// "4.2.1 Compatible FreeBSD Clang 3.6.1 (tags/RELEASE_361/final 237755)"
-w4 // Enable maximum pickiness
-passes(6) // Recommended in FlexeLint manual for torture testing
+fsc // Make string literals have type const char*
+fnr // ptr-returning functions may return NULL
-strong(AJX,and,pro,ser,ala) // strong types
-strong(AcJcm,thr) // thr is strong, but most arithmetic is okay
-strong(AarJemorX,met) // met is strong, but some use is okay
+libclass(angle) // All <headers> are system headers
-wlib(1) // Only errors for system headers
-i/usr/include // System headers
-i/usr/local/lib/supp/ansi // Comes with FlexeLint
-d__GNUC__=4 // Pretend...
-d__GNUC_MINOR__=2 // I'm...
-d__GNUC_PATCHLEVEL__=1 // someone else.
-d__builtin_va_list=char* // Fake this compiler extension
-d__inline= // Delete this compiler extension
-d__attribute__(x)= // Delete this compiler extension
+e900 // Announce number of messages produced
// MISRA 2004 checking
/usr/local/lib/supp/lnt/au-misra2.lnt // Enable all MISRA checking
-elib(960) // Don't check FreeBSD system headers for required rules
-elib(961) // Don't check FreeBSD system headers for advisory rules
-e829 // stdio.h used
-e522 // MISRA 14.2 Highest operation, lacks side-effects
-esym(960,17.4) // pointer arithmetic other than array indexing used
-e971 // char without signed/unsigned
-e974 // stack usage report
// Use verboten functions, Req. Rules 20.4 malloc() et al., 20.11, exit()
-esym(586,malloc,realloc,calloc,free,exit)
-e911 // implicit promotion of smaller than int to int
-e921 // cast from integral to integral
-e925 // cast from pointer to pointer
-e958 // padding required in struct
+e9??? // Enable all 9xxx informational messages, except:
-e9079 // conversion from pointer to void to pointer to other type
-e9087 // cast performed between a pointer to object type and a
// pointer to a different object type
-e9141 // global declaration of symbol
// Messages due to code in FreeBSD headers.
//
-dlint // The "lint" macro is tested in x86/_types.h
-elib(537) // Repeated include file
-e793 // external identifiers > 6 chars
-e935 // (unsigned) int within struct (actually the size_t)
-estring(960,_*) // Could be defined at block scope
-e964 // Header file not directly used
-e966 // Indirectly included header file not used
-elib(970) // int outside typedef
-esym(9003,_*) // could be defined at block scope
-elib(9047) // FILE pointer dereferenced
-esym(9058,__*) // tag not used outside typedef
-e9092 // NULL does not expand to a pointer (but plain 0)
Compulsory obfuscations
-----------------------
Which of the rules cause which obfuscation?
MISRA 6.1, "The plain char type shall be used only for the storage and
use of character values." This forbids using character constants in
expressions other than assignments to `char` objects. A consequence is
that printing digits with `'0' + digit` is not allowed (even though
`'0'` is technically an `int`!) so I am forced to output hex digits with
printf("%c", (met)tyr + 32 + 16 + ((8 + EOF) * ((met)tyr / (8 + 2))));
because of the "no magic numbers other than powers of two" rule. How is this
an improvement over `printf("%c", '0' + tyr + 7 * (tyr / 10)`, MISRA?
MISRA 6.3 "typedefs that indicate size and signedness should be used in
place of the basic types." Well, if you can't infer the size and
signedness from `typedef int met`, you're not a real C programmer.
MISRA 10.5, "If the bitwise operators `~` and `<<` are applied to an
operand of underlying type `unsigned char` or `unsigned short`, the
result shall be immediately cast to the underlying type of the operand."
Because the program must work for any unsigned type chosen for the `typ`
macro, including the narrow types enumerated in the rule, a lot of
redundant casting ensues. It gets worse with the next rule...
MISRA 12.1, "Limited dependence should be placed on the C operator
precedence rules in expressions." This requires parentheses for almost
all expressions involving more than one operator, especially those for which
a cast is required, leading to hard to understand expressions such as
const ser glx = (ser)((asx > (ser)64u) ? (ser)((ser)asx + (ser)8u + (ser)1u) : (ser)asx);
not.not[leu] = (and)((and)not.not[leu] | (and)(((and)glx % (and)16u) << (and)lys));
MISRA 14.7, "A function shall have a single point of exit at the end of
the function." Sigh. Since I must use eloquent prototypes (8.1, 16.3,
16.4) and static functions (8.10, 8.11), I can only use a few functions.
Everything usually written with an early `return` now cause *another
useless indent level*. The first three `if` statements in `main` cause a
silly 24 character indent. The maximum indent is forced to 8, which is way
too high for a sane function.
MISRA 16.10, "If a function returns error information, then that error
information shall be tested." A cast to void would draw a lint warning, so
I use the `printf` result in expressions,
lys -= 4 * printf("%c", (met)tyr + 32 + 16 + ((8 + EOF) * ((met)tyr / (8 + 2))));
val += printf("\n") / ((__LINE__ * L_tmpnam) + TMP_MAX);
val -= (printf(" %d\n", val) > BUFSIZ) ? FILENAME_MAX : EOF;
which are, in the absence of errors, equivalent to
lys -= 4;
/*nop*/
++val;
MISRA 13.1, "Assignment operators shall not be used in expressions that
yield a Boolean value." Forbids the idiomatic `if ((p = malloc(n)) ==
NULL)` and requires separate statements, in other words, bloat.
MISRA 16.7, "A pointer parameter in a function prototype should be
declared as pointer to const if the pointer is not used to modify the
addressed object." in conjunction with lint's "Note 952: Parameter could
be declared const" causes const-poisoning for all functions,
static void phe(const ala not);
static void gly(ala *const not, const and his);
met main(met val, const pro *const his[]);
and quite a number of automatic variables.
### Why the "laugh" and "throw up" messages?
The guidelines state "We like programs that: make us laugh and/or throw
up :-) (humor really helps!)"
### If you have a 128 bit type
If your compiler supports a 128 bit wide type (e.g. clang, gcc) then
you can use it via the `typ` macro:
clang -Dtyp=__uint128_t -o prog prog.c
Indeed, the program can use (and lints clean for) all of
clang -Dtyp=uint8_t -o prog8 prog.c
clang -Dtyp=uint16_t -o prog16 prog.c
clang -Dtyp=uint32_t -o prog32 prog.c
clang -Dtyp=uint64_t -o prog64 prog.c
clang -std=c89 -Dtyp="unsigned long" -o prog89 prog.c
This works because the program has no need for corresponding `SCN` or
`PRI` macros to do the scanning and printing of variables of these
types. With a 128 bit type the program can represent numbers up to
340282366920938463463374607431768211457 (3.4 * 10<sup>39</sup>) as a
single "place", enough to explore yet untested numbers for the rest of
your life.
### How big a number can I test with 4 GB of RAM?
The number of hex digits in the start number is limited by `ARG_MAX`,
probably minus some overhead for the environment variables (use
[`env`(1)](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/env.html)
to trim your environment). In bits this leaves you with 2<sup>4 *
ARG_MAX</sup>.
The algorithm requires two bignums in memory for addition.
If you hit a divergent number, this will cause out-of-memory ("laugh")
somewhere near 2<sup>16,000,000,000</sup> (4GB/2 * 8bits/byte).
Sadly, I don't have a test case :-)
How long would it take to overflow the *Not Overflowing Type*? Lets
assume we're processing 2GB numbers. The program copies, shifts by one,
adds and increments 2GB long bit strings, each time completely thrashing
the data cache -- at *all* levels. We have a fast machine that can do an
iteration in one second, on average. To make things easy, we round up
3*n* + 1 to 4*n*, and assume we never need to divide by two (which is
quite optimistic). Then each iteration shifts left by 2. This would take
8 billion seconds, or about 250 years. If you want to get famous, you
better *remove* some of the RAM, use an ancient box, or reduce available
memory resources with the ulimit(1) built-in of your shell.
For all intents and purposes, the *Not Overflowing Type* keeps the promise!
--------------------------------------------------------------------------------
<!--
(c) Copyright 1984-2016, [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/
-->
Loaded 100 of 1683 files, more files were not shown because too many files have changed in this diff. Show more