Remove hint.html and index.html

As per discussions on GitHub the index.html and hint.html files should
be deleted in favour of README.md files (from any
.text/.txt/.markdown/.md files which will be turned into README.md in an
upcoming commit).
This commit is contained in:
Cody Boone Ferguson committed 2023-02-08 05:07:05 -08:00
1 parent ee8a36310f
commit 77fb0f11a2
143 files changed
-28606

No files matched your search

-154
View File
@@ -1,154 +0,0 @@
<!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 cacophonic</title>
</head>
<body>
<h1>Most cacophonic</h1>
<p>Anton Älgmyr<br>
Twitter: @aalgmyr</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
cat prog.c | ./prog # Printing garbage might break your font
./prog &lt;file1&gt; &lt;file2&gt; &gt; out.raw
./prog -d 2 0 out.raw # Decode the first (0th) channel out of two
</code></pre>
<h3>To try:</h3>
<pre><code>./prog -h | ./prog -d 1 0
# Who needs cat?
./prog prog.c | ./prog -d 1 0
# Assuming ALSA
echo '&lt;&lt;&lt;&lt;&lt;&lt; /\_/\_/\ _-_-_-_ !!!!! :.:.:.: &gt;&gt;&gt;&gt;&gt;&gt; ****** ~~~~~~~' |
./prog | aplay -c1 -fFLOAT_LE -r44100
# Assuming sox
echo -n ' MENE MENE TEKEL UPHARSIN ' | ./prog |
sox -t raw -c 1 -r 44100 -L -e floating-point -b 32 - -n spectrogram -d 10 -X 300
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Be warned, this is not your garden variety text-to-speech program! Earplugs are advised,
or at least a handy and well-tested volume knob.</p>
<p>Pixels are numbered, amplitudes are weighed, frequencies are divided,
and the message can be displayed in fiery letters, but don&rsquo;t be alarmed.</p>
<p>How does decoding of the waveform work? Can you encode an arbitrary text in a sound sample?</p>
<h2>Author&rsquo;s comments:</h2>
<h1>What is this?</h1>
<p>To put it brief, this entry is akin to a sound based cat. It takes characters as input and outputs them into frequency space as audio. The entry also supports decoding the produced waveforms using the <code>-d</code> flag. Usage instructions is output if run with the <code>-h</code> flag, albeit not in an immediately legible format.</p>
<h2>Details</h2>
<p>In normal operation, the entry reads characters from one or more sources. If the <code>-h</code> flag is given, usage instructions is used as a source. Else if file paths are present as arguments those will be used. Else stdin is used.</p>
<p>If a character is part of the supported subset of ASCII <code>{10, 32-126}</code> then that character is output into frequency space of an audio signal (44.1 kHz single precision float, endianness should depend on system endianness) through stdout. Any other character will be interpreted and outputted as a space.</p>
<p>Characters are printed using a (slightly modified) pixel font based on <a href="https://github.com/hchargois/gohufont">gohufont</a>. Pixels are drawn using crosses in frequency space, achieved by simultaneous up and down chirps.</p>
<p>Each input source is designated its own channel in the output (one float per channel per time step in the output) so if you have a surround sound system you could listen to a cacophony of chirpy characters.</p>
<p>Interestingly, with training you might actually be able to tell characters just from hearing. But even without training you can easily read along with the printed characters and have the sound make sense with the look of the characters.</p>
<p>See image spoiler.png for an example spectrogram.</p>
<h2>Limitations</h2>
<p>There is no error checking done when opening files, so expect segfaults if you provide the wrong path to a file.</p>
<p>This program is bound to misbehave if int is less than 32 bits.</p>
<p>Flags will only be interpreted correctly if they are the first argument. Reading a file named <code>-d</code> or <code>-h</code> is fully possible if it is not the first file provided, even though I am not sure why you would want to do that.</p>
<p>Providing invalid/unexpected arguments to the decode flag will result in odd behavior. Some erroneous arguments cause segfaults (negative number of channels, channel id outside valid range). One argument in particular causes an infinite loop printing whitespace.</p>
<h1>Techniques</h1>
<h2>Obfuscation</h2>
<p>A lot of the obfuscations done came naturally from trying to appease the size tool. To name some:</p>
<ul>
<li>One character names</li>
<li>Merging of related (and not so related) arithmetic operations</li>
<li>Short circuiting for flow control to replace some <code>if</code>s</li>
<li>Some <code>#defines</code>, sadly</li>
</ul>
<p>On the intersection of size and obfuscation is the data encoding, which was quite fun to design.</p>
<p>Some additional obfuscation was done to mathematical formulas. Somewhat known expressions was transformed into equivalent but less recognizable counterparts.</p>
<p>I have tried to avoid intentional red herrings in the code, although fishy statements are plentiful.</p>
<h2>Data encoding</h2>
<p>The large string in the beginning of the source file contains font data, encoded in base64 using characters in the range <code>' '</code> to <code>'_'</code>. The space was chosen as the zero because the data contains a lot of zeroes, and quite helpfully the size tool ignores whitespace even in strings. Without this fact the program would have been too large and the decoding feature would have had to go. Fortunately this hole in the size spec was readily available. :)</p>
<p>Characters in the font (5x8 pixels, 40 bits) is packed into 7 base64 digits (which was a pain to decode in minimal code).</p>
<h2>Math</h2>
<p>Note that even though floats are used for the waveforms, the standard math library is not used at all! Most arithmetic is done purely on integers. The only major exception is generating a table of sine values which are interpolated to give high resolution waveforms. Can you see when the generation is triggered, and how it is done?</p>
<p>A critical issue encountered was that having abrupt starts and ends of signals cause a lot of problems with spectral leakage which makes spectrograms hard to read and audio painful to listen to. To reduce spectral leakage a windowing function was used. Although the one used is quite well known, it is not in a form that should be familiar to anyone. What looks like a polynomial and quacks like a polynomial might not actually be a polynomial, at least not deep inside.</p>
<h2>Printing a string</h2>
<p>The program was written to deal exclusively with file descriptors, so how would one go about printing a char array not from a file descriptor without adding additional logic? Answer: <code>ungetc</code> into stdin, one char at a time (to be standards compliant). This is used to print the usage instructions.</p>
<h1>Compilation warnings</h1>
<p>Compiling using</p>
<pre><code>gcc -Wall -Wextra -pedantic
</code></pre>
<p>gives only <code>-Wmisleading-indentation</code> which is sensible considering the source code. While</p>
<pre><code>clang -Wall -Wextra -pedantic
</code></pre>
<p>is a bit more pessimistic and gives <code>-Wempty-body</code> (I like loops without bodies), <code>-Wstring-plus-int</code> (since apparently some people think string+int is a concatenation) and one of the weirder warnings I have seen from me splitting a negative constant with whitespace. Compiling using</p>
<pre><code>clang -Wall -Wextra -pedantic -Weverything
</code></pre>
<p>produces a few pagefuls of warnings and makes me feel generally bad about myself. :(</p>
<h1>Misc</h1>
<p>The reported size of the source code using the size tool is very intentionally 2018.</p>
<hr />
<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-2018,
<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>
-91
View File
@@ -1,91 +0,0 @@
<!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 able to divine code gaps</title>
</head>
<body>
<h1>Most able to divine code gaps</h1>
<p>Derek Anderson</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &lt; textfile
</code></pre>
<h3>Try:</h3>
<pre><code>./prog &lt; prog.c
./prog &lt; prog.orig.c
./prog &lt; hint.text
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>With this entry, you won&rsquo;t need to turn your monitor <a href="http://en.wikipedia.org/wiki/River_%28typography%29">upside down</a>!</p>
<p>Compare <code>prog.c</code> and <code>prog.orig.c</code> and find out why we had to modify the entry, and what confused the author
(see the author&rsquo;s remarks). No, it was not the shape of the Roman V that we, or the compiler, didn&rsquo;t like.</p>
<h2>Author&rsquo;s comments:</h2>
<h2>Compiling the program</h2>
<pre><code>gcc -Wall -Wextra -Wpedantic -O3 -std=c11 prog.c -o prog
</code></pre>
<p>Also works with a standard of c99, but c90/c89 will not compile due to
for loop initial declarations, along with additional warnings about
variable length arrays and lack of a return statement.</p>
<h2>Additional info</h2>
<p>This small program, when given text on stdin, will produce a pattern of
squiggly lines. This pattern is deterministic, and it shouldn&rsquo;t be too
difficult to determine from whence they come. There is even a comment
that describes the highlighted phenomena in the source, for those that
require a small nudge. With denser text blocks, such as an essay or
similar prose, the output can be rather pretty, in an chaotic emergence
sort of way. Try using this file, or the source file as inputs.</p>
<p>In its current form, this program can handle lines of length 255; to
adjust this limit, change the variable <code>a</code> at the top of the source.
Other adjustments, such as the exact printed characters, are rather
easy, once sufficient reverse engineering has occurred. Improvements
such as proper handling of tabs are left as an exercise to the reader.</p>
<p>In developing this program, the author found a potentially interesting
bug. If the expression <code>(j=k,j)</code> (near the middle of the source) is
changed to <code>(j=k,k)</code>, the program produces different output. The author
used compiler gcc 5.4.0, compiled for x86_64-linux-gnu. Enabling or
disabling optimization produces the same results. The author is not
sure who is the culprit, but instead shrugged and moved on with life.
Of course, YMMV with your own environment.</p>
<p>The structure of this program, as you may have deduced, is two for
loops, one nested in the other. There is also a bunch of direct
variable assignment, such as <code>j=k</code>. There is some filler fluff, such as
<code>0-0+0</code>, but all that sort should be rather easy to spot. It was mostly
added for the purpose of making certain things line up right, and only
secondarily to obfuscate.</p>
<hr />
<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-2018,
<A HREF="/judges.html">Leo Broukhis, Simon Cooper, Landon Curt Noll</A>
- All rights reserved<BR>
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</P></TD>
<TD>&nbsp;<!--<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>--></TD>
</TR></TABLE>
</body>
</html>
-105
View File
@@ -1,105 +0,0 @@
<!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 inflationary</title>
</head>
<body>
<h1>Most inflationary</h1>
<p>Fabrice Bellard<br>
<a href="https://bellard.org/">https://bellard.org/</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &gt; lena.ppm
</code></pre>
<h3>Try:</h3>
<pre><code>eog lena.ppm # On Linux
preview lena.ppm # On MacOS
wget http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png
pngtopnm &lt; Lenna.png | pnmscale 0.25 | cjpeg -arithmetic -dct float -quality 14 &gt; small.jpg
</code></pre>
<p>The file <code>small.jpg</code> will be approximately of the same size as the raw image data
in the program. Compare the level of the detail and the artifacts of
<code>small.jpg</code> and <code>lena.ppm</code>.</p>
<h3>Selected Judges Remarks:</h3>
<p>Compressing images is just a matter of simple arithmetic and some magic, isn&rsquo;t it?</p>
<p>We could understand some of the arithmetic but none of the magic.</p>
<p>Deciphering the mechanism used for data encoding to make use
of the whitespaces, braces and semicolons should be a slightly easier task.</p>
<h2>Author&rsquo;s comments:</h2>
<p>This program outputs a 128x128 RGB image file to the standard output
using the portable pixmap file format (PPM). It contains the famous
&ldquo;Lena&rdquo; image which is used in many image compression tests.</p>
<p>The uncompressed image is 12 times larger than the source code of the
program which includes the image data and the complete decoder. The
actual image data is 1220 byte long, which gives a compression ratio
of 40. Using a JPEG-like algorithm would not be enough to reach this
level of compression (the Lena image would be barely recognizable). So
the algorithm is based on the latest advances in image compression. It
includes the following features:</p>
<ul>
<li>DCT transform with variable block size (4x4, 8x8, 16x16 and 32x32)</li>
<li>DC and directional predictors</li>
<li>arithmetic coding</li>
<li>YCgCo color space.</li>
</ul>
<p>The image data is encoded to a C string with some tricks to make the
best use of the IOCCC size constraints. The identifiers were shortened
to a single letter to save space. No specific obfuscation was needed
as the algorithms already have a significant complexity.</p>
<p>Although the program was optimized to decompress its built-in image,
it accepts to decompress image files from its standard
input. Examples:</p>
<pre><code>./prog d &lt; lena512.bin &gt; lena512.ppm
./prog d &lt; fruits.bin &gt; fruits.ppm
./prog d &lt; vintage_cars.bin &gt; vintage_cars.ppm
</code></pre>
<p>The original images for <a href="https://commons.wikimedia.org/wiki/File%3AFruits_oranges%2C_jardin_japonais_2.JPG">fruits</a> and <a href="https://commons.wikimedia.org/wiki/File%3ARed_Bull_Jungfrau_Stafette%2C_10th_stage_-_vintage_cars_%282%29.jpg">vintage cars</a> come from
Wikipedia and were resized to a width of 1024 pixels. Warning: the
program is not protected against invalid input.</p>
<p>The program should be portable on any Unix system. On Windows the line
&ldquo;<em>setmode(0, 32768); </em>setmode(1, 32768);&rdquo; must be added at the start of
the main() function to avoid unwanted carriage return characters in
the output.</p>
<hr />
<hr />
<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-2018,
<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>
-246
View File
@@ -1,246 +0,0 @@
<!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>Dave Burton<br>
<a href="http://ioccc.snox.net">http://ioccc.snox.net</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &lt; any-file
</code></pre>
<h3>Try:</h3>
<pre><code>./prog &lt; prog
./prog &lt; prog.c
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>One line, one array, one loop and one statement but it prints many bytes. It won.</p>
<h2>Author&rsquo;s comments:</h2>
<p>Feed this anything on stdin.</p>
<p>The included script may be used as a driver program for this entry.
It adds several nice-to-have features, and allows salt-to-taste customizability.</p>
<p>This code has been compiled and tested on:</p>
<ul>
<li>OSX-10.11, gcc 4.2.1 and clang 3.0, -O0 and -O3</li>
<li>X86-Linux, gcc 4.1.2 and 4.8.4, -O0 and -O3</li>
<li>ARM-QEMU, gcc 4.8.4, -O0 and -O3</li>
<li>X86-FreeBSD 10.3, clang 3.4.1, -O0 and -O3</li>
<li>TCC 0.9.26 (x86-64) (used as a proxy for <a href="http://ioccc.org/years.html#2001_bellard">2001/bellard</a>)</li>
<li>UNIX V7 pcc (Johnson&rsquo;s C compiler) on a <a href="http://simh.trailing-edge.com/">simulated PDP-11/45</a>
(see spoiler for further detail)</li>
</ul>
<div style="margin-bottom:60em;margin-top:4em"><strong>Spoiler below; scroll down.</strong></div>
<h2>SPOILER</h2>
<p>This started life as a personal challenge: write the shortest hex dump utility in C.</p>
<p>The self-imposed ground rules in the hunt for shortest:
the code has to output correctly,
no extraneous newlines, the code must be portable,
and without bypassing the solution using execve(2),
or functions built upon it (system(3), popen(3), etc). E.g:</p>
<pre><code>main(){system("hd");} // it's turtles all the way down!
</code></pre>
<p>is not acceptable.
And, &ldquo;output correctly&rdquo; is the output format of this entry. QED.</p>
<p>Early attempts ended up at a reasonably short 157 characters.
This was too long for a one-liner, so it had to be formatted as something more interesting.
This solution is pleasing, but a true one-liner was the hoped-for goal.
Here is the 157 character version in it&rsquo;s entirety:</p>
<pre><code>char O,o[ 20];L(O){
putchar ( O+ 48+39 *(9&lt;
O));} I(O) {L(~ 15);
O|| puts(o);} main (l){
for(;~(l=getchar()) ;I(O
&amp;=15 ))o[ O++ ]=4&lt;
(4^l &gt;&gt;5) ?l: 46,L
(l&gt;&gt; 4),L (l&amp;15);O&amp;&amp;
I(o[ O]=0 );}//157c
</code></pre>
<p>While thinking about this in the shower (you are not the only one that does this!)
came the idea which reduced the code to just 119 chars.
This dramatic reduction started to feel close to minimal, and the hunt resumed.
The progression to the present size is interesting,
and it is interesting that the same algorithm can be expressed so differently
by slight rearrangement of its parts.</p>
<pre><code>// 119
char O,o[20];main(l){for(;~(l=getchar());O||puts(o))o[O++]=isprint(l)?l:46,O&amp;=15,printf("%02x ",l);O[o]=0;O&amp;&amp;puts(o);}
// 116
char O,o[20];main(l){for(;O++[o]=~(l=getchar())?4&lt;(4^l&gt;&gt;5)?l:46:0;(O&amp;=15)||puts(o))printf("%02x ",l);O&gt;1&amp;&amp;puts(o);}
// 115
char O,o[20];main(l){for(;O[o]=~(l=getchar())?4&lt;(4^l&gt;&gt;5)?l:46:0;(O=-~O&amp;15)||puts(o))printf("%02x ",l);O&amp;&amp;puts(o);}
// 113
char O,o[20];main(l){for(;~l;(O=~l?printf("%02x ",l),-~O&amp;15:!O)||puts(o))O[o]=~(l=getchar())?4&lt;(4^l&gt;&gt;5)?l:46:0;}
// 112
char O,o[20];main(l){for(;~l;(O=~l?-~O&amp;printf("%02x ",l)*5:!O)||puts(o))O[o]=~(l=getchar())?4&lt;(4^l&gt;&gt;5)?l:46:0;}
// 111
char O,o[20];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4&lt;(4^l&gt;&gt;5)?l:46:0)?-~O&amp;printf("%02x ",l)*5:!O;}
// 110
char O,o[0];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4&lt;(4^l&gt;&gt;5)?l:46:0)?-~O&amp;printf("%02x ",l)*5:!O;}
// 109
char O,o[];main(l){for(;~l;O||puts(o))O=(O[o]=~(l=getchar())?4&lt;(4^l&gt;&gt;5)?l:46:0)?-~O&amp;printf("%02x ",l)*5:!O;}
</code></pre>
<p>There are solutions without the ASCII sidebar that are significantly shorter.
These do not compete in the same category, since their output is materially different.
They are derived from the solutions above, but are still fascinating as concise utilities,
so here is their progression, for the curious:</p>
<pre><code>// 102
I;O(O){putchar(O+48+39*(9&lt;O));}main(l){for(;~(l=getchar());O(++I&amp;15?~15:~37))O(l&gt;&gt;4),O(l&amp;15);O(-38);}
// 80
O;main(l){while(~(l=getchar()))printf("%02x%c",l,++O&amp;15?32:10);O&amp;15&amp;&amp;puts("");}
// 78
O;main(l){for(;~l;(O=~(l=getchar())?printf("%02x ",l),-~O&amp;15:!O)||puts(""));}
// 77
O;main(l){for(;~l;(O=~(l=getchar())?-~O&amp;printf("%02x ",l)*5:!O)||puts(""));}
// 76
O;main(l){for(;~l;O||puts(&amp;O))O=~(l=getchar())?-~O&amp;printf("%02x ",l)*5:!O;}
</code></pre>
<p>It is possible to reduce the size of each of these by one by eliding the trailing newline.
This was not reported above since the newline kept getting appended by processing software,
and it is more interesting to remove characters by changing code than by filtering:</p>
<pre><code>$ tr -d '\012' &lt; 109.c | wc -c
108
$ tr -d '\012' &lt; 76.c | wc -c
75
$ tr -d '\012' &lt; 109.c | cc -o 108 -xc -
$ verify 108
$
</code></pre>
<p>An obfuscated hex dump has been done before:
<a href="http://ioccc.org/1986/bright/bright.c">1986/bright/bright.c</a> is similar in function,
but it uses more characters in just setting up its obfuscation than this entire solution!</p>
<h2>BIGGER SPOILER</h2>
<p>If you are unhappy with the way DEL (character 127) is handled,
replace the cryptic expression <code>4&lt;(4^l&gt;&gt;5)?l:46</code> with <code>32&gt;l|l&gt;126?46:l</code>.
Both take the same number of characters, but the former is a bit more interesting.
Bonus question: how does the first expression work?</p>
<h2>BIGGEST SPOILER (and some history)</h2>
<p>Technically, <code>char o[0];</code> is illegal (SS 6.7.6.2) according to ISO (N1570).
And <code>char o[];</code> is a conditionally supported feature (SS 6.7.6.2, 6.10.8.3).
However, it works in modern C implementations as an extension,
including GCC, Clang and TCC, for X86 and ARM,
on multiple operating systems (Linux, OSX, FreeBSD), so it is <em>functionally</em> correct.
MicroSoft Visual C++ does not allow <code>char o[]</code> or <code>char o[0]</code>,
and implements its close relative <code>char o[1]</code>
such that writing more than a single char will cause a fault, which is <em>technically</em> correct.</p>
<p>But how does this work at all, even as an extension?
<code>o[]</code> allocates one(!) byte in a zero-filled data area (formerly BSS).
The UNIX-derived systems this code was run upon all place the
storage of <code>O</code> and <code>o</code> into a zero-filled VM page with nothing following:
thus, there are plenty of available and unused zero bytes following <code>O</code>, addressed via <code>o</code>,
and this code only needs 17.
This is <em>undefined</em> behavior, but as shown, it is widely available.</p>
<p>The <a href="http://minnie.tuhs.org/cgi-bin/utree.pl">1979 Seventh Edition UNIX</a> (v7) system pre-dates the IOCCC by several years,
and the source code to <code>sh</code>(1) was a <a href="http://ioccc.org/all/README">significant inspiration for this contest</a>.
There are two C compilers present: <code>cc</code> written by Dennis Ritchie, and <code>pcc</code> written by Steven Johnson.
The nested conditional expressions in 116 and smaller are too complex for <code>cc</code> (&ldquo;Illegal conditional&rdquo;)
but <code>pcc</code> handles them correctly, and neither compiler accepts <code>char o[]</code> or <code>char o[0]</code> nor puts the bytes in
a zero-filled page (as a paged VM was not yet written for UNIX).</p>
<p>More significant is that v7 <code>printf</code>(3) does not report the number of characters written,
and therefore 111 compiles but does not work correctly;
113 is the shortest code that compiles and runs correctly in Ancient UNIX.</p>
<blockquote><p>Interesting digression: v7 <code>printf</code> (<code>_doprnt</code>) was written in PDP-11 assembler.
It pre-dates <code>varargs.h</code>, and assembly was the only way to gain access to the variable argument types.
The first edition <em>The C Programming Language</em>, 1978, page 71, remarks:</p>
<blockquote><p>By the way, there is no entirely satisfactory way to write a portable function
that accepts a variable number of arguments, because there is no portable way
for the called function to determine how many arguments where actually passed to it in a given call.
&hellip;
<code>printf</code>, the most common C function with a variable number of arguments,
&hellip; is also non-portable and must be modified for different environments.</p></blockquote>
<p>It is fascinating to explore the roots of C through the history of the operating system
it was birthed within. C is often criticized as a difficult, inscrutable language,
but as this contest demonstrates, this is in parody.
<em>Shell-gol</em> is one of those instances where someone <a href="http://www.computerworld.com.au/article/279011/a-z_programming_languages_bourne_shell_sh/?pp=4">preferred a different language</a>,
and (ab)used the preprocessor to re-mold C into something they found comfortable.
Most of the rest of the system, especially in the kernel,
are models of clarity and efficient expression.</p></blockquote>
<h2>TL;DR</h2>
<p>So which version is the shortest, portable hex dump?</p>
<ul>
<li>109 works with (most?) modern Unix-like systems and compilers, see example list above.</li>
<li>111 works adds Microsoft, is standards-approved, and does not exploit undefined behavior.</li>
<li>113 works on Ancient UNIX and the portable C compiler.</li>
<li>119 works on all platforms, including the original Ritchie PDP-11 C compiler.</li>
</ul>
<h2>Coda</h2>
<p>Clearly, the smallest possible program violates modern best practice.
It is not even possible to compile cleanly, but it will compile correctly.</p>
<p>Included is <code>prog.nowarn.c</code>, a modern C implementation that is &ndash; perhaps &ndash; the smallest,
clean-compiling version using <code>clang</code> or <code>gcc</code> with <code>-Wall -pedantic</code>.
Note that while this is larger than all but the original attempt,
it will <em>not</em> work with the original Ritchie PDP-11 C compiler,
since the expression within the ternary remains too complex.</p>
<p>Try</p>
<pre><code>cat prog.c prog.nowarn.c
</code></pre>
<p>to compare the differences (<code>diff</code> is not helpful on a one-liner).</p>
<hr />
<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-2018,
<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>
-428
View File
@@ -1,428 +0,0 @@
<!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 abuse of the rules</title>
</head>
<body>
<h1>Best abuse of the rules</h1>
<p>Dave Burton<br>
<a href="http://ioccc.snox.net">http://ioccc.snox.net</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog [-tcksri] &lt; file.c
</code></pre>
<h3>Try:</h3>
<pre><code>./prog -i &lt; prog.c
./prog -s &lt; prog.c
./prog -sk &lt; prog.c
</code></pre>
<p>If you get stuck, try:</p>
<pre><code>make test
</code></pre>
<p>If you get really stuck, try:</p>
<pre><code>man ./tac.man
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>They say size isn&rsquo;t everything, and in the case of IOCCC <a href="/2018/iocccsize.c">iocccsize.c</a>
that is saying something! What is this program weighing and how much does it weigh?</p>
<h2>Author&rsquo;s comments:</h2>
<h2>tac - tokenize and count C and derivative languages</h2>
<blockquote><pre style="font-style:italic">
tac computes C program size
(obfuscated / otherwise)
by splitting code as tokens small,
ignoring space, then counting all.
It tries quite hard to act the same
as counting tool of I-OCCC fame.
Some bugs were fixed, it's faster too,
and does more things, just add some glue!
It does far more than print the size:
the token part's a better prize!
With each upon on a single line,
how many things can you design?
Included is a keyword sorter,
de-obfuscator, freq reporter.
With code produced as little parts,
just add your own creative arts.
But first you have to figure out
the braces part, without a doubt!
And then the code - it isn't easy:
for as else? That's rather cheesy!
The rest of it is standard fare:
expressions strange, the globals bare,
confusing symbols one and oh,
and precedence you have to know.
The keyword list was made external,
because of standards change eternal.
Thus other languages can now,
be counted just like C, somehow!
I hope you find this code obscure
enough to win, and thus procure
a public place for all to see
how badly I can butcher C!
</pre></blockquote>
<h2>Said another way&hellip;.</h2>
<p><code>tac</code> is the inverse of <code>cat</code>(1): it un-concatenates its input into C tokens,
writing the token stream to stdout. There are options to suppress the token ids,
summarize the token counts, and several options to allow it to be compatible
with <code>iocccsize</code>.</p>
<p>The token-based output is quite useful in analyzing source code (see below),
and the counter is more accurate than <code>iocccsize</code> (see below); but this can be
fixed by using the -c compatibility flag, restoring the following problems as
in the official tool:</p>
<ul>
<li>whitespace <strong>within</strong> a string is <strong>not</strong> counted;
this seems wrong, as these chars <strong>are</strong> significant</li>
<li>&ldquo;<code>{;}</code>&rdquo; is not counted within a double-quoted string</li>
<li>whitespace preceding a comment is char-counted, unless the comment starts a line</li>
<li>-k processes the reserved words within <code>//</code> comments(!), but not <code>/*</code>, changing the counts</li>
</ul>
<p>The following bugs are always corrected:</p>
<ul>
<li>treats <code>/*/</code> as a complete comment (<code>/*/int if for/*/</code> has three keywords)</li>
<li>-k enables <code>//*</code> or within a line comment <code>/*</code> to initiate a comment block until following <code>*/</code></li>
<li>-k processes double quote characters in <code>//</code> comments -
thus a solitary quote consumes everything until the next quote</li>
<li>single quotes are not handled correctly (<code>'"'</code> starts a dquote in <code>iocccsize</code>)</li>
<li><code>#ifndef</code> is omitted as a keyword (but <code>#ifdef</code> is allowed?)</li>
<li>I is not a reserved word.</li>
<li><code>tac</code> correctly penetrates <a href="http://ioccc.org/2014/birken/hint.html" title="Best use of port 1701">23rd century cloaking technology</a>. ;-)</li>
</ul>
<p>There is one (known) remaining problem with detection:</p>
<ul>
<li><p>comments between preprocessor hash and keyword are not replaced with whitespace;
the following counts #include as two tokens, <code>#</code> and <code>include</code> (not as a reserved word):</p>
<pre><code> #/*this will not be counted*/include/*correctly*/&lt;stdio.h&gt;
</code></pre></li>
</ul>
<p>Fixing this properly hampers backwards compatibility in counting. This requires
eliding comments during readsource (ISO 5.1.1.2, phase 3), and yet still
counting words correctly absent -k.</p>
<h2>Backwards Compatibility</h2>
<p><code>tac</code> was run over all 366 previous IOCCC winning entries:</p>
<pre><code>find ~/src/obc -type f -name \*.c | wc
</code></pre>
<p>The discrepancies found are documented and explained in the file &ldquo;discrepancies&rdquo;.</p>
<pre><code>find ~/src/obc -type f -a -name "*.c" | xargs ./spotcheck ./prog | ./spotdiff |
grep -v keep | diff -bw - discrep* | grep "[&lt;&gt;] cl "
</code></pre>
<p>In summary, there are only 6 unique entries out of 366 that have any variation
in Rule 2 counts; in all cases, the differences are due to bugs within
<code>iocccsize</code>, described in detail in the file <code>discrepancies</code>. There are only 40
files (40/366, ~11%, including originals and variations) that differ at all, 31
only in word count; most word count differences appear related to comment block
detection, weighted more towards recent entries (2011 and onward = 20/40 ~50%).</p>
<p>This (minor) variation in word count values has not been addressed since
it is not a qualifying metric, nor is it very useful in a programming context:
whitespace surrounds English words, not necessarily C tokens, as in <code>a+=1;</code>.</p>
<p>Accuracy (versus compatibility) is demonstrated through a series of small test cases
designed to allow exhaustive, hand-counted values for comparison with the tool values.
These test cases were vital in debugging and regression testing, and provided a way to
determine which tool was correct when there were differences.</p>
<blockquote><p>A version of this tool in more clearly written C (tac.c)
is presented for the Judge&rsquo;s consideration as a more accurate replacement for <code>iocccsize</code>.
This obfuscated entry is derived from (and compatible with) that code,
but due to obfuscation, has had some significant, deep changes for the contest.
Nevertheless, the more clearly written code remains a spoiler for this entry.</p></blockquote>
<p>NB: <code>iocccsize</code> gets a different answer from <code>tac</code> on its own (iocccsize.c) source code;
<code>tac</code> gets the correct answer. This is due to the aforementioned bugs within <code>iocccsize</code>,
proved by fixing iocccsize.c with the included patch, so <code>iocccsize</code> reports
the correct answer for itself.</p>
<h2>But wait&hellip; There&rsquo;s More!</h2>
<p>There is no limit on line length, file length, comment length, or identifier length.</p>
<p><code>tac</code> features an accurate tokenizer; which presents each C token on a line by itself.
This feature enables interesting analyses of C (and C++) code, hard to get any other way.</p>
<p>For instance, here is a simple token counter, useful in finding repeated long tokens, or operator
frequency, or counting the references to identifiers, constants, or breadth of use of the
language:</p>
<pre><code>!/bin/sh
cat $* | ./prog -t | sort | uniq -c | sort -k1nr
</code></pre>
<p>And here is a C keyword frequency counter:</p>
<pre><code>#!/bin/sh
function iskeyword {
awk 'BEGIN{f="c11";while(getline&lt;f)k[$1]=0}
{if($1 in k)k[$1]++}END{for(i in k)print k[i],i}'
}
cat $* | ./prog -t | iskeyword | sort -k1nr
</code></pre>
<p>This script was used to &ldquo;optimize&rdquo; the reserved word order so the most frequent IOCCC
winning entry keywords are checked first.</p>
<blockquote><p>An interesting aside: as might be expected, obfuscation has changed the frequency of
keyword distribution over time. The top five for the decades:</p>
<pre><code> 1980s 1990s 2000s 2010s
----- ----- ----- -----
94 if 532 char 375 if 254 int
69 for 524 if 372 char 217 for
59 while 417 int 332 int 198 if
48 char 223 for 184 for 121 return
43 int 223 void 165 return 104 char
</code></pre></blockquote>
<p>The keyword list is external to the program, and is easily changed, sorted, checked, verified.
This allows such additional programs in concert with the tool&rsquo;s primary operation.</p>
<p>A poor-man&rsquo;s de-obfuscator can be based upon the output of <code>tac -t</code> and a handful of
simple rules (and another use of the external keyword file).
A more refined version of this is included in the file <code>unob.sh</code>,
but the simple code below is a serviceable obfuscated C de-obfuscator in a <em>scripting language</em>.
It really is this easy with <code>tac</code>:</p>
<pre><code>#!/bin/sh
script='
BEGIN {
last=nl="\n";
f="c11"; while(getline &lt;f &gt; 0) kw[$0]++; close(f);
}
function iskw(a) { return a in kw }
function indent(a) { return sprintf("%*s", n*3, " ") }
function newline() { if (!infor &amp;&amp; last != nl) printf last=nl; }
function show(a) {
if (last==nl) printf "%s", indent()
printf "%s%s", space(), a
last=a
}
function space() {
return iskw(last) ||
(last ~ /[A-Za-z0-9_+-\/%^[&amp;\]\)=:&lt;&gt;;]$/ &amp;&amp; $0 !~ /[:;()\[\],]/) ? " " : ""
}
/^\(/ { ++paren }
/^\)/ { --paren }
/^for/ { newline(); infor=1 }
infor &amp;&amp; /^;/ { ++infor; show($0 " "); next }
infor==1 &amp;&amp; /^:/ { ++infor }
infor&gt;1 &amp;&amp; paren==0 { infor=0 }
/^\?/ { tern++; n++; newline(); show($0 " "); next }
tern &amp;&amp; /^:/ { newline(); show($0); --tern; --n; next }
/^#/ { newline(); show($0); newline(); next }
/^;/ { show($0); newline(); next }
/^{/ { show($0); ++n; newline(); next }
/^}/ { n--; newline(); show($0); newline(); next }
{ show($0) }
'
cat $* | sed 's/#include/##include/' | cpp -E -trigraphs |
sed 's/^# .*$//' | sed 's/^#//' |
./prog -t | awk "$script"
</code></pre>
<h2>On the question of obfuscation</h2>
<ul>
<li><p>I assume you noticed the <a href="https://www.youtube.com/watch?v=fUspLVStPbk&amp;start=53" title="Meaning of Life">braces</a>?</p>
<p><em>Every brace is sacred,<br>
Every brace is great.<br>
If a brace is wasted,<br>
Clang gets quite irate</em>.</p></li>
<li><p>Keywords follow the 2010s top five, without the <code>if</code>, for interesting flow control.</p></li>
<li>Sometimes a <code>for</code> can be an <code>else</code> - <a href="https://www.youtube.com/watch?v=OHVjs4aobqs" title="Inconceivable">inconceivable</a>!</li>
<li>I see the <code>getopt</code>. But &ldquo;<a href="https://www.youtube.com/watch?v=Ug75diEyiA0" title="Where's the beef?">where&rsquo;s the beef?</a>&rdquo;</li>
<li><p>No character constants, several int constants, and one string
(hint: which does not encode letters) &ndash; how does this code parse code?</p>
<blockquote><p>Interesting aside: how many is &ldquo;several int constants&rdquo;?</p>
<pre><code> ./prog &lt; prog.c 2&gt;/dev/null | awk '$1~/260/{a[$2]++}END{for(i in a)print i,a[i]}'
... | wc
</code></pre>
<p>Which numbers are most often used?</p>
<pre><code> ... | sort -k2nr | sed 5q
</code></pre></blockquote></li>
<li><p>The code describes its function by careful arrangement of variables up front&hellip;</p></li>
<li>&hellip;coupled with a description of the typical IOCCC contestant, or at least the author</li>
<li>Why shouldn&rsquo;t trigraph parsing be written in trigraph?</li>
<li>Where iocccsize.c mocks, this code flaunts:
&ldquo;<em>no matter how well you may think you understand this code, you don&rsquo;t, so don&rsquo;t mess with it. :-)</em>&rdquo;</li>
<li><code>O,0,l,1</code> are used to confusing effect, local names obscure global names.</li>
<li>Globals are used to pass information between routines: don&rsquo;t reorder &ldquo;unrelated&rdquo; statements&hellip;.</li>
<li>How does the compatibility mode account for the fundamentally different manner of computation?</li>
<li>The algorithm is quite efficient; reserved word detection and trigraph parsing particularly so.</li>
<li>This may be the first obfuscated submission that provides the means for its own de-obfuscation.</li>
</ul>
<h2>Rule 2</h2>
<p>The keyword list is externalized as an include file. This presents a useful
feature for the source code: not only can the reserved word script above be
produced, but the tool can be rebuilt with any set of reserved words, just by
using a different list. For instance: removing all the secondary keywords;
removing all the C11 keywords; trying just K&amp;R C. Since C++ and Java share the
same operators as C, just change the keyword list and <code>tac</code> will correctly
tokenize both of these; the tokens >>> and :: can be handled with a short
post-filter (tokenfix, included).</p>
<p>I believe this entry may also satisfy the request for gratuitous use of all the C11 keywords?
Whether this context satisfies &ldquo;intended C language context&rdquo; is a matter of interpretation. ;-)
And <code>tac</code> is ready for the IOCCC++ contest. And the IOJCC trashcan.</p>
<p>The following reserved word files are included:</p>
<pre><code>kandr from my venerable 1978 18th printing "The C Programming Language"
v7unix 7th edition Unix source code, extracted from c00.c
kandr2 from my 1988 1st printing "The C Programming Language", 2e
ansi ANS X3.159-1989
c99 ISO/IEC 9899:1999(E)
c11 ISO/IEC 9899:201x(E) N1570
c++98 http://en.cppreference.com/w/cpp/keyword
c++11 ISO/IEC 14882:2011(E) N3337 2012-01-16
c++14 ISO/IEC 14882:2014(E) N4296 2014-11-09
java8 http://docs.oracle.com/javase/specs/index.html
ioccc.kw.freq c11 + additional words, sorted on frequency of occurrence in ioccc winners
</code></pre>
<p>NB: The keyword file used in this code is derived from the list in iocccsize.c,
which is neither complete (<code>#define</code>, <code>#ifndef</code>, <code>#undef</code> are missing
&ndash; yes, Virginia knows about <code>#define</code> omitted on purpose),
nor correct (many more are added: <code>I</code>, <code>true</code>, <code>bool</code>, <code>compl</code>, &hellip;):</p>
<pre><code>(sed -n '1p' c11; sed -n '2,$p' ioccc.kw.freq | sort) | comm -3 - c11
</code></pre>
<p>That is an obfuscated way to say &ldquo;diff&rdquo;. But it also more clearly shows the, um, diffs.</p>
<p>The usage string is similarly externalized, providing a better usability string than
the limits would otherwise allow. If this is considered bending the rules too far,
just -DU=O to get a passible, if cryptic, usage message using no additional octets
than without the define.
This also allows the builder to configure the amount of help a utility should provide
(<a href="https://www.youtube.com/watch?v=VU0GYSA1POs" title="Ants">you want a manpage? Because that&rsquo;s how you get a manpage.</a>)
&ndash; a rather significant point of contention made moot.</p>
<p>There is definitely abuse of the Rule2 counter, exploiting a &ldquo;feature&rdquo; of <code>iocccsize</code>:
<code>iocccsize</code> does not Rule2 count {, } and ; when followed by whitespace &ndash; even within a string!
Thus: Freecode, a simple, uncounted, highly obfuscated encoding of a central part
of this program. (The reserved word list is not Freecoded, both because it is useful
apart from the program, and because Freecode is not entirely free.*)</p>
<ul>
<li>Some restrictions apply. Not approved for all uses. Some assembly required.</li>
</ul>
<h2>Compilation</h2>
<p>The code is ANSI compliant, but it does have a string longer than 509 characters.
It has been tested on OSX and Linux, Clang and GCC.</p>
<p>The code uses trigraphs, ironically: it parses trigraphs with trigraph code.
Because that&rsquo;s funny. And it remains obscure after, so trigraphs are not used for obfuscation.
Thus -trigraphs -Wno-trigraphs (which is also humorous).</p>
<p>It&rsquo;s obfuscated C. Thus -Wno-parentheses -Wno-empty-body -Wno-char-subscripts.</p>
<p>The code uses unsigned chars, but C strings are signed. Thus -Wno-pointer-sign.
NB: This is <em>not</em> a portability concern, the one string holds only printable ASCII characters.</p>
<p>Thus:</p>
<pre><code>clang -ansi -Wall -trigraphs -Wno-trigraphs -Wno-parentheses -Wno-empty-body -Wno-char-subscripts -Wno-pointer-sign -DU=O -DW=\"keywords\" -o prog prog.c
</code></pre>
<h2>Coda</h2>
<p>Cody Ferguson was relentless in his pursuit of bugs.
Thanks to his reports, the version of <code>unob.sh</code> is stronger,
<code>tac</code> groks digraphs, <code>tokenfix</code> corrects for missing digraphs in <code>prog.c</code>,
and the program <code>manpage</code> was added to the corpus.</p>
<p><code>manpage</code> is a useful program that turns ASCII versions of man pages (e.g. <code>tac.man</code>) into real
man pages. It works for C and C-like languages, command lines,
and was designed to handle man page sections 1-8.
It works well on most inputs, but tends to need some raw nroff for more fancy constructions,
such as combined arguments
(e.g. the -r and -s arguments to tac are not recognised when written as -rs in prose).</p>
<p>Try:</p>
<pre><code>manpage tac
manpage -h
manpage -h | manpage
manpage -h | manpage -R | less
manpage -h | manpage -P | lpr
</code></pre>
<hr />
<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-2018,
<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>
-308
View File
@@ -1,308 +0,0 @@
<!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 likely to be awarded</title>
</head>
<body>
<h1>Most likely to be awarded</h1>
<p>Marcin Ciura <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#111;&#58;&#x6d;&#x63;&#105;&#x75;&#114;&#97;&#64;&#103;&#109;&#97;&#105;&#x6c;&#x2e;&#x63;&#x6f;&#109;">&#x6d;&#99;&#x69;&#117;&#x72;&#97;&#64;&#103;&#x6d;&#97;&#x69;&#x6c;&#46;&#x63;&#x6f;&#x6d;</a><br>
Twitter: @mciura</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &lt; text
</code></pre>
<h3>Try:</h3>
<pre><code>./prog &lt; Makefile
./prog &lt; hint.text
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>This text was processed by prog. You may get confused.
We&rsquo;re not really sure: prog.c wasn&rsquo;t commented.
Who has been thoroughly puzzled by prog? Also how obfuscated is prog?
Having been written in C, how large of a vocabulary has it?</p>
<h2>Author&rsquo;s comments:</h2>
<h1>The Program</h1>
<p>&ldquo;The Elements of Style&rdquo; by prof. William Strunk, Jr. and E. B. White
is well known for its dislike of the passive voice. Direct, vigorous,
active constructions were instead recommended by the authors.
The development of this program has been driven by this tenet.</p>
<p>Only passive sentences from the standard input are output. The offending
part(s) of each sentence will be highlighted. Several kinds of passive
constructions are recognized:</p>
<ul>
<li>Plain passive voice.
Foo was bazzed by bar.</li>
<li>Passive voice with &ldquo;get&rdquo;.
I got almost quuxed.</li>
<li>Contractions.
I&rsquo;m not really quuxed: foo wasn&rsquo;t bazzed.</li>
<li>Questions.
Who has been quuxed? Was foo indeed bazzed? How was it bazzed?</li>
<li>Clause-initial inversion.
Also bazzed is bar.</li>
</ul>
<p>Sentences are never broken by periods that follow abbreviations and
initials. Both regular and irregular past participles are properly
dealt with. Note that some words are red herrings: even though their
ending is -ed, they are not past participles.</p>
<h1>The Big String</h1>
<p>Here is the purpose of every byte inside the <strong><code>c[]</code></strong> string:</p>
<ul>
<li>0-9: highlighting passive constructions in the output;</li>
<li>10-50: classifying characters - called by <strong><code>V(4)</code></strong>;</li>
<li>52: outputting the newline character;</li>
<li>51-187: tokenizing text and detecting passive constructions - two
type A state machines, called by <strong><code>V(2)</code></strong> and <strong><code>V(3)</code></strong>;</li>
<li>186-2786: determining word categories (past participles, present
simple and past simple forms of &ldquo;to be&rdquo;, other forms of &ldquo;to be&rdquo;,
adverbs, wh-words, and other words) and recognizing abbreviations -
two type B state machines, called by <strong><code>V(808)</code></strong> and <strong><code>V(205)</code></strong>.</li>
</ul>
<h1>The State Machines</h1>
<p>I heard you don&rsquo;t like state machines so I put a state machine in your
state machine so you can reject this entry while you reject this entry.</p>
<p>Both types of state machines in the program are Mealy machines: we can
think of their transitions as triples (<strong><code>transition_label</code></strong>,
<strong><code>next_state</code></strong>, <strong><code>output</code></strong>).</p>
<h2>Type A</h2>
<p>A state of type A state machine consists of eight transitions whose
representations occupy consecutive bytes. The byte
<strong><code>c[3 + 8*state + transition_label]</code></strong> contains
<strong><code>(unsigned char)(30 + 5*next_state + output)</code></strong>.</p>
<p>The <code>transition_label</code> is either one of character classes:</p>
<ul>
<li><strong><code>nil</code></strong> = 0,</li>
<li><strong><code>space</code></strong> = 1,</li>
<li><strong><code>new_line</code></strong> = 2,</li>
<li><strong><code>uppercase</code></strong> = 3,</li>
<li><strong><code>lowercase</code></strong> = 4,</li>
<li><strong><code>period</code></strong> = 5,</li>
<li><strong><code>bang_question</code></strong> = 6,</li>
<li><strong><code>punctuation</code></strong> = 7,</li>
</ul>
<p>or one of word classes:</p>
<ul>
<li><strong><code>adverb</code></strong> = 0,</li>
<li><strong><code>other</code></strong> = 2,</li>
<li><strong><code>past_participle</code></strong> = 3,</li>
<li><strong><code>to_be</code></strong> = 4,</li>
<li><strong><code>are_were</code></strong> = 5,</li>
<li><strong><code>wh_word</code></strong> = 6 (cf. the <strong><code>output</code></strong> of type B state machines).</li>
</ul>
<p>The <strong><code>output</code></strong> is either one of:</p>
<ul>
<li><strong><code>end_of_text</code></strong> = 0,</li>
<li><strong><code>sentence_start</code></strong> = 1,</li>
<li><strong><code>sentence_end</code></strong> = 2,</li>
<li><strong><code>token_end</code></strong> = 3,</li>
<li><strong><code>ignore</code></strong> = 4,</li>
</ul>
<p>or one of</p>
<ul>
<li><strong><code>passive_construction_start</code></strong> = 1,</li>
<li><strong><code>ignore</code></strong> = 2,</li>
<li><strong><code>passive_construction_end</code></strong> = 3.</li>
</ul>
<p>Type A state machines run continuously. Their state is kept in
<strong><code>k[2]</code></strong> and <strong><code>k[3]</code></strong>.</p>
<p>Below are sample steps of scanning a sequence of characters with
classes <strong><code>uppercase</code></strong>, <strong><code>lowercase</code></strong>, <strong><code>period</code></strong>, <strong><code>space</code></strong>,
and <strong><code>uppercase</code></strong>.</p>
<ul>
<li><strong><code>state</code></strong> = 7, <strong><code>transition_label</code></strong> = 3 (<strong><code>uppercase</code></strong>), <strong><code>output</code></strong> = <strong><code>sentence_start</code></strong></li>
<li><strong><code>state</code></strong> = 14, <strong><code>transition_label</code></strong> = 4 (<strong><code>lowercase</code></strong>), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
<li><strong><code>state</code></strong> = 15, <strong><code>transition_label</code></strong> = 5 (<strong><code>period</code></strong>), <strong><code>output</code></strong> = <strong><code>token_end</code></strong></li>
<li><strong><code>state</code></strong> = 13, <strong><code>transition_label</code></strong> = 1 (<strong><code>space</code></strong>), <strong><code>output</code></strong> = <strong><code>token_end</code></strong></li>
<li><strong><code>state</code></strong> = 18, <strong><code>transition_label</code></strong> = 3 (<strong><code>uppercase</code></strong>), <strong><code>output</code></strong> = <strong><code>sentence_end</code></strong></li>
</ul>
<p>And here are sample steps of scanning tokens with classes <strong><code>to_be</code></strong>,
<strong><code>adverb</code></strong>, <strong><code>past_participle</code></strong>.</p>
<ul>
<li><strong><code>state</code></strong> = 8, <strong><code>transition_label</code></strong> = 4 (<strong><code>to_be</code></strong>), <strong><code>output</code></strong> = <strong><code>passive_construction_start</code></strong></li>
<li><strong><code>state</code></strong> = 22, <strong><code>transition_label</code></strong> = 0 (<strong><code>adverb</code></strong>), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
<li><strong><code>state</code></strong> = 22, <strong><code>transition_label</code></strong> = 3 (<strong><code>past_participle</code></strong>), <strong><code>output</code></strong> = <strong><code>passive_construction_end</code></strong></li>
</ul>
<h2>Type B</h2>
<p>Type B state machines are built by a variant of the algorithm described
in the paper
<em><a href="http://sun.aei.polsl.pl/~mciura/publikacje/lexicon.pdf">How to squeeze a lexicon</a></em>.
Their states are represented as interlaced sparse arrays of transitions.</p>
<p>The <strong><code>transition_label</code></strong> is one of:</p>
<ul>
<li><strong><code>word_start</code></strong> = 0,</li>
<li><strong><code>period_or_apostrophe</code></strong> = 1,</li>
<li><strong><code>a_z_letter</code></strong> = 2..27.</li>
</ul>
<p>The <code>output</code> is either one of word classes:</p>
<ul>
<li><strong><code>adverb</code></strong> = 0,</li>
<li><strong><code>ignore</code></strong> = 1,</li>
<li><strong><code>other</code></strong> = 2,</li>
<li><strong><code>past_participle</code></strong> = 3,</li>
<li><strong><code>to_be</code></strong> = 4,</li>
<li><strong><code>are_were</code></strong> = 5,</li>
<li><strong><code>wh_word</code></strong> = 6,</li>
</ul>
<p>or</p>
<ul>
<li><strong><code>ignore</code></strong> = 1,</li>
<li><strong><code>abbreviation</code></strong> = 2.</li>
</ul>
<p>The byte <strong><code>c[186 + (state + transition_label)] = (unsigned char)(2 + transition_label + 28 * output)</code></strong>.</p>
<p>The byte <strong><code>c[836 + 2*(state + transition_label)] =</code></strong></p>
<ul>
<li><strong><code>' '</code></strong> when <strong><code>next_state / 376 == 0</code></strong>,</li>
<li><strong><code>';'</code></strong> when <strong><code>next_state / 376 == 1</code></strong>.</li>
</ul>
<p>The byte <strong><code>c[837 + 2*(state + transition_label)] =</code></strong></p>
<ul>
<li><strong><code>' '</code></strong> when <strong><code>next_state / 94 % 4 == 0</code></strong>,</li>
<li><strong><code>';'</code></strong> when <strong><code>next_state / 94 % 4 == 1</code></strong>,</li>
<li><strong><code>'{'</code></strong> when <strong><code>next_state / 94 % 4 == 2</code></strong>,</li>
<li><strong><code>'}'</code></strong> when <strong><code>next_state / 94 % 4 == 3</code></strong>.</li>
</ul>
<p>The byte <strong><code>c[2136 + (state + transition_label)] = (unsigned char)(32 + next_state % 94)</code></strong>.</p>
<p>A type B state machine starts in a given <strong><code>state</code></strong> with <strong><code>output</code></strong>
set to <strong><code>ignore</code></strong>. It scans a word backwards, converting character by
character to <strong><code>transition_label</code></strong>. When it meets <strong><code>word_start</code></strong>, it
returns, leaving the most recently stored <strong><code>output</code></strong> in <strong><code>v</code></strong>.
It also returns when
<strong><code>c[186 + (state + transition_label)] != (unsigned char)(2 + transition_label + 28 * output)</code></strong>,
i.e. when the <strong><code>transition_label</code></strong> in the byte mismatches the
<strong><code>transition_label</code></strong> used to compute the index. Otherwise, if the
<strong><code>output</code></strong> in this byte differs from <strong><code>ignore</code></strong>, the state machine
stores it in <strong><code>v</code></strong>. Regardless of the value of the <strong><code>output</code></strong>,
it also assigns <strong><code>next_state</code></strong> to <strong><code>state</code></strong> and proceeds to scan
the previous character. The state machine that determines the word
class is set up so that it never returns <strong><code>ignore</code></strong>.</p>
<p>Below are sample steps of scanning the word &ldquo;chiefly&rdquo;.</p>
<ul>
<li><strong><code>state</code></strong> = 623, <strong><code>transition_label</code></strong> = 26 (&lsquo;y&rsquo;), <strong><code>output</code></strong> = <strong><code>other</code></strong></li>
<li><strong><code>state</code></strong> = 602, <strong><code>transition_label</code></strong> = 13 (&lsquo;l&rsquo;), <strong><code>output</code></strong> = <strong><code>adverb</code></strong></li>
<li><strong><code>state</code></strong> = 594, <strong><code>transition_label</code></strong> = 7 (&lsquo;f&rsquo;), <strong><code>output</code></strong> = <strong><code>other</code></strong></li>
<li><strong><code>state</code></strong> = 549, <strong><code>transition_label</code></strong> = 6 (&lsquo;e&rsquo;), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
<li><strong><code>state</code></strong> = 543, <strong><code>transition_label</code></strong> = 10 (&lsquo;i&rsquo;), <strong><code>output</code></strong> = <strong><code>adverb</code></strong></li>
<li><strong><code>state</code></strong> = 0, <strong><code>transition_label</code></strong> = 9 (&lsquo;h&rsquo;) mismatches the value stored
in the byte. Return <strong><code>adverb</code></strong>.</li>
</ul>
<p>And here are sample steps of scanning the string &ldquo;i.e.&rdquo;:</p>
<ul>
<li><strong><code>state</code></strong> = 19, <strong><code>transition_label</code></strong> = 1 (&lsquo;.&rsquo;), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
<li><strong><code>state</code></strong> = 24, <strong><code>transition_label</code></strong> = 6 (&lsquo;e&rsquo;), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
<li><strong><code>state</code></strong> = 3, <strong><code>transition_label</code></strong> = 1 (&lsquo;.&rsquo;), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
<li><strong><code>state</code></strong> = 2, <strong><code>transition_label</code></strong> = 10 (&lsquo;i&rsquo;), <strong><code>output</code></strong> = <strong><code>ignore</code></strong></li>
<li><strong><code>state</code></strong> = 1, <strong><code>transition_label</code></strong> = 0 (&lsquo;\0&rsquo;), <strong><code>output</code></strong> = <strong><code>abbreviation</code></strong>.
Return <strong><code>abbreviation</code></strong>.</li>
</ul>
<h1>Remarks</h1>
<p>The judges found a bug in the handling of contractions: <strong><code>prog.orig.c</code></strong>
outputs &ldquo;foo wasn'<strong>[t bazzed]</strong>&rdquo;. I fixed the bug in <strong><code>prog.c</code></strong>, making
it output &ldquo;foo <strong>[wasn&rsquo;t bazzed]</strong>&rdquo; instead, and took the liberty to merge
one statement into a <strong><code>for</code></strong> loop inside its <strong><code>main()</code></strong> function.</p>
<p>The program uses a 9,437,187-byte buffer so it probably will not run
on 16-bit and smaller machines without changing the size of array <strong><code>C[]</code></strong>
and the expression <strong><code>9&lt;&lt;20</code></strong> inside the call to <strong><code>read()</code></strong>.</p>
<p>I have tested it on:</p>
<ul>
<li>Linux with gcc version 5.4.0 20160609,</li>
<li>Linux with clang version 3.4-1ubuntu3,</li>
<li>OS/X with Apple LLVM version 6.0 (clang-600.0.57).</li>
</ul>
<p>For a clean compile under c89 and c90, add <strong><code>-Woverlength-strings</code></strong>
to <strong><code>CSILENCE</code></strong>.</p>
<hr />
<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-2018,
<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>
-78
View File
@@ -1,78 +0,0 @@
<!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 tool to reveal holes</title>
</head>
<body>
<h1>Best tool to reveal holes</h1>
<p>Yusuke Endoh<br>
Twitter: @mametter</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &lt; textfile &gt; output.gif
</code></pre>
<h3>Try:</h3>
<pre><code>./prog &lt; golem.txt &gt; golem.gif
./prog &lt; smily.txt &gt; smily.gif
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>To get the best experience, use a GIF viewer that can handle animated gifs.
On OS X you can use Safari using &ldquo;open -a Safari smily.gif&rdquo;</p>
<p>Some things to consider are that this 2.5KiB gem encodes a 96 character 8x8
font (naively this could already take 6144 bytes) and a GIF encoder. But
how does it know which characters are closed?</p>
<p>You should only give this program printable ASCII characters.</p>
<p>Unfortunately this won&rsquo;t run on your PDP8, if you had one, as it needs at
least 2MiB of memory to run in.</p>
<h2>Author&rsquo;s comments:</h2>
<p>This program generates an animated GIF from a plain text. Run:</p>
<pre><code>gcc -o prog prog.c
./prog &lt; invisible.txt &gt; invisible.gif
</code></pre>
<p>Open invisible.gif and then wait a minute. You will see a hidden message.
Can you tell the difference between letters that leaves the mark and ones that does not?</p>
<p>Other examples:</p>
<pre><code>./prog &lt; golem.txt &gt; golem.gif
./prog &lt; smily.txt &gt; smily.gif
</code></pre>
<p>The program itself has a hidden message.</p>
<pre><code>./prog &lt; prog.c &gt; prog.gif
</code></pre>
<hr />
<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-2018,
<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>
-80
View File
@@ -1,80 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Best use of python</title>
</head>
<body>
<h1>Best use of python</h1>
<p>Yusuke Endoh<br>
Twitter: @mametter</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code>make
./prog | tee prog_next.c
make prog_next
./prog_next | tee prog_next.c
make prog_next
./prog_next | tee prog_next.c
make python
make python3
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>And now for something completely different: A program whose metabolic
processes are a matter of interest only to historians. It has kicked the bucket
and departed to that mysterious country from whose bourne no traveller returns!
This is an EX-tremely obfuscated program!</p>
<h2>Author&rsquo;s comments:</h2>
<pre><code> ___-----__
_-- --__
_- _--_ \
_- /\ +-.:.:-+ /\ \
/ \/ |.:.:.:| \/ |
/ |:.:.:.| |
/ |.:.:.:| | ___-----___
| |.:.:| | / \
| |:.:.| | &lt; It's ... |
\ |:.| | \ /
\ || | ---_____---
_--\ |
_- -__ |
__- --___ |
_- |
/ |
| |
</code></pre>
<hr />
<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-2018,
<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>
File diff suppressed because it is too large. Load diff
-80
View File
@@ -1,80 +0,0 @@
<!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 unstable</title>
</head>
<body>
<h1>Most unstable</h1>
<p>Edward Giles</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>sudo apt install libsdl2-dev # Linux
Something else # MacOS
make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code>./prog ioccc.txt
./prog prog.c
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Can you explain the behavior of the program when ioccc.txt is given to it as input?</p>
<p>How would the description of the state machine look like when translated from
Polynomish to English?</p>
<h2>Author&rsquo;s comments:</h2>
<h1>Remarks</h1>
<p>This entry graphically displays a simulation of sand falling.
It uses SDL to draw the interface.</p>
<p>The code makes the following assumptions about the underlying system:</p>
<ul>
<li>SDL 2 is installed from https://libsdl.org</li>
<li>&ldquo;double&rdquo; is an IEEE 754 floating-point type and sizeof(double)==8</li>
<li>The compiler supports the C99 standard</li>
</ul>
<p>In order to simulate the motion of the sand, a cellular automaton is used. The
state transition table is not stored directly. Instead, the program stores the
coefficients of a polynomial that map each state to the correct one. These
coefficients are stored as raw hexadecimal in the V[] array, and they are
reinterpreted as doubles when used. This allows more numeric precision in fewer
characters (base 16 > base 10), and makes the purpose of the array less clear.</p>
<p>The code is laid out graphically as a bucket pouring sand, and it is far easier
to observe this high-level layout than the code&rsquo;s actual function.</p>
<p>The preprocessor is used to both obfuscate the code as a whole and abbreviate
the calls to SDL. Additionally, throughout the code, the variables were named
so that they are short and easily confused with each other.</p>
<hr />
<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-2018,
<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>
-64
View File
@@ -1,64 +0,0 @@
<!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 likely to top the charts</title>
</head>
<body>
<h1>Most likely to top the charts</h1>
<p>Qiming HOU</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &lt; input.json &gt; output.html
</code></pre>
<p>View <code>output.html</code> in a browser.</p>
<h3>Try:</h3>
<pre><code>grep -e '[-?+*/^&amp;|.&lt;&gt;=]' prog.c
(cd ..; ls -lS */prog.c) | \
awk 'BEGIN { print "["; } { print "{\"winner\":\"",$9,"\", \"size\":",$5,"},"} END { print "]"}' \
&gt; ioccc.json
./prog &lt; ioccc.json &gt; ioccc.html
</code></pre>
<p>What&rsquo;s not right with the output? How to fix it?</p>
<h3>Selected Judges Remarks:</h3>
<p>This entry exhibits a way of obfuscation we haven&rsquo;t seen before, we think.
The rulez of programming in an imperative language are violated, aren&rsquo;t they?</p>
<p>Try figuring out how to increase the number of different colors, if you can.</p>
<h2>Author&rsquo;s comments:</h2>
<p>Nowadays almost every programmer needs to do some Web chore. With all the open source stuff readily available, often we just need to call a bunch of libraries to generate an HTML page from a JSON feed.</p>
<p>This entry takes such decadence to an extreme. It just calls a bunch of libraries to generate an HTML page from a JSON feed, literally. There is no variable (function parameters included), no operator, no flow control statements except a few decorative returns. In compliance to production coding standards, the code is littered with fashionable jargon, doxygen comment, and license text.</p>
<p>As one would expect from such an approach, this program is much more resource intensive than it should be. And one needs a C99-compatible libc (with the common UNIX stuff) to build this and an HTML5-compatible browser to open the result. And it terminates with an assertion failure, but who cares if the web page is already generated?</p>
<hr />
<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-2018,
<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>
-753
View File
@@ -1,753 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta name="GENERATOR" content="mkd2html 2.1.5a DL=DISCOUNT">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<link rel="stylesheet"
type="text/css"
href="../hint.css">
<title>Best of show</title>
</head>
<body>
<h1>Best of show</h1>
<p>Christopher Mills <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#111;&#58;&#x6d;&#x72;&#120;&#x6f;&#64;&#115;&#111;&#110;&#105;&#99;&#46;&#x6e;&#x65;&#x74;">&#x6d;&#114;&#x78;&#111;&#x40;&#115;&#x6f;&#110;&#105;&#99;&#x2e;&#110;&#x65;&#x74;</a><br>
Twitter: @MisterXopher</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<pre><code>make
./prog
(At the "&gt;boot" prompt, type return)
(At the ":" prompt, type "rk(0,0)rkunix")
NOTE: To quit, press Control-E
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Do small machines only need small programs? This program weighs in at just
3636 bytes, which is considerably lighter than the original machine it can replace.</p>
<p>This program can take you back to the start of everything, it is possible to
run v0. Just type:</p>
<pre><code>make
./v0
NOTE: To quit v0, press Control-E
</code></pre>
<p>You will be greeted with a familiar prompt of &ldquo;login&rdquo;. The username and
password are &ldquo;dmr&rdquo; and &ldquo;dmr&rdquo;. To make things more familiar you&rsquo;ll need to
create &lsquo;.&rsquo; as it hasn&rsquo;t been invented yet on this image!</p>
<pre><code>@ ln dd dmr .
</code></pre>
<p>An &ldquo;ls&rdquo; will reveal that C hasn&rsquo;t been invented yet! IOBCC anyone? The
compiler is &ldquo;bc&rdquo;. It producess assembly, which will then need to be assembled
together in this order &ldquo;ops.s bl.s hello.s bi.s&rdquo; to produce a.out!</p>
<p>But wait, we said this was the start of it all! This program can also run a
program that replaces an even larger machine that can run BSD 2.9. To start this,</p>
<pre><code>make
./prog
(At the "&gt;boot" prompt, type return)
(At the ":" prompt, type "rk(0,0)rkunix")
NOTE: To quit prog, press Control-E
</code></pre>
<p>This should now be very familiar and it is possible to compile and run one of
the very first IOCCC entires &ldquo;mullender.c&rdquo;</p>
<p>But wait, there is even more! Try:</p>
<pre><code>make
./v6
(At the "@" prompt, type "rkunix")
NOTE: To quit v6, press Control-E
</code></pre>
<h2>Author&rsquo;s comments:</h2>
<blockquote><p> <em>This IOCCC entry is dedicated to the late Dennis M. Ritchie</em></p></blockquote>
<h1>The Program</h1>
<p>Since this is the 25th &ldquo;annual&rdquo; IOCCC, I thought I should mark the occasion
with a look back to its earliest roots. At the same time the contest enters
its 34th year of providing a safe forum for poor C code, the C language
itself is fast approching its 50th anniversary, along with the UNIX operating
system whose history is so entwined with.</p>
<p>The program delivered here is both a full machine emulation of the original
PDP-7 that Ken Thompson used to write the first version of UNIX and a full
machine emulation of the PDP-11/40 used by subsequent UNIXes. The <code>Makefile</code>
can build versions that can run each of the following:</p>
<ol>
<li> UNIX v0 for the PDP-7 (circa 1969)</li>
<li> Research UNIX Version 6 (circa 1975)</li>
<li> BSD 2.9 (circa 1983)</li>
</ol>
<p>For reasons to be described in a bit, the last (BSD 2.9) is the default.</p>
<h2>Building and Running BSD 2.9</h2>
<p>To run BSD 2.9, do <code>make</code> to build <code>prog</code> and then <code>./prog</code> to run it.</p>
<p>You should see a prompt from the first-stage bootloader that looks like</p>
<pre><code> &gt;boot
</code></pre>
<p>Type <code>RETURN</code> at this point and you will get to the second-stage boot loader
that looks like</p>
<pre><code> 40Boot
:
</code></pre>
<p>The 40 in the prompt indicates that the bootloder has correctly determined
that we are running on a PDP-11/40.</p>
<p>At this point, type the rather cryptic command <code>rk(0,0)rkunix</code> &ndash; this tells
the system to look at the first partition on the first RK05 fixed disk, find
the <code>rkunix</code> file and load it. You should eventually see the following:</p>
<pre><code> &gt;boot
40Boot
: rk(0,0)rkunix
Berkeley UNIX (Rev. 2.9.1) Sun Nov 20 14:55:50 PST 1983
mem = 135872
CONFIGURE SYSTEM:
xp ? csr 176700 vector 254 skipped: No CSR
rk 0 csr 177400 vector 220 attached
hk ? csr 177440 vector 210 skipped: No CSR
rl ? csr 174400 vector 160 skipped: No CSR
rp ? csr 176700 vector 254 skipped: No CSR
ht 0 csr 172440 vector 224 skipped: No CSR
tm 0 csr 172520 vector 224 skipped: No CSR
ts 0 csr 172520 vector 224 skipped: No CSR
dh ? csr 160020 vector 370 skipped: No CSR
dm ? csr 170500 vector 360 skipped: No autoconfig routines
dz ? csr 160110 vector 320 skipped: No CSR
dz ? csr 160110 vector 320 skipped: No CSR
dn 0 csr 175200 vector 300 skipped: No autoconfig routines
vp ? csr 177500 vector 174 skipped: No autoconfig routines
lp ? csr 177514 vector 200 skipped: No CSR
Erase=^?, kill=^U, intr=^C
#
</code></pre>
<p>Congratulations, you are running BSD UNIX 2.9 in single-user mode as root.</p>
<p>On the other hand, if you did a typo somewhere, the boot loader has probably
crashed and halted &ndash; if so, type Control-E to quit the simulation and try
again. If you did really badly, you might have corrupted the virtual disk.
If so, consider a <code>make clean</code> to start from scratch.</p>
<p>Assuming you managed to type 15 characters correctly, You should be at the
root prompt. Most of the commands you are familiar with work here (this was
only a quarter of a century ago &ndash; how much could things have changed?).
Let&rsquo;s try some:</p>
<pre><code> # ls
.cshrc .profile boot hkunix mnt tmp
.login 2.9stamp dev lib mullender.c unix
.msgsrc bin etc lost+found rkunix usr
# df
Filesystem Mounted on kbytes used free % used
/dev/rk0 / 1958 1688 270 86%
# cc mullender.c
# ./a.out
</code></pre>
<p>The program you&rsquo;ve just run was the <a href="http://ioccc.org/1984/mullender/mullender.c" title="mullender.c">winner of the first IOCCC contest from
1984</a> (or was it 1894?), a personal favorite of mine. It is rather
tightly bound to running on either a PDP-11 or a VAX. Now you have one.</p>
<p>Hitting Control-C will return you to the BSD UNIX prompt. Hitting Control-D
will log you out of the single-user session and get you back to the <code>:login:</code>
prompt. Here you can log in as <code>root</code> and get a full timesharing session.
Feel free to try things like <code>vi</code>. I&rsquo;ve taken the liberty of editing the
<code>.login</code> and <code>.profile</code> files to set the console to a less traditional setup
so that you don&rsquo;t have to wait for the Model 33 KSR teletype to move its
carriage. I&rsquo;ve also predefined <code>TERM</code> to <code>vt100</code>, which will probably work
well enough with whatever sort of ANSI terminal emulation you are using.</p>
<p>Note that I have not mounted the <code>/usr</code> disk here, so some commands from
<code>/usr/bin</code> will be missing, along with all of the <code>man</code> pages. They are
<a href="http://minnie.tuhs.org/cgi-bin/utree.pl?file=2.9BSD" title="2.9 BSD">available online</a> if you need them. Adding a second RK05 disk was
possible, but I didn&rsquo;t get around to it&hellip; As the Judges can no doubt attest,
&ldquo;Mid 2017&rdquo; creeps up on you quicker than you expect. :)</p>
<p>Once you&rsquo;ve had enough fun in BSD 2.9, type Control-E to exit the emulation.</p>
<h2>Building and Running Research UNIX v6</h2>
<p>Research UNIX v6 and BSD 2.9 use the same executable, but require a different
disk image. Type <code>make v6</code> to build it, then type <code>./prog</code> to run it.</p>
<p>You should see the boot loader prompt which is a single <code>@</code>:</p>
<pre><code> @
</code></pre>
<p>At this point, you again must type a special incantation: <code>rkunix</code>. After that
you should see:</p>
<pre><code> @rkunix
mem = 1035
RESTRICTED RIGHTS
Use, duplication or disclosure is subject to
restrictions stated in Contract with Western
Electric Company, Inc.
#
</code></pre>
<p>You are now running a single-user session of v6 UNIX. You might want to start
with <code>stty -lcase</code> because otherwise everything will be IN ALL CAPS.</p>
<p>Again, if you failed typing seven characters without making a mistake, you
may need to use Control-E to quit the simulation.</p>
<p>Assuming you&rsquo;re more careful than that, we can try a few commands:</p>
<pre><code> @rkunix
mem = 1035
RESTRICTED RIGHTS
Use, duplication or disclosure is subject to
restrictions stated in Contract with Western
Electric Company, Inc.
# STTY -LCASE
# ls
bin
dev
etc
hpunix
lib
mnt
rkunix
rpunix
tmp
unix
usr
# cat &gt; foo.c
main()
{
printf("Hello, World!\n");
}
# cc foo.c
# ./a.out
Hello, World!
</code></pre>
<p>Why is Version 6 interesting? Well, it was the oldest version that I could
find a boot image of that had a C compiler&hellip; This C compiler is recognizably
C, but not quite the same syntax as we have today. It&rsquo;s much closer to the
<a href="https://www.bell-labs.com/usr/dmr/www/kbman.html" title="B Language">B language</a> from which it is derrived. In particular, this C compiler
would not be able to compile <code>mullender.c</code> (as simple as it is), because the
following syntax features don&rsquo;t exist yet:</p>
<ul>
<li>The <code>short</code> data type doesn&rsquo;t exist yet. Only <code>int</code> (<code>short</code> will show
up when <code>long</code> comes, and the port to the Interdata 7/32 starts to make
the idea of portability become important).</li>
<li>Hexidecimal constants don&rsquo;t exist yet. Digital&rsquo;s computers all used
octal.</li>
<li>The array initializer syntax hasn&rsquo;t yet moved to using <code>=</code>. It still uses
the older form taken from B, which looks like <code>array[] { 1, 2, 3 };</code></li>
</ul>
<p>It can still compile &ldquo;Hello World!&rdquo; (note that you must type a Control-D after
you finish entering the code, to let <code>cat</code> see an end-of-file).</p>
<p>This version of UNIX doesn&rsquo;t go into multi-user mode if you do a Control-D.
Single-user mode was entered because the front-panel console switches were
set to the magic number 0173030 (this can be changed with a re-compile).</p>
<p>Once you are done with Version 6, Type Control-E to exit the simulation.</p>
<p>Note that since both BSD 2.9 and UNIX v6 use the same PDP-11/40 emulation
code, and they use the same name for the disk (<code>rk05.fs</code>), if you want to go
back to the BSD simulation, you should either delete <code>rk05.fs</code> or do a
<code>make clean</code> before you do a <code>make</code>.</p>
<h2>Building and Running UNIX v0</h2>
<p>We now set the Wayback Machine to the very start of it all, 1969.</p>
<p><a href="https://www.bell-labs.com/usr/dmr/www/hist.html" title="UNIX history">The story</a> here is interesting and well worth a read. Bell Labs was
pulling out of the Multics project and Ken Thompson and his collegues had
become accustomed to the relatively nice programming environment. They also
enjoyed the early computer game <a href="https://www.bell-labs.com/usr/dmr/www/spacetravel.html" title="Space Travel"><em>Space Travel</em></a> and wanted another system
to run it on. They found a PDP-7 which was already obsolete at the time to
port <em>Space Travel</em> to. The primitive programming environment influenced
Thompson to recreate parts of the Multics experience in the much more
hardware-constrained PDP-7 environemnt. In the summer of 1969, with his wife
out on a month-long vacation, Thompson re-wrote a filesystem emulation he had
been experementing with to include an assembler, a shell, an editor and an
operating system kernel and hence created the first version of UNIX (although
it hadn&rsquo;t been named that yet).</p>
<p>You can try out this version by typing <code>make v0</code>. Since this version is a
native PDP-7 emulation, it gets its own binary. Type <code>./v0</code> to run it. You
should see the login prompt.</p>
<pre><code> login:
</code></pre>
<p>There are two user accounts <code>ken</code> and <code>dmr</code>, with the passwords <code>ken</code> and <code>dmr</code>
respectively. Let&rsquo;s try the Dennis Richie&rsquo;s <code>dmr</code> account:</p>
<pre><code> login: dmr
password: dmr
@ ls
. ?
</code></pre>
<p>Even though this is not Ken&rsquo;s doing, I feel this gives me licence to
include this quote from the BSD <code>fortune</code> program:</p>
<blockquote><p>Ken Thompson has an automobile which he helped design. Unlike
most automobiles, it has neither speedometer, nor gas gauge,
nor any of the numerous idiot lights which plague the modern
driver. Rather, if the driver makes any mistake, a giant &ldquo;?&rdquo;
lights up in the center of the dashboard. &ldquo;The experienced
driver&rdquo;, he says, &ldquo;will usually know what&rsquo;s wrong.&rdquo;</p></blockquote>
<p>What&rsquo;s the deal here? Well, that&rsquo;s a slightly long story. The short version
is we have gone so far back in the history of UNIX that <em>we don&rsquo;t have
filesystem paths yet</em>. In other words, we can&rsquo;t say something like
<code>/bin/ls</code> yet, and the shell can&rsquo;t store that path in <code>$PATH</code> to search for it.
We also haven&rsquo;t invented <code>.</code> or <code>..</code> yet. In fact, the filesystem isn&rsquo;t even
the traditional UNIX tree structure, it&rsquo;s a directed graph of hard links&hellip;</p>
<p><code>ls</code> needs to be able to read &lsquo;<code>.</code>&rsquo;, the current directory. <code>dmr</code>&rsquo;s home
directory doesn&rsquo;t have that yet, but we can make it, because the home
directory has a hard link to <code>dd</code>, which is the directory that holds all
of the user home directories (this will eventually become <code>/</code>, the root
path). We can do</p>
<pre><code> @ ln dd dmr .
</code></pre>
<p>To make the new link (note that <code>ln</code> doesn&rsquo;t support paths either, so you have
to give it three arguments &ndash; a directory in the current dir, a file in that
directory, and the new name).</p>
<p>Now <code>ls</code> will work, and we can try some other things while we are here:</p>
<pre><code> login: dmr
password: dmr
@ ln dd dmr .
@ ls
dd
system
as.s
b_readme
bi.s
bl.s
db.s
hello.b
ops.s
.
@ cat b_readme
Here is how to compile and run hello.b:
@ bc hello.b hello.s
@ as ops.s bl.s hello.s bi.s
I
II
ops.s
bl.s
hello.s
bi.s
@ a.out
Hello, World!
@ bc hello.b hello.s
@ as ops.s bl.s hello.s bi.s
I
II
ops.s
bl.s
hello.s
bi.s
@ a.out
Hello, World!
@
</code></pre>
<p>The last command is invoking the compiler for an exteremely early version of
the <a href="https://www.bell-labs.com/usr/dmr/www/kbman.html" title="B Language">B programming language</a>, the predecessor to C. Thompson missed the
convinience of writing code in a high-level language &ndash; Multics was written
a version of PL/1 &ndash; and wanted the same convinience on UNIX. He preferred
BCPL (a typeless language) to PL/1. As Dennis Ritchie <a href="https://www.bell-labs.com/usr/dmr/www/chist.html" title="C History">wrote</a>:</p>
<blockquote><p>B can be thought of as C without types; more accurately,
it is BCPL squeezed into 8K bytes of memory and filtered
through Thompson&rsquo;s brain.</p></blockquote>
<p>A look at the B reference manual will show the strong correlation with C, and
shows the source of a lot of C&rsquo;s mysteriousness &ndash; some of which is preserved
simply so that C could compile the <em>dozens</em> of lines of existing B code&hellip;</p>
<p>Thompson&rsquo;s assembler was also extremely simple. It didn&rsquo;t even know about
opcodes &ndash; these need to be defined in the first assembly file, with the
assembler OR-ing the opcode fields together (space was the &ldquo;operator&rdquo; for
logical OR). There is no link step &ndash; all files are provided to the assembler
on the command line, concatenated together and assembled, producing a single
<code>a.out</code> (assembler output) file. Even after UNIX got a linker, <code>a.out</code>
remained the default name of the binary generated by the linker (and hence
also by <code>cc</code>).</p>
<p>This system is still has the familiarity of UNIX, with all the two- and
three-letter commands, device files, shell redirection, the same core system
calls (<code>read</code>, <code>write</code>, <code>open</code>, <code>close</code>, <code>creat</code>, <code>fork</code>, etc.). There are a
number of differences still:</p>
<ul>
<li>As noted, there are no file paths</li>
<li><code>read</code> and <code>write</code> do I/O on (18-bit) words. Character I/O to files needs
to unpack those to bytes, and of course deal with <code>NUL</code> characters.</li>
<li><code>exec</code> was performed by the shell directly. Arguments are passed as
four words (eight bytes), and space padded. This matches the format for
file names for <code>open</code> and <code>creat</code>.</li>
<li><code>wait</code> does not yet exist. A more complicated mechanism for sending and
recieving messages (<code>smes</code> and <code>rmes</code>) are used instead.</li>
<li>File permission bits are all different, since groups don&rsquo;t exist yet.</li>
<li>User programs are not allowed to run during disk I/O. This is because the
disk controller&rsquo;s &ldquo;data break&rdquo; (DMA) accesses were so fast relative to the
CPU that transfers would be dropped if an instruction that used
&ldquo;deferred&rdquo; mode (indirection) was executed. This also meant that the
&ldquo;program break&rdquo; (interrupt) routine in the kernel had to specifically
avoid deferred accesses by using self-modifying code to do indirection
through pointers.</li>
<li>Although the PDP-7 suppoted a &ldquo;trap mode&rdquo; (a primitive supervisor mode),
the UNIX kernel doesn&rsquo;t use it. This means that user programs could alter
or crash the kernel at will (in fact, there is a system call that returns
addresses of useful kernel routines so that user code can call them
directly).</li>
</ul>
<p>As usual, when you are done exploring UNIX v0, type Control-E to exit the
simulator.</p>
<h1>About the Program</h1>
<p>The program came about when I was looking for something to honor the pending
50th anniversary of the C language (because of the mercurial nature of IOCCC
contest scheduling, I chose not to wait for the actual 50th anniversary).
I had though of writing self-hosting compilers for a stripped-down version of
C, or maybe even a version of the B language&hellip; At the same time, I was
obsessed with the idea of allowing <code>mullender.c</code> from 1984 to run. Although
that was still a possibility on an interpreted version of B or a stripped-down
version of C, it felt cheap, as it would be <code>mullender.c</code> only in spirit.</p>
<p>It was during this time that I discovered that in 2016, members of the Unix
Heritage Society got access to <a href="http://www.tuhs.org/Archive/Distributions/Research/McIlroy_v0/" title="V0 Scans">printouts of assembly-language source for the
original version of UNIX</a>. With what was a <a href="http://minnie.tuhs.org/Y5/wkt_hapop_paper.pdf" title="UNIX v0">huge amount of work</a>,
they scanned in the printouts, fixed up the OCR translations, built assembler
and file system tools from scratch and made an accurate simulation of
Thompson&rsquo;s PDP-7 that allowed them to get the system up and running. Although
source for the entire kernel and about half of the user-space commands were
present (including the runtime and libraries for the B compiler), the
remainder needed to be written from scratch, including the shell. The final
results of the project are <a href="https://github.com/DoctorWkt/pdp7-unix" title="PDP-7 UNIX">available on github</a>.</p>
<p>None of this was remotely easy (as I was to discover myself). The PDP-7 is
long gone, and the documentation for it is less complete than one would like.
In addition, the devices attached for it were a bit of a mystery. The disk
system is referenced only in an old price list. It was a RB09 fixed disk,
probably made by Burroughs. It is close to what was called the RC10 for the
PDP-10, but with a different interface. And the system also included a custom
display device called Graphics-2, which had been built in-house by AT&amp;T.
It can&rsquo;t be completely ignored, because the kernel itself pokes at it (the
UNIX crew used it as a second terminal &ndash; a &ldquo;glass TTY&rdquo;).</p>
<p>I decided that implementing this PDP-7 would be possible as an IOCCC entry.</p>
<p>The emulator emulates the full machine:</p>
<ul>
<li>PDP-7 Central Processor</li>
<li>Core Memeory Module Type 147 &ndash; extends the core to 8,192 18-bit words</li>
<li>Extended Arithmetic Element Type 177 &ndash; adds one&rsquo;s-complement
multiplication, division and shifting</li>
<li>Real Time Clock</li>
<li>Teletype Model 33 KSR</li>
<li>Perforated Tape Reader Type 444</li>
<li>RB09 Fixed Disk Controller</li>
</ul>
<p>The <a href="http://bitsavers.trailing-edge.com/pdf/dec/pdp7/F-75P_PDP7prelimUM_Dec64.pdf" title="PDP-7 Manual">PDP-7</a> is an odd duck by modern computer standards:</p>
<ul>
<li>18 bit words, with no byte addressing.</li>
<li>Both one&rsquo;s and two&rsquo;s complement math (there is <code>ADD</code> for one&rsquo;s complement
and <code>TAD</code> for two&rsquo;s complement). The EAE is entirely one&rsquo;s-complement.</li>
<li>&ldquo;Microcoded&rdquo; instructions.</li>
<li>Auto-increment memory locations.</li>
<li>Non-reentrant function calls (the return address is stored at the indicated
address and the PC jumps to the location after it).</li>
<li>The <code>XCT</code> instruction, that executes the word loaded from memory as an
instruction.</li>
<li>An instruction <code>LAW</code> that loads the instruction opcode into the
accumulator.</li>
<li>Heavy use of &ldquo;inline&rdquo; operands. For instance the <code>MUL</code> instruction expects
the second operand to be stored in memory after the instruction. This
pretty much requires the use of self-modifying code.</li>
<li>No immediates. Almost all constants have to live in memory locations and
be referenced by address.</li>
<li>Common operations, like &ldquo;subtract&rdquo; and &ldquo;inclusive OR&rdquo; are not directly
supported on the machine and require multiple instructions and some spare
memory locations to support. Being clever also helps.</li>
<li>Single accumulator architecture. No direct support for things like stacks.</li>
<li>I/O is done with dedicated I/O instructions (which are also microcoded).</li>
<li>The RB09 disk controller gets a special mention here because of its
particularly annoying encoding of track and sector offsets in
<a href="https://en.wikipedia.org/wiki/Binary-coded_decimal" title="BCD">packed BCD</a>. A non-trivial amount of code space in the simulator
is needed to convert into and out of BCD, along with an equivalent amount
of code in the UNIX kernel itself.</li>
</ul>
<p>The simulation handles everything I was able to discover about the PDP-7, even
things that the UNIX code itself doesn&rsquo;t use. For instance, it correctly
implements the &ldquo;trap mode&rdquo; feature (a primitive form of supervisor mode) even
though the kernel does not enable it. It also implements the microcoding of
the EAE instructions even though the UNIX environment uses only the standard
encodings. If you wanted to do a 11-bit multiply instead of an 18-bit one,
it will probably work.</p>
<p>The simulation starts by loading a boot program off of the virtualized paper
tape, which is in a modified version of the RIM boot loader format. The
RIM format encodes each 18-bit word as three six-bit characters, using one bit
to denote the final word (which is executed directly and is usually a <code>JMP</code> or
<code>HLT</code> instruction). The load address comes from the console address switches.
Both of these are controlled by compile-time flags.</p>
<p>The emulator continues emulating instructions until it sees a <code>HLT</code> instruction
which will cause it to exit. Console I/O is emulated by setting the terminal
into raw mode and polling via <code>read</code>. Line-clock ticks (at 60 Hz) are done
by polling <code>gettimeofday</code>. Dynamic frequency code arranges to reduce the
polling interval to a few polls per tick, so that simulation remains
responsive. Since we use the real wall-clock time, this means that the
emulated system will see time advance at the correct rate.</p>
<h2>Licencing Fun</h2>
<p>So now I have a system that can run UNIX v0. One problem remains&hellip; I don&rsquo;t
have permission to submit UNIX v0 to the IOCCC. It is not my code and the
copyright for it remains the property of whoever owns that part of what was
once Bell Labs &ndash; I believe it is Nokia at this point. I have worked around
this problem in two ways:</p>
<p>First, I didn&rsquo;t submit the source code or binary image for v0 UNIX as part of
my IOCCC entry. I merely submitted a <code>Makefile</code> that can issue a <code>curl</code>
command to fetch a prebuilt v0 disk image from the github repository. I am
hoping this is considered part of &ldquo;Legal abose of the rules&rdquo; which is supposed
to be &ldquo;somewhat encouraged&rdquo;. As per RULE 12, I am justifying said abuse here,
in the remarks file.</p>
<p>Secondly, the choice to run the UNIX v0 code is optional. If you are worried
about Nokia&rsquo;s lawyers running you to ground for running a 50-year old copy
of a binary image for a machine that is almost completely nonexistant, you
can just not do so. Delete the lines from the <code>Makefile</code> and sleep well.
You still have two other UNIXes to play with.</p>
<p>What about the other two UNIX variants? These are both covered by licences
that allow me to use them. Back in 2002, Caldera International released
Research Unix versions 1-7 and 32V under a <a href="http://www.tuhs.org/Archive/Caldera-license.pdf" title="Caldera Licence">permissive BSD-like license</a>.
BSD UNIX is based off of v7 UNIX, and of course has its own permissive
BSD licence. And in 2017, Nokia also released versions 8-10 under the
condition that it will not assert copyright rights for non-commercial use.</p>
<p>So the newer UNIXes are in the clear. I doubt anyone actually cares about
version 0 either, but technically it&rsquo;s still under copyright.</p>
<h2>PDP-11/40</h2>
<p>So if I have a PDP-7 emulator, how do I run operating systems that expect a
PDP-11? Simple&hellip; <em>I emulate a PDP-11/40 on the PDP-7</em>. I have written
PDP-7 assembler code to emulate a PDP-11/40 with the following equipment:</p>
<ul>
<li>PDP-11/40 (KD11-A)</li>
<li>EIS instruction set (KE11-E)</li>
<li>Memory management unit (KJ11-A)</li>
<li>Line time clock (KT11-D)</li>
<li>124 Kwords of memory (244 Kbytes)</li>
<li>RK05 fixed disk drive (RK11)</li>
<li>Console TTY (DL11)</li>
</ul>
<p>This required a few tweaks to the emulator. The first problem is that the
RK05 disk is about 2.5 MB, but the RB09 is only about 2 MB. That&rsquo;s easily
solveable &ndash; just add more tracks to the RB09. UNIX v0 is unlikely to notice
(although the number of tracks is a compile time parameter, and the <code>v0</code>
build commands set it to the correct value).</p>
<p>The second problem is that we are simulating a system that can have up to
124 Kwords of memory on a system with only 8 Kwords total. That meant I needed
to virtualize the PDP-11/40&rsquo;s physical memory (and add a few more tracks to
the disk to hold the virtualization).</p>
<p>A large amount of time was spent tuning this code to be efficient. The
memory virtualization uses part of the 8 Kword memory as an LRU cache, and
uses a number of first-level microcaches to avoid having to do the LRU updates.
This also serves to offload the complexity of the PDP-11&rsquo;s segmentation logic
from a large number of memory accesses (the PDP-11 does as many as eight
accesses per instruction). Despite the super fast emulated disk, the PDP-7
code in the emulator is slow, mostly because it has to do a bunch of divides
to convert the linear disk offset into a BCD-coded track and sector for the
emulated RB09. I/O polling is again used, except this time it uses the
PDP-7&rsquo;s &ldquo;skip on flag set&rdquo; I/O instructions. As with the PDP-7 emulator
itself, the PDP-11 emulator dynamically measures the instruction throughput
relative to the line-clock tick, so that it only polls for I/O a few times
per tick.</p>
<p>The one remaining problem is building the disk images themselves. Since the
PDP-11&rsquo;s disk is 16-bit, but the PDP-7&rsquo;s is 18-bit (which the emulator stores
in 32-bit <code>int</code>s), a conversion program is needed to unpack the binary disk
images from 16 bits per word to 32. This in turn needs to be done in the
<code>Makefile</code> using standard POSIX tools, which aren&rsquo;t exactly good with binary.
I had a wierdly clever way to do this with <code>od</code>, <code>awk</code> and <code>uudecode</code> that
I will leave as an exercise for the curious, but I decided it would be easier
to do it with the PDP-7 emulator itself, feeding a simple program in on its
boot tape. This required an additional tweak to the emulator, since by default
its console TTY is not eight-bit clean (in fact, UNIX v0 expects to see the
MSB set on the terminal reads, and sets it on writes, what is called &ldquo;mark&rdquo;
parity). This is also enabled by a compile-time setting (used only for the
<code>builddisk</code> program).</p>
<p>Despite the complexity of the PDP-11 instruction set and its emulated I/O
devices and the corresponding primitiveness of the PDP-7&rsquo;s instruction set,
the emulation itself is a suprisingly small amount of code, not really taxing
the 8 Kword memory, with about 2.25 Kwords of actual code and a similar
amount of space for the memory virtualization cache and disk block buffer,
leaving nearly half (3.5 Kwords) of the memory unused. The simulator executes
somewhere around 250 PDP-7 instructions per PDP-11 instruction. On my laptop,
the PDP-7 is running somewhere in the neighborhood of 70 MIPS, which means the
PDP-11 is running at about 0.3 MIPS, which is probably not too far off of its
actual speed (the cycle time of an 11/40 was around a microsecond for simple
instructions, but could be proportionally larger for instructions that did
multiple memory accesses, which many did).</p>
<p>As an aside, although the idea of emulating the PDP-11 on an emulated PDP-7
came about from the realization that I needed a response to the late-discovered
licence issue, I&rsquo;m quite pleased with the result &ndash; it enables an interesting
window on the dawn of the UNIX era. I feel that someone should complete the
circle here by emulating a VAX 780 on the PDP-11 and run 4.2BSD on it, so that
we can get the <a href="https://groups.google.com/forum/?hl=en#!msg/net.lang.c/lx-TAuEyeRI/HdOOnNx6LC0J" title="First annual IOCCC announcement">original runtime environment used for the first IOCCC</a>.</p>
<h2>Compile-time Options</h2>
<p>The following command flags control the compilation:</p>
<ul>
<li><code>-DI="image.fs"</code>: Name of the disk image file. This must be created
offline, and be of the correct size to avoid segmentation violations.</li>
<li><code>-DA=4096</code>: Setting of the console address switches. This tells the RIM
bootloader where to load the boot image.</li>
<li><code>-DS=0</code>: Setting of the console data switches. The PDP-7 emulation can
read these with the microcoded <code>OAS</code> (OR switches into AC) instruction.
By proxy, the PDP-11 emulation can read them via the <code>CSW</code> device.</li>
<li><code>-DW=MAP_PRIVATE</code>: This sets the memory mapping for <code>mmap</code>. Setting to
<code>MAP_PRIVATE</code> makes the disk image be copy-on-write. Setting it to
<code>MAP_SHARED</code> makes the disk image be sharable. Do the latter if you want
to preserve the disk contents between sessions.</li>
<li><code>-DT=</code>: List of initializers for the <code>termios</code> structure. The v0 UNIX
expects the terminal to be in half-duplex mode, echoing its input, with
swapped CR and NL. The PDP-11 UNIXes don&rsquo;t.</li>
<li><code>-DX=5</code>: The ASCII code of the control character that causes the simulation
to abort. If set to 0, there is no abort code.</li>
<li><code>-DY=128</code>: Controls console I/O parity. If set to zero, the console is
eight-bit clean. If set to 128, the high bit is set on keyboard reads and
masked off on printer output (&ldquo;mark&rdquo; parity). UNIX v0 expects the latter.</li>
<li><code>-DV=270</code>: The size of the disk, in tracks. The UNIX v0 disk has 200
tracks (each has 80 sectors of 64 18-bit words). The PDP-11 UNIXes
increase this to 270, to allow for the larger RK05 disk emulation
(406 tracks of twelve 256-word sectors), plus the space for the 124 Kwords
of virtualized memory and the 8 Kwords of emulator code.</li>
<li><code>-DP="xxx"</code>: RIM bootstrap program paper tape image. Be careful with the
quoting here &ndash; there is at least three levels going on. In particular,
you will need to escape <code>$</code> as <code>$$</code> to protect it from <code>make</code>.</li>
</ul>
<h2>What is the ASCII art supposed to be?</h2>
<p>The ASCII art represents a torn piece of <a href="https://en.wikipedia.org/wiki/Punched_tape" title="Paper Tape">paper tape</a>.</p>
<h2>Acknowledgements</h2>
<p>None of this could have been possible without the hard work of</p>
<ul>
<li>Warren Toomey and the other members of the
<a href="http://www.tuhs.org" title="The Unix Heritage Society">The Unix Heratage Society</a></li>
<li>Robert M. Supnik and the other contributors to <a href="http://simh.trailing-edge.com" title="SimH">SimH</a>, the simulator
for historic computer architectures. The number of times I needed to
&ldquo;Use the Source, Luke&rdquo; on SimH to unravel some dark corner of these
machines was uncountable.</li>
<li><a href="http://bitsavers.trailing-edge.com" title="Bitsavers.org">Bitsavers</a>, which acquired, scanned and preserved all the manuals
I spent many hours squinting at.</li>
<li>Ken Thompson, Dennis Ritchie, Brian Kernigan, M. D. McIlroy, J. F.
Osssanna, Rudd Canaday and the other members of the Bell Labs
Computing Science Research Center who were responsible for the invention
of UNIX, the C programming language, and the innumerable other innovations
that we now take for granted as part of the modern software landscape.
In particular, the <a href="https://www.bell-labs.com/usr/dmr/www/" title="DMR Homepage">home page of the late Dennis Ritchie</a> contained
a trove of useful information on the evolution of UNIX and C and is
recommended for perusal by others who share my peculiar retrocomputing
affectations.</li>
</ul>
<p>Finally, thanks to my spouse for putting up with the many hours I spent on this
nonsense, and treating &ldquo;I&rsquo;m working on my IOCCC entry&rdquo; as an acceptable answer
to queries about how I was spending my free time. Similarly, I apologise to
those friends and coworkers who had to listen to me complain about obscure
corner-case bugs in my code. The obsession is over, at least until next
time&hellip;</p>
<hr />
<hr />
<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-2018,
<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>
-157
View File
@@ -1,157 +0,0 @@
<!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 stellar</title>
</head>
<body>
<h1>Most stellar</h1>
<p>Timo Poikola <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#111;&#58;&#x69;&#x6f;&#99;&#x63;&#99;&#50;&#48;&#49;&#56;&#64;&#105;&#x67;&#x2e;&#x66;&#x69;">&#105;&#x6f;&#99;&#x63;&#99;&#x32;&#48;&#49;&#56;&#x40;&#105;&#x67;&#x2e;&#102;&#x69;</a><br>
<a href="https://ig.fi/">https://ig.fi/</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog
</code></pre>
<h3>Try:</h3>
<p>On terminal supports 24 bit color, has black background, and size at least 125x38, try:</p>
<pre><code>./prog
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>It is said by some students of Astronomy:</p>
<pre><code>Oh, Be A Fine Gal, Kiss Me!
Oh, Be A Fine Gentleman, Kiss Me!
</code></pre>
<p>Many <a href="http://www.star.ucl.ac.uk/%7Epac/obafgkmrns.html">Mnemonic variations</a> exist.
You might wish, on a star, to better understand the colors being displayed.
And those in the deep south might wish to go north for a better view.</p>
<h2>Author&rsquo;s comments:</h2>
<h3>How to build</h3>
<pre><code>gcc -o prog -std=gnu11 -O3 prog.c
</code></pre>
<p>or</p>
<pre><code>make
</code></pre>
<h3>Poster</h3>
<p>You can generate an A3 sized poster by <em>make docs</em>. This command creates a pdf file <em>poikola.pdf</em>.</p>
<h3>What this entry does</h3>
<h4>Introduction</h4>
<p>It was a starry night when my wife pointed her finger up and asked: &ldquo;What is this star and may I have some Easter eggs?&rdquo;</p>
<p>So I had to sit down and solve those tricky questions with Nano and a C compiler.</p>
<h4>Little spoilers</h4>
<p>Basically, the program draws animated ASCII art of the Big Dipper using Annie Jump Cannon&rsquo;s spectral classification system of stars and I think the
colors of the output are as accurate as possible.</p>
<p>This program also tells once in a year if it is correct time to find and eat some Easter eggs.</p>
<p>The program has also at least three other functions, obvious and not so obvious.</p>
<h4>Technical jargon</h4>
<p>This program has been tested on xterm and Konsole and also Linux virtual terminal. Color support in the terminal is not necessary, but the effect is better with it.
This entry has partial support for terminals with a white background but the best viewing experience is achieved when the terminal in use supports 24-bit colors,
has a black background and the size is at least 125x38.</p>
<p>Special note for Mac users: <strong>Terminal</strong> does not work as expected you might need xterm from XQuartz or some other
working terminal. Thanks to Dave Burton for spotting this problem.</p>
<p>The main reason for the header <code>unistd.h</code> is <code>getdelim()</code> but once I included it I also abused other functions and defines. This header is mutually exclusive with <em>-std=c11</em>.</p>
<p>The program was developed with little-endian machines; I tried to support big-endian too, but this support is somewhat limited.</p>
<p>This program has been compiled in</p>
<ol>
<li>i386 (Debian Stretch) with gcc and clang</li>
<li>amd64 (Debian Buster) with gcc and clang</li>
<li>Raspberry Pi 3 (Debian stretch) with gcc and clang</li>
<li>Lego Mindstorms EV3 Intelligent Brick (Debian Jessie) with gcc and clang (in this case, compiling time with clang-3.5 12 seconds and with gcc 27 seconds)</li>
</ol>
<h3>Warnings and restrictions required by law</h3>
<p>Please do not feed little babies chocolate.</p>
<h3>Major spoilers</h3>
<div style="margin-bottom:61em;">&nbsp;</div>
<p>I incorporated the Fletcher 16 checksum algorithm into the source for security reasons; it might be challenging to make changes without breaking the main functionality of the code.
The space after <code>#define p return</code> is necessary.</p>
<p>The computus uses an algorithm described in the journal Nature in 1876. It should be valid for Gregorian calendars.</p>
<h4>Some obfuscation techniques used</h4>
<ol>
<li>I tried to use meaningless or misleading variable names. For example, this program draws the Big Dipper with the correct colors, but variables
like <code>o</code>, <code>b</code>, and <code>a</code> are used in totally unrelated tasks.</li>
<li>I reused and recycled variables almost every time when possible.</li>
<li>Unnecessary use of predefined stuff like <code>__ATOMIC_SEQ_CST</code>.</li>
<li>When I was a kid, my favorite programming language was Pascal. In Pascal, there are things like <code>begin;</code> and <code>end;</code> instead of curly brackets.
They are used also in my code, but I had to shorten them to meet size requirements.</li>
<li>I also have strong Perl background,
and therefore I added some dollar signs to the code. One of the first ideas was to
write all variables with prefixed <code>$</code>, but then I rejected it.</li>
</ol>
<p>If you think you understand how this program works, can you answer these questions:</p>
<ol>
<li>What is the value of <code>aI_</code> after line 21?</li>
<li>Why are there some big numbers on line 47?</li>
<li>How is the scaling effect created?</li>
<li>How do you change a single bit, without changing the functionality?</li>
</ol>
<h3>Rot18ed part</h3>
<p>Because the rot13 is too easy to decode with the plain eyes, I decided to use the Caesar cipher with the key 18.</p>
<p>Lzw xajkl tsffwj ak wfugvwv mkafy AWWW 754 xdgslk gf dafw 47. Al ak hjaflwv gfdq gf dalldw-wfvasf esuzafwk.</p>
<hr />
<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-2018,
<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>
-227
View File
@@ -1,227 +0,0 @@
<!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 connected</title>
</head>
<body>
<h1>Most connected</h1>
<p>Scott Vokes<br>
Twitter: @silentbicycle</p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
./prog &lt; example-1.txt
</code></pre>
<h3>Try:</h3>
<pre><code>./prog &lt; example-2.txt
./prog &lt; example-tab.txt
./prog &lt; ioccc.txt
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>What this program does is not witchcraft and there are no spectres, but you
might have a meltdown trying to work it all out.</p>
<p>This entry is designed to mislead in many ways. However, if you find yourself
wanting to know the possibilities for navigating a graph, you will get the
answer you seek with no hocus pocus.</p>
<h2>Author&rsquo;s comments:</h2>
<h2>Introduction</h2>
<p>This program reads a directed graph (as lines with integer node IDs),
and prints the graph&rsquo;s nodes in reverse-topologically sorted order,
grouped into strongly connected components. Given a set of nodes
representing targets and edges representing dependencies between them,
it produces a build order with any dependency cycles gathered.</p>
<p>For example, the following input (provided as <code>example-1.txt</code>):</p>
<pre><code>0 4 8
1 0
2 1 3
3 2
4 1
5 4 6
6 5 2
7 3 6 7
</code></pre>
<p>would be interpreted as:</p>
<pre><code>0 -&gt; 4, 8
1 -&gt; 0
2 -&gt; 1, 3
3 -&gt; 2
4 -&gt; 1
5 -&gt; 4, 6
6 -&gt; 5, 2
7 -&gt; 3, 6, 7
</code></pre>
<p>So, node 0 has edges to / depends on nodes 4 and 8, node 1 depends on
node 0, and so on. Then, it groups the graph&rsquo;s nodes into
strongly connected components and prints them in reverse-topologically
sorted order:</p>
<pre><code>0: 8
1: 0 1 4
2: 2 3
3: 5 6
4: 7
</code></pre>
<p>It uses Tarjan&rsquo;s strongly connected components algorithm for the
grouping and reverse-topological sorting, along with a bonus hidden
implementation of counting sort, which sorts each group.</p>
<p>For other details about the input format, see &ldquo;Issues and
Limitations&rdquo;.</p>
<h2>Building</h2>
<p>To build:</p>
<pre><code>${CC} -o prog prog.c -std=c11 -O3 \
-Wall -Wextra -pedantic -Wno-missing-prototypes
</code></pre>
<p><code>-Wno-missing-prototypes</code> is necessary because there aren&rsquo;t any
prototypes. (They would put the program well over the size limit.)</p>
<p>Note: The program can also be built with <code>-std=c99</code> or <code>-std=c89</code>.</p>
<p>If building with <code>-Weverything</code>, then <code>-Wno-strict-prototypes</code>
may also be necessary &ndash; the function pointer declarations for
<code>_</code> and <code>B</code> may get warnings otherwise, for reasons described
under &ldquo;Obfuscations&rdquo;.</p>
<h2>Obfuscations</h2>
<ul>
<li><p>This entry uses functions that have a variable number of arguments,
but despite what the rules say, there is no need to be careful about
<code>va_list</code> implementation differences. :) . There are several
references to a function pointer, <code>_</code>, but it&rsquo;s called with different
numbers of arguments in different places. (In particular, look at
<code>spell</code>.) Because the function pointer declaration has an empty list
of parameters, the argument count and types are unconstrained. <code>_</code> is
set to different functions in several places, but it is always called
with appropriate argument(s) for its possible current functions. This
is allowed by the standard &ndash; The section on F,I,N,D,M,Y,C,L,U,E has
further details.</p></li>
<li><p>It uses <code>_</code> in three different scopes: as a goto label (function
scope), as an enum name, and a <code>_</code> function pointer (which is required
to have file scope, since it starts with &lsquo;_&rsquo;). There are also other
<code>_</code>s: it appears in a string, obscured by a headecimal escape sequence
(<code>\x5f</code>), and the cauldron is supported by a giant underscore.
(Does this program qualify for Best One Liner?)</p></li>
<li><p>Most of the variables are not only global, but used for unrelated
purposes at different times, so just renaming them while studying the
program should make it even more confusing. The few variables local to
functions have their names reused for different things in other
functions.</p></li>
<li><p>There is an enum early on that defines several single-letter
identifiers: F,I,N,D,M,Y,C,L,U,E. These are used for array offsets,
both individually and in combination. The first several values are
also a clue: ISO/IEC 9899:1999 chapter 6.7.5.3 verse 14 describes how
function declarators with an empty parameter list behave. (As does
3.5.4.3 for ANSI C, which explains the 0x3543 that appears soon
after.)</p></li>
<li><p>Several parts of the program&rsquo;s state are stashed in otherwise unused
offsets of the node arrays. These locations are accessed in multiple
ways, such as using <code>I[p]</code> (where I == 7) as well as <code>p[F+L]</code> (6+1),
or <code>b[M-N]</code> (14-5) and <code>U[b]</code> (where U == 9).</p></li>
<li><p>The other identifiers are misleading, punny, or both. <code>spectre</code> does
not exploit CVE-2017-5753 or CVE-2017-5715, for example &ndash; it just fits
the witch theme. <code>cast</code> doesn&rsquo;t cast, <code>hex</code> has nothing to do with
hexadecimal, <code>bubble</code> is not bubble sort, there is no undefined
behavior in <code>nasal_demons</code>, and <code>main</code> has absolutely nothing to do
with a hand.</p></li>
<li><p>For well-formed input, how the program determines when to exit is a
bit obscure. <code>main</code> ends with a <code>goto</code> leading back to an earlier <code>_</code>
label, so it just loops forever, and <code>exit</code> only appears in code paths
related to error-handling. It looks like <code>cast</code> calls <code>meltdown</code> with
its second argument set to 0, which would call <code>exit</code>, but running in
gdb with a breakpoint on <code>cast</code> reveals that it isn&rsquo;t being called&hellip;</p></li>
<li><p>Instead of using <code>isdigit()</code>, the program checks the numeric value of
each <code>char</code>, and literals that would suggest comparing against e.g. &lsquo;0&rsquo;
are specified in octal in one place, and produced by arithmetic using
the enum elsewhere.</p></li>
<li><p>Common conventions are subverted: <code>i</code> is not a loop index, <code>argv</code> and
<code>argc</code>&rsquo;s names are swapped.</p></li>
<li><p><code>NULL</code> does not appear in the program. Instead, <code>argc[argv]</code> (which is
required to be a null pointer) is saved and passed to where its value
is needed.</p></li>
<li><p>Oh, and the program is squashed into the shape of a bubbling cauldron,
on top of a giant underscore, so there&rsquo;s that.</p></li>
</ul>
<h2>Issues and Limitations</h2>
<ul>
<li><p>Despite appearances, it does not handle numbers in hex, or provide
a <code>curses(3)</code>-based interface.</p></li>
<li><p>The expected input format is zero or more lines of space-separated
integers. If other characters appear in the input, it will either
reject the input entirely and exit with a non-zero status, or skip
number(s) adjacent to the non-digit characters, depending on where the
characters appear. Tabs and multiple consecutive spaces are handled
correctly, however.</p></li>
<li><p>Individual lines of input longer than <code>0x3543 - 1</code> bytes will be
split and processed as if they were multiple lines of input, which can
produce incorrect results. This magic number&rsquo;s significance is
described earlier.</p></li>
<li><p>The algorithm expects its input to represent a fully connected graph.
While the output is otherwise topologically sorted, if there are nodes
completely unconnected to the rest of the graph (with or without
self-cycles), they will be output as soon as they are processed &ndash;
this means that, when there are disconnected nodes, reordering the
input lines can produce different output. Addressing this by adding
another pass is would put the program over the size limit.</p></li>
<li><p>While the node IDs don&rsquo;t need to be consecutive or start at 0, the
implementation doesn&rsquo;t have special handling for sparse graphs. If you
give it a graph with nodes numbered 0 and 2147483647, it will attempt
to allocate sufficient memory (potentially around 32 GB) for the
entire range of graph nodes, even if those are the only ones. If
memory allocation returns NULL, it will gracefully exit, otherwise it
will succeed, eventually, perhaps after a great deal of swapping.</p></li>
<li><p>Node IDs >= 2147483648 will cause the program to print an error
message and exit with a non-zero status. This shrinks the code that
detects overflowing the array size by a bit.</p></li>
<li><p>A very large group of nodes in a cycle can cause a stack overflow.
This typically takes over 100,000 nodes, and depends on the order the
nodes are visited. Addressing this would put the program over the size
limit.</p></li>
<li><p>The implementation depends on the characters &lsquo;0&rsquo;, &lsquo;1&rsquo;, &hellip; &lsquo;9&rsquo; having
the values 48 through 57, rather than using <code>isdigit()</code>. As noted
above, this program has nothing to do with a hand.</p></li>
</ul>
<hr />
<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-2018,
<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>
-189
View File
@@ -1,189 +0,0 @@
<!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 shifty</title>
</head>
<body>
<h1>Most shifty</h1>
<p>Don Yang<br>
<a href="http://uguu.org/">http://uguu.org/</a></p>
<h2>Judges' comments:</h2>
<h3>To use:</h3>
<pre><code>make
more generated1.c
more generated2.c
more generated3.c
</code></pre>
<h3>Try:</h3>
<pre><code>make
./left &lt; prog.c
./right &lt; prog.c
./left &lt; prog.c | ./left
./shift &lt; prog.c
./msg0
./msg1
./msg2
</code></pre>
<h3>Selected Judges Remarks:</h3>
<p>Code should be readable in any direction! This tool will help you rotate your
code so you don&rsquo;t have to stare at it sideways or even upside down. Rotating
this program left and recompiling will reveal other tools including a right rotate
and a shift program.</p>
<p>Strange things happen when the world is upside down! It is entirely possible
that this is remark is completely misleading.</p>
<p>What exactly does the shift program do?</p>
<p>Like a great sliding puzzle (hint) this entry has 6 more programs that will
reveal messages and one more tool that can be used to reveal the final
message hidden in the original source. All of these can be created using
combinations of ./left, ./right and ./shift and the additionally generated
programs.</p>
<p>The final message can be revealed using</p>
<pre><code>./msg9 &lt; prog.c
</code></pre>
<p>But what combinations will generate ./msg3, ./msg4, ./msg5, ./msg6, ./msg7,
./msg8 and finally ./msg9?</p>
<h2>Author&rsquo;s comments:</h2>
<h1>Tools usage</h1>
<p>Nuko is a text rotator: given some text in stdin, Nuko will write the
same text to stdout, but rotated 90 degrees counterclockwise.</p>
<pre><code>gcc prog.c -o left
./left &lt; input.txt &gt; rotated_counterclockwise.txt
</code></pre>
<p>Due to static memory allocation, only the first 1K columns by 1K rows
are rotated, the rest are silently ignored. But fear not, a separate
tool with dynamic memory allocation is included:</p>
<pre><code>./left &lt; prog.c &gt; r1.c
gcc r1.c -o right
./right &lt; input.txt &gt; rotated_clockwise.txt
</code></pre>
<p>For variety, this second tool rotates clockwise instead of
counterclockwise. Also, it can handle files larger than 1024x1024,
depending on how much memory you got.</p>
<p>Of course we wouldn&rsquo;t stop with just two rotations, if we continue to
rotate counterclockwise once more, we get another program. This
program outputs a single message to stdout, which is the name of the
series that Nuko came from.</p>
<pre><code>./left &lt; prog.c | ./left &gt; r2.c
gcc r2.c -o msg0
./msg0
</code></pre>
<p>There is one final rotation, which produces a tool that removes
leading whitespaces:</p>
<pre><code>./left &lt; prog.c | ./left | ./left &gt; r3.c
gcc r3.c -o shift
./shift &lt; input.txt &gt; no_leading_space.txt
</code></pre>
<p>Where this might be useful, besides ruining the formatting of certain
files, is that it completes the set of tools needed to solve the
puzzle that is embedded in prog.c</p>
<h1>Puzzle box</h1>
<p>Notice how the edges of prog.c contain two notches. By rotating
prog.c and removing leading space, the code would be shifted one space
toward one of those notches (and creating a new notch on the other
side). This shifted code behaves slightly different from the original
program. For example, here are two more messages that can be
produced:</p>
<pre><code>./shift &lt; prog.c | ./right &gt; msg1.c &amp;&amp; gcc msg1.c -o msg1 &amp;&amp; ./msg1
./shift &lt; prog.c | ./left &gt; msg2.c &amp;&amp; gcc msg2.c -o msg2 &amp;&amp; ./msg2
</code></pre>
<p>In total, there are 9 embedded strings that can be produced via a
sequence of rotates and shifts, one of which can be used to extract
the 10th final string from prog.c. The intent is to simulate those
wooden puzzle boxes that can be opened by pushing and shifting various
well-concealed seams. Thus, finding the correct sequence of rotates
and shifts is left as an exercise to the reader (but if you are really
lazy, just read the Makefile).</p>
<p>Source code for all the tools needed to solve this puzzle are embedded
in prog.c, all you need is a C compiler.</p>
<h1>Features</h1>
<ul>
<li><p> Code compiles when rotated 4 ways. This required a bit of
patience to achieve. Code still compiles even with one column of
text shifted. This required even more patience.</p></li>
<li><p> All rotated and shifted variants compiles without warnings. This
involves various tweaks to satisfy cases where compiler is overly
protective, including but not limited to the &ldquo;1125&rdquo; at line 4 as
opposed to &ldquo;1025&rdquo;, to satisfy -Waggresive-loop-optimizations.</p></li>
<li><p> CRC32 of the code is embedded in the code itself.</p></li>
<li><p> Process for writing prog.c is available in spoiler.html</p></li>
</ul>
<h1>Compatibility</h1>
<p>Nuko and the rotated tools accepts only ASCII files where each
character maps to exactly one byte. Also, end-of-line sequence is
assumed to be LF only, as opposed to CR-LF. All control characters
are treated like normal printable characters, so files containing tabs
will look weird after rotation, for example.</p>
<p>Nuko has been verified to work with these compiler / OS combinations:</p>
<ul>
<li> gcc 4.8.4 on Linux</li>
<li> gcc 4.9.2 on Linux</li>
<li> gcc 6.1.0 on JS/Linux</li>
<li> gcc 6.3.0 on Linux</li>
<li> gcc 6.4.0 on Cygwin</li>
<li> clang 3.5.0 on Linux</li>
<li> clang 3.8.1 on Linux</li>
<li> clang 5.0.1 on Cygwin</li>
<li> tcc 0.9.25 on JS/Linux</li>
</ul>
<p>Nuko compiles without warnings with all compilers above, even with
&ldquo;-Wall -Wextra -pedantic&rdquo; for gcc and clang.</p>
<hr />
<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-2018,
<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>