force use of pandoc version >= 3.1.12.2
The `bin/pandoc-wrapper.sh` tool will verify that the ssytem has a recent enough version of `pandoc(1)`. We explain why we insist on `pandoc(1)`. version >= 3.1.12.2 in comments where the $PANDOC_MIN_VERSION is set. Added `--wrap=preserve` as a default argument to `pandoc(1)`. While this change will impact every HTML file generated, we believe this will improve the ability of someone to look at the generated HTML and correlate with the original markdown. Changed `bin/pandoc-wrapper.sh` VERSION from "1.4.2 2024-03-17" to "1.4.3 2024-03-18". Performed `make www` to achieve all of the above and to generate HTML using the new `--wrap=preserve` `pandoc(1)` mode.
This commit is contained in:
1 parent
9eb7a54e9f
commit
b0b212acb1
402 files changed
+37061
-55132
No files matched your search
+165
-255
@@ -129,9 +129,9 @@
|
||||
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Ondrej_Adamovsky">Ondřej
|
||||
Adamovský</a><br> Location: <a href="../../location.html#CZ">CZ</a> -
|
||||
<em>Czech Republic</em> (<em>Czechia</em>) <br><br></li>
|
||||
<li>Name: <a href="../../authors.html#Ondrej_Adamovsky">Ondřej Adamovský</a><br>
|
||||
Location: <a href="../../location.html#CZ">CZ</a> - <em>Czech Republic</em> (<em>Czechia</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -144,8 +144,7 @@ Adamovský</a><br> Location: <a href="../../location.html#CZ">CZ</a> -
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_adamovsky">2019 adamovsky bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_adamovsky">2019 adamovsky bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> file.unl</span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
@@ -153,107 +152,71 @@ href="../../bugs.html#2019_adamovsky">2019 adamovsky bugs</a>.</p>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Even after pre-processing and indenting, the C code of this entry it
|
||||
is about as understandable as the Unlambda code.</p>
|
||||
<p>Pretending that we don’t know a bit of functional programming :) and
|
||||
lacking a better way to understand the entry but to fuzz it, we stumbled
|
||||
on a string of bytes which crashed it:</p>
|
||||
<p>Pretending that we don’t know a bit of functional programming :) and lacking a
|
||||
better way to understand the entry but to fuzz it, we stumbled on a string of
|
||||
bytes which crashed it:</p>
|
||||
<pre><code>````.0`.0`.0`c.0``sssss</code></pre>
|
||||
<p>Functional programming is not a panacea against core dumps, after
|
||||
all.</p>
|
||||
<p>Functional programming is not a panacea against core dumps, after all.</p>
|
||||
<p>This can be demonstrated by:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> crash.unl</span></code></pre></div>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="a-highly-structured-state-state-machine">A highly structured
|
||||
state state machine</h3>
|
||||
<h3 id="a-highly-structured-state-state-machine">A highly structured state state machine</h3>
|
||||
<h3 id="purpose">Purpose:</h3>
|
||||
<p>The purpose of this program is to allow you to play Colossal Cave
|
||||
Adventure as implemented by <a
|
||||
href="https://github.com/irori/advent-unlambda"
|
||||
title="Adventure">Kunihiko Sakamoto</a>. As that was written in <a
|
||||
href="http://www.madore.org/~david/programs/unlambda/"
|
||||
title="Unlambda programming language">Unlambda programming language</a>
|
||||
designed by David Alexander Madore it has to be an Unlambda
|
||||
interpreter.</p>
|
||||
<p>The purpose of this program is to allow you to play Colossal Cave Adventure as
|
||||
implemented by <a href="https://github.com/irori/advent-unlambda" title="Adventure">Kunihiko Sakamoto</a>. As that was written in <a href="http://www.madore.org/~david/programs/unlambda/" title="Unlambda programming language">Unlambda programming
|
||||
language</a> designed by David Alexander Madore it has to be an Unlambda interpreter.</p>
|
||||
<h3 id="aesthetics">Aesthetics:</h3>
|
||||
<p>The program grew a bit too long so I had to use several macros to
|
||||
downsize it. That unfortunately reduced my options for program layout. I
|
||||
decided to separate it into two portions: the initial macro section
|
||||
where I had limited resources which you should disregard its shape,
|
||||
unless you like it, and the rest, which is a separator in the form of a
|
||||
single line followed by a section signifying the function of the
|
||||
program, a block with removed shape of lambda character. Even the
|
||||
official IOCCC size tool acknowledges this: When you call
|
||||
<code>./iocccsize -i <prog.c</code>, using the <a
|
||||
href="../../2019/iocccsize.c">2019 version of iocccsize</a>, iocccsize
|
||||
returns <strong>955</strong>, which is the Unicode codepoint of the
|
||||
<strong>λ</strong> character.</p>
|
||||
<p>It might be a surprise for you that according to the IOCCC size tool
|
||||
the program is actually a <code>one-liner</code>. It certainly was for
|
||||
me. I like to think the tool is overwhelmed by the sheer length of the
|
||||
dividing line and totally overlooks the rest of the program.</p>
|
||||
<p>The program grew a bit too long so I had to use several macros to downsize it.
|
||||
That unfortunately reduced my options for program layout. I decided to separate
|
||||
it into two portions: the initial macro section where I had limited resources
|
||||
which you should disregard its shape, unless you like it, and the rest, which is a
|
||||
separator in the form of a single line followed by a section signifying the
|
||||
function of the program, a block with removed shape of lambda character. Even
|
||||
the official IOCCC size tool acknowledges this: When you call <code>./iocccsize -i <prog.c</code>, using the <a href="../../2019/iocccsize.c">2019 version of
|
||||
iocccsize</a>, iocccsize returns <strong>955</strong>,
|
||||
which is the Unicode codepoint of the <strong>λ</strong> character.</p>
|
||||
<p>It might be a surprise for you that according to the IOCCC size tool the program is
|
||||
actually a <code>one-liner</code>. It certainly was for me. I like to think the tool is overwhelmed
|
||||
by the sheer length of the dividing line and totally overlooks the rest of the program.</p>
|
||||
<h3 id="usage">Usage:</h3>
|
||||
<p>When built directly using</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>the program (<code>prog</code>) accepts a single parameter with the
|
||||
name of an Unlambda program. You can download the <a
|
||||
href="https://github.com/irori/advent-unlambda"
|
||||
title="Adventure">Colossal Cave Adventure</a> (the <a
|
||||
href="advent.unl">advent.unl</a> file) and run it like this:</p>
|
||||
<p>the program (<code>prog</code>) accepts a single parameter with the name of an Unlambda program. You can
|
||||
download the <a href="https://github.com/irori/advent-unlambda" title="Adventure">Colossal Cave Adventure</a> (the <a href="advent.unl">advent.unl</a> file)
|
||||
and run it like this:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> advent.unl</span></code></pre></div>
|
||||
<blockquote>
|
||||
<p>NOTE: the file was added to the entry so there is no need to download
|
||||
it.</p>
|
||||
<p>NOTE: the file was added to the entry so there is no need to download it.</p>
|
||||
</blockquote>
|
||||
<p>You can also try other programs from the Web. Many example programs
|
||||
are in the official <a
|
||||
href="http://www.madore.org/~david/programs/unlambda/#distrib"
|
||||
title="Reference Unlambda distribution">Unlambda distribution</a> on the
|
||||
Unlambda homepage. The most complex programs there are entries from <a
|
||||
href="http://www.madore.org/~david/programs/unlambda/#quine"
|
||||
title="Unlambda quine contest">quine contest</a>.</p>
|
||||
<p>There is an alternative build path that requires the 2018 IOCCC size
|
||||
tool to complete. Put the tool source <a
|
||||
href="iocccsize_2018.c">iocccsize_2018.c</a> in the project directory
|
||||
and call</p>
|
||||
<p>You can also try other programs from the Web. Many example programs are in the official
|
||||
<a href="http://www.madore.org/~david/programs/unlambda/#distrib" title="Reference Unlambda distribution">Unlambda distribution</a> on the Unlambda homepage. The most complex programs there are
|
||||
entries from <a href="http://www.madore.org/~david/programs/unlambda/#quine" title="Unlambda quine contest">quine contest</a>.</p>
|
||||
<p>There is an alternative build path that requires the 2018 IOCCC size tool to complete. Put the tool
|
||||
source <a href="iocccsize_2018.c">iocccsize_2018.c</a> in the project directory and call</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> identify</span></code></pre></div>
|
||||
<p>It will build the tool and use it to build an alternative program
|
||||
<code>prog2</code>, which in turn will produce an Unlambda program
|
||||
<code>identify.unl</code>. <code>make identify</code> runs this program
|
||||
to identify itself.</p>
|
||||
<p>The base program (<code>prog</code>) implements an interpreter of
|
||||
Unlambda 2.0. It recognises all its builtins (<code>k</code>,
|
||||
<code>s</code>, <code>i</code>, <code>v</code>, <code>c</code>,
|
||||
<code>d</code>, <code>.x</code>, <code>e</code>, <code>@</code>,
|
||||
<code>?x</code> and <code>|</code>) including the syntactic sugar
|
||||
function <code>r</code> and formatting properties in the form of
|
||||
ignoring whitespace and comments to the end of line introduced by the
|
||||
<code>#</code> character.</p>
|
||||
<p>In case of wrong usage (missing Unlambda program file or missing
|
||||
parameter) or use of an unseekable (<code>fseek(3)</code>) Unlambda
|
||||
program source if it uses the <code>c</code> function, the program
|
||||
returns the message <code>fail</code>. It also informs you about
|
||||
syntactic errors in the Unlambda program should there be any (but only
|
||||
when the execution reaches them).</p>
|
||||
<p>The Unlambda source file may contain several Unlambda programs. The
|
||||
interpreter will run them all in sequence.</p>
|
||||
<p>It will build the tool and use it to build an alternative program <code>prog2</code>, which in turn will
|
||||
produce an Unlambda program <code>identify.unl</code>. <code>make identify</code> runs this program to identify
|
||||
itself.</p>
|
||||
<p>The base program (<code>prog</code>) implements an interpreter of Unlambda 2.0. It
|
||||
recognises all its builtins (<code>k</code>, <code>s</code>, <code>i</code>, <code>v</code>, <code>c</code>, <code>d</code>, <code>.x</code>, <code>e</code>, <code>@</code>, <code>?x</code>
|
||||
and <code>|</code>) including the syntactic sugar function <code>r</code> and formatting properties in
|
||||
the form of ignoring whitespace and comments to the end of line introduced by
|
||||
the <code>#</code> character.</p>
|
||||
<p>In case of wrong usage (missing Unlambda program file or missing parameter) or
|
||||
use of an unseekable (<code>fseek(3)</code>) Unlambda program source if it uses the <code>c</code>
|
||||
function, the program returns the message <code>fail</code>. It also informs you about
|
||||
syntactic errors in the Unlambda program should there be any (but only when the
|
||||
execution reaches them).</p>
|
||||
<p>The Unlambda source file may contain several Unlambda programs. The interpreter
|
||||
will run them all in sequence.</p>
|
||||
<h3 id="unlambda">Unlambda</h3>
|
||||
<p>If you want to familiarise yourself with the language, visit its <a
|
||||
href="https://en.wikipedia.org/wiki/Unlambda"
|
||||
title="Unlambda on Wikipedia">Wikipedia page</a> for a brief
|
||||
introduction or its <a
|
||||
href="http://www.madore.org/~david/programs/unlambda/"
|
||||
title="Unlambda programming language">homepage</a> for an in depth
|
||||
discussion. For further reading you can visit Wikipedia pages on <a
|
||||
href="https://en.wikipedia.org/wiki/Lambda_calculus"
|
||||
title="Lambda Calculus on Wikipedia">Lambda Calculus</a> and <a
|
||||
href="https://en.wikipedia.org/wiki/Combinatory_logic"
|
||||
title="Combinatory Logic on Wikipedia">Combinatory Logic</a>.</p>
|
||||
<p>You can also play with an <a href="https://inazz.jp/unlambda/"
|
||||
title="Online Unlambda interpreter">online interpreter</a> by GitHub
|
||||
user inazz. There you can debug one of the example programs provided or
|
||||
try your wits in writing your own.</p>
|
||||
<p>If you want to familiarise yourself with the language, visit its <a href="https://en.wikipedia.org/wiki/Unlambda" title="Unlambda on Wikipedia">Wikipedia page</a> for
|
||||
a brief introduction or its <a href="http://www.madore.org/~david/programs/unlambda/" title="Unlambda programming language">homepage</a> for an in depth discussion. For further reading you
|
||||
can visit Wikipedia pages on <a href="https://en.wikipedia.org/wiki/Lambda_calculus" title="Lambda Calculus on Wikipedia">Lambda Calculus</a> and <a href="https://en.wikipedia.org/wiki/Combinatory_logic" title="Combinatory Logic on Wikipedia">Combinatory Logic</a>.</p>
|
||||
<p>You can also play with an <a href="https://inazz.jp/unlambda/" title="Online Unlambda interpreter">online interpreter</a> by GitHub user inazz. There you can
|
||||
debug one of the example programs provided or try your wits in writing your own.</p>
|
||||
<h3 id="hints">Hints:</h3>
|
||||
<p>Here are some pointers where to start when trying to understand the
|
||||
interpreter:</p>
|
||||
<p>Here are some pointers where to start when trying to understand the interpreter:</p>
|
||||
<ul>
|
||||
<li>Where are syntax errors detected?</li>
|
||||
<li>How is the memory managed?</li>
|
||||
@@ -264,198 +227,145 @@ interpreter:</p>
|
||||
</ul>
|
||||
<h3 id="obfuscation-sources">Obfuscation sources</h3>
|
||||
<ul>
|
||||
<li>The elephant in the room is the Unlambda language. As we all know,
|
||||
functional programming defies sanity. Furthermore, Unlambda was
|
||||
specifically designed to be unintelligible and hard to code in. Most of
|
||||
its functions are quite simple and straightforward to implement, but two
|
||||
make it a mess: the promise operator <code>d</code> and the call with
|
||||
current continuation <code>c</code>.</li>
|
||||
<li>Most of the additional obfuscation is derived from basic design
|
||||
choices. That is, how the state of the program is stored and how the
|
||||
Unlambda functions are implemented.</li>
|
||||
<li>The elephant in the room is the Unlambda language. As we all know, functional
|
||||
programming defies sanity. Furthermore, Unlambda was specifically designed to be
|
||||
unintelligible and hard to code in. Most of its functions are quite simple and
|
||||
straightforward to implement, but two make it a mess: the promise operator <code>d</code>
|
||||
and the call with current continuation <code>c</code>.</li>
|
||||
<li>Most of the additional obfuscation is derived from basic design choices. That
|
||||
is, how the state of the program is stored and how the Unlambda functions are
|
||||
implemented.</li>
|
||||
</ul>
|
||||
<p>More on this in the <strong>Spoilers</strong> section.</p>
|
||||
<h3 id="build-notes">Build notes:</h3>
|
||||
<p>The program does not require any special treatment by compilers. Some
|
||||
warnings had to be suppressed when compiling with
|
||||
<code>-Wall -Wextra -pedantic</code>. Those were produced because of the
|
||||
formatting of the source code, not any programming technique.
|
||||
Compilation with <code>clang -Weverything</code> produced many more
|
||||
warnings, but those are only relevant for multi-source-file projects and
|
||||
some are really questionable
|
||||
(e.g. <code>-Wdisabled-macro-expansion</code>).</p>
|
||||
<p>The program does not require any special treatment by compilers. Some warnings
|
||||
had to be suppressed when compiling with <code>-Wall -Wextra -pedantic</code>. Those were
|
||||
produced because of the formatting of the source code, not any programming
|
||||
technique. Compilation with <code>clang -Weverything</code> produced many more warnings,
|
||||
but those are only relevant for multi-source-file projects and some are really
|
||||
questionable (e.g. <code>-Wdisabled-macro-expansion</code>).</p>
|
||||
<h3 id="portability">Portability:</h3>
|
||||
<p>Development was done on Debian 9 on x86-64 architecture using mainly
|
||||
Clang 3.8.1-24 and GCC 6.3.0. The source is C11 compliant and does not
|
||||
use any special properties except the following:</p>
|
||||
<p>Development was done on Debian 9 on x86-64 architecture using mainly Clang 3.8.1-24
|
||||
and GCC 6.3.0. The source is C11 compliant and does not use any special properties
|
||||
except the following:</p>
|
||||
<ul>
|
||||
<li>The interpreter sort of relies on tail call optimization. It works
|
||||
well even without it, but the stack runs out quickly with some Unlambda
|
||||
programs (e.g. <code>trivial.unl</code> example from the <a
|
||||
href="http://www.madore.org/~david/programs/unlambda/#distrib"
|
||||
title="Reference Unlambda distribution">reference Unlambda
|
||||
distribution</a> produces segfault). Clang with <code>-O3</code> option
|
||||
does this optimization well and said example does not segfault with it.
|
||||
I was not able to force GCC to optimize it out (probably an operator
|
||||
fault).</li>
|
||||
<li>The only data structure of the program (the <code>union</code>) had
|
||||
much more members originally. I joined all integers to a single
|
||||
<code>long long</code> member in the name of obfuscation. It is used for
|
||||
reference counting (only 1 for every reference) among other uses.
|
||||
<code>size_t</code> should be used for that, but practically, I think
|
||||
the memory would run out sooner than the reference counter in any real
|
||||
world situation even when <code>size_t</code> is bigger than
|
||||
<code>long long</code>. It is also used for storing <code>char</code>s
|
||||
for later printing. This might produce some warnings, but since it was
|
||||
developed using <code>char</code>s it should be always used safely.</li>
|
||||
<li>The interpreter sort of relies on tail call optimization. It works well even
|
||||
without it, but the stack runs out quickly with some Unlambda programs (e.g.
|
||||
<code>trivial.unl</code> example from the <a href="http://www.madore.org/~david/programs/unlambda/#distrib" title="Reference Unlambda distribution">reference Unlambda distribution</a> produces
|
||||
segfault). Clang with <code>-O3</code> option does this optimization well and said example
|
||||
does not segfault with it. I was not able to force GCC to optimize it out
|
||||
(probably an operator fault).</li>
|
||||
<li>The only data structure of the program (the <code>union</code>) had much more
|
||||
members originally. I joined all integers to a single <code>long long</code> member in the
|
||||
name of obfuscation. It is used for reference counting (only 1 for every
|
||||
reference) among other uses. <code>size_t</code> should be used for that, but practically,
|
||||
I think the memory would run out sooner than the reference counter in any real
|
||||
world situation even when <code>size_t</code> is bigger than <code>long long</code>. It is also used
|
||||
for storing <code>char</code>s for later printing. This might produce some warnings, but
|
||||
since it was developed using <code>char</code>s it should be always used safely.</li>
|
||||
</ul>
|
||||
<h3 id="spoilers">Spoilers:</h3>
|
||||
<ul>
|
||||
<li><p>You can examine the <a href="progSpoiler.c">progSpoiler.c</a>
|
||||
file. It is the original final version of the interpreter, before I
|
||||
started the downsizing. It accepts one more optional parameter that
|
||||
specifies a filename for the output Unlambda function (it’s the Unlambda
|
||||
function that remains after all function applications are done). When no
|
||||
filename is provided, <code>stderr</code> is used.</p>
|
||||
<p>The function <em>output</em> is used for this additional
|
||||
functionality. You can use it while debugging to visualise current
|
||||
variables.</p></li>
|
||||
<li><p>The Unlambda functions are represented by a record consisting of
|
||||
an array of five multipurpose arguments. The first one refers to the
|
||||
function implementing its application, the second and the third ones are
|
||||
for arguments of the function, the fourth one is for stack building, and
|
||||
the fifth one is the reference counter.</p>
|
||||
<p>The function argument is used not only for evaluation of the
|
||||
functions, but also as a state variable to decide whether we want to
|
||||
call it, or do something else.</p></li>
|
||||
<li><p>The interpreter reads the Unlambda source as it interprets it,
|
||||
translating the incoming character to a function using a constructor
|
||||
stored in translation array <code>T</code>.</p>
|
||||
<p>This means the interpreter must reposition in the source file
|
||||
whenever current continuation is called.</p></li>
|
||||
<li><p>The state of the interpreter is represented by trees representing
|
||||
evaluated Unlambda functions stored on the C stack as local variables,
|
||||
plus the source file position. When a current continuation is created,
|
||||
the stack is unwound using the fourth argument of the nodes, stored in
|
||||
the continuation, and rebuilt back resuming the evaluation. When its
|
||||
called, the stack is unwound and thrown away, and the stack stored in
|
||||
the continuation is restored.</p>
|
||||
<p>This makes implementation of a complete debugger a bit more
|
||||
challenging.</p>
|
||||
<p>For this to work, the functions that do the work (i.e. make a series
|
||||
of applications and/or evaluations each of which may be a call to
|
||||
current continuation), the <code>s</code> combinator and the
|
||||
<code>`</code> application operation had to be broken down to pieces,
|
||||
one for each application/evaluation and corresponding helper functions
|
||||
for stack rebuilding. (the helper functions are named beginning with
|
||||
<code>r</code> instead of <code>f</code>)</p></li>
|
||||
<li><p>The <code>`</code> application operation does the reading of the
|
||||
Unlambda source when needed. It also implements the promise function.
|
||||
Whenever it would apply it, it overwrites the Apply constructor in
|
||||
translation array <code>T</code>, changing its function to build an
|
||||
unevaluated sub-tree that is later evaluated whenever the promise is
|
||||
<li><p>You can examine the <a href="progSpoiler.c">progSpoiler.c</a> file. It is the original
|
||||
final version of the interpreter, before I started the downsizing. It accepts
|
||||
one more optional parameter that specifies a filename for the output Unlambda
|
||||
function (it’s the Unlambda function that remains after all function
|
||||
applications are done). When no filename is provided, <code>stderr</code> is used.</p>
|
||||
<p>The function <em>output</em> is used for this additional functionality. You can use
|
||||
it while debugging to visualise current variables.</p></li>
|
||||
<li><p>The Unlambda functions are represented by a record consisting of an array of
|
||||
five multipurpose arguments. The first one refers to the function implementing
|
||||
its application, the second and the third ones are for arguments of the
|
||||
function, the fourth one is for stack building, and the fifth one is the
|
||||
reference counter.</p>
|
||||
<p>The function argument is used not only for evaluation of the functions, but also
|
||||
as a state variable to decide whether we want to call it, or do something else.</p></li>
|
||||
<li><p>The interpreter reads the Unlambda source as it interprets it, translating the
|
||||
incoming character to a function using a constructor stored in translation array
|
||||
<code>T</code>.</p>
|
||||
<p>This means the interpreter must reposition in the source file whenever current
|
||||
continuation is called.</p></li>
|
||||
<li><p>The state of the interpreter is represented by trees representing evaluated
|
||||
Unlambda functions stored on the C stack as local variables, plus the source
|
||||
file position. When a current continuation is created, the stack is unwound
|
||||
using the fourth argument of the nodes, stored in the continuation, and rebuilt
|
||||
back resuming the evaluation. When its called, the stack is unwound and thrown
|
||||
away, and the stack stored in the continuation is restored.</p>
|
||||
<p>This makes implementation of a complete debugger a bit more challenging.</p>
|
||||
<p>For this to work, the functions that do the work (i.e. make a series of applications
|
||||
and/or evaluations each of which may be a call to current continuation), the <code>s</code>
|
||||
combinator and the <code>`</code> application operation had to be broken down to pieces, one
|
||||
for each application/evaluation and corresponding helper functions for stack
|
||||
rebuilding. (the helper functions are named beginning with <code>r</code> instead of <code>f</code>)</p></li>
|
||||
<li><p>The <code>`</code> application operation does the reading of the Unlambda source when
|
||||
needed. It also implements the promise function. Whenever it would apply it, it
|
||||
overwrites the Apply constructor in translation array <code>T</code>, changing its function
|
||||
to build an unevaluated sub-tree that is later evaluated whenever the promise is
|
||||
applied.</p></li>
|
||||
<li><p>To further the obfuscation, I shortened the function names while
|
||||
downsizing, but preserved their meaning (with the exception of Apply
|
||||
functions, which I renamed to <code>Y</code> to possibly confuse with
|
||||
<code>Y</code> combinator). Simple functions retained their names to
|
||||
misguide the reader to believe to know what is what. The names of
|
||||
continuation and exit functions were swapped. The names of
|
||||
<code>S</code> and Apply functions were shuffled both for <code>S</code>
|
||||
functions and Apply functions in the same way to hide the meaning of
|
||||
<code>f</code> and <code>r</code> prefixes.</p></li>
|
||||
<li><p>To further the obfuscation, I shortened the function names while downsizing,
|
||||
but preserved their meaning (with the exception of Apply functions, which I
|
||||
renamed to <code>Y</code> to possibly confuse with <code>Y</code> combinator). Simple functions retained
|
||||
their names to misguide the reader to believe to know what is what. The names of
|
||||
continuation and exit functions were swapped. The names of <code>S</code> and Apply functions
|
||||
were shuffled both for <code>S</code> functions and Apply functions in the same way to hide
|
||||
the meaning of <code>f</code> and <code>r</code> prefixes.</p></li>
|
||||
</ul>
|
||||
<h3 id="identification-spoiler">Identification spoiler:</h3>
|
||||
<p>The alternative build path <code>make identify</code> output
|
||||
commemorates a <a href="../../2014/birken/index.html"
|
||||
title="Best use of port 1701">previous IOCCC winning entry</a> which
|
||||
uses similar methods to mess with the size tool.</p>
|
||||
<p>The alternative build path <code>make identify</code> output commemorates a <a href="../../2014/birken/index.html" title="Best use of port 1701">previous IOCCC
|
||||
winning entry</a> which uses similar methods to mess with the size tool.</p>
|
||||
<h3 id="judges-spoilers">Judges’ spoilers:</h3>
|
||||
<p>It is not a bug, it is a feature. :)</p>
|
||||
<p>The crash is caused by a stack overflow. Conventional Unlabmda
|
||||
interpreters implement the Unlambda execution stack using data
|
||||
structures on the heap. This interpreter uses the C call stack for this
|
||||
purpose. In a conventional interpreter, the judges’ program would
|
||||
consume memory until the user (or the operating system) would lose
|
||||
patience. The C call stack is usually of a limited size and protected,
|
||||
so this interpreter crashes, when the judges’ program depletes the
|
||||
stack. You can always increase the maximal stack size through the system
|
||||
settings (on Linux) or compiler options (on Windows) if your Unlambda
|
||||
program needs it. Nevertheless, it will not help the judges’ program
|
||||
which quickly depletes any limit you define.</p>
|
||||
<p>The judges, pretending to not know what they are doing, created a
|
||||
program that grows Unlambda execution stack indefinitely. You may
|
||||
consider it an Unlambda anti-pattern. Normally, infinite cycles in
|
||||
Unlambda work by creating two functions and applying one to the other
|
||||
which creates further functions to apply. The application of the
|
||||
function frees its position on the stack. This program builds one ever
|
||||
growing function that will never be complete and be able to be
|
||||
applied.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<p>The crash is caused by a stack overflow. Conventional Unlabmda interpreters
|
||||
implement the Unlambda execution stack using data structures on the heap. This
|
||||
interpreter uses the C call stack for this purpose. In a conventional
|
||||
interpreter, the judges’ program would consume memory until the user (or the
|
||||
operating system) would lose patience. The C call stack is usually of a limited
|
||||
size and protected, so this interpreter crashes, when the judges’ program
|
||||
depletes the stack. You can always increase the maximal stack size through the
|
||||
system settings (on Linux) or compiler options (on Windows) if your Unlambda
|
||||
program needs it. Nevertheless, it will not help the judges’ program which
|
||||
quickly depletes any limit you define.</p>
|
||||
<p>The judges, pretending to not know what they are doing, created a program that
|
||||
grows Unlambda execution stack indefinitely. You may consider it an Unlambda
|
||||
anti-pattern. Normally, infinite cycles in Unlambda work by creating two
|
||||
functions and applying one to the other which creates further functions to
|
||||
apply. The application of the function frees its position on the stack. This
|
||||
program builds one ever growing function that will never be complete and be able to
|
||||
be applied.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019adamovsky"><a name="inventory"></a>Inventory
|
||||
for 2019/adamovsky</h1>
|
||||
<h1 id="inventory-for-2019adamovsky"><a name="inventory"></a>Inventory for 2019/adamovsky</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/advent.unl">advent.unl</a>
|
||||
- unlambda script</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/crash.unl">crash.unl</a>
|
||||
- unlambda script</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/iocccsize_2018.c">iocccsize_2018.c</a>
|
||||
- 2018 iocccsize source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/progSpoiler.c">progSpoiler.c</a>
|
||||
- SPOILER WARNING</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/sierpinski.unl">sierpinski.unl</a>
|
||||
- unlambda code</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/spam.unl">spam.unl</a>
|
||||
- unlambda code</li>
|
||||
<li><a href="2019_adamovsky.tar.bz2">2019_adamovsky.tar.bz2</a> -
|
||||
download entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/advent.unl">advent.unl</a> - unlambda script</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/crash.unl">crash.unl</a> - unlambda script</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/iocccsize_2018.c">iocccsize_2018.c</a> - 2018 iocccsize source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/progSpoiler.c">progSpoiler.c</a> - SPOILER WARNING</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/sierpinski.unl">sierpinski.unl</a> - unlambda code</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/spam.unl">spam.unl</a> - unlambda code</li>
|
||||
<li><a href="2019_adamovsky.tar.bz2">2019_adamovsky.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/adamovsky/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+48
-81
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Dave_Burton">Dave Burton</a><br>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of
|
||||
America</em> (<em>United States</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -144,8 +144,7 @@ America</em> (<em>United States</em>) <br><br></li>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_burton">2019 burton bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_burton">2019 burton bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> file</span>
|
||||
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
@@ -153,112 +152,80 @@ href="../../bugs.html#2019_burton">2019 burton bugs</a>.</p>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>A tiny, but punctually correct way of POSIX counting for text files.
|
||||
This one line, one word, 127 character beauty continues to expand the
|
||||
number of classic unix utilities available as winning entries.</p>
|
||||
<p>You might find the author’s <a href="on.one.liners.txt">commentary on
|
||||
one liners</a> interesting.</p>
|
||||
<p>A tiny, but punctually correct way of POSIX counting for text files. This one
|
||||
line, one word, 127 character beauty continues to expand the number of classic
|
||||
unix utilities available as winning entries.</p>
|
||||
<p>You might find the author’s <a href="on.one.liners.txt">commentary on one liners</a>
|
||||
interesting.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="synopsis">Synopsis:</h3>
|
||||
<p>Feed it anything on <code>stdin</code>. The output should look
|
||||
familiar.</p>
|
||||
<p>Feed it anything on <code>stdin</code>.
|
||||
The output should look familiar.</p>
|
||||
<p>Compiles cleanly with:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="va">WARN</span><span class="op">=</span><span class="st">"-Wno-implicit-int -Wno-missing-variable-declarations -Wno-parentheses"</span></span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">cc</span> <span class="at">-Wall</span> <span class="at">-Wextra</span> <span class="at">-Weverything</span> <span class="at">-pedantic</span> <span class="va">$WARN</span> <span class="at">-include</span> stdio.h <span class="at">-o</span> prog prog.c</span></code></pre></div>
|
||||
<h3 id="description">Description:</h3>
|
||||
<p>Included is a test script, useful for the corner cases. As in all
|
||||
good Unix programs, it is silent upon success; any output demonstrates
|
||||
an error. Instead of checking correctness, the <a
|
||||
href="check.sh">check.sh</a> script can simply output the results: (The
|
||||
Makefile contains the spoiler):</p>
|
||||
<p>Included is a test script, useful for the corner cases. As in all good Unix
|
||||
programs, it is silent upon success; any output demonstrates an error. Instead
|
||||
of checking correctness, the <a href="check.sh">check.sh</a> script can simply output the
|
||||
results: (The Makefile contains the spoiler):</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="va">out</span><span class="op">=</span>cat <span class="ex">./check.sh</span> ./prog</span></code></pre></div>
|
||||
<p>Interestingly, and a spoiler here: macOS and FreeBSD implement the
|
||||
common utility “correctly”. CentOS and Ubuntu both share a “flawed”
|
||||
utility that changes output format based upon input redirection or
|
||||
pipeline(!). As well, the latter two also behave slightly differently on
|
||||
what they count as whitespace: <code>\a</code> and <code>\b</code> are
|
||||
both counted whitespace(!), even though the relevant man pages on these
|
||||
systems omit these characters from the description.</p>
|
||||
<p>This program follows FreeBSD and macOS, the arbiters of correct for
|
||||
these purposes.</p>
|
||||
<p>Interestingly, and a spoiler here: macOS and FreeBSD implement the common
|
||||
utility “correctly”. CentOS and Ubuntu both share a “flawed” utility that
|
||||
changes output format based upon input redirection or pipeline(!). As well, the
|
||||
latter two also behave slightly differently on what they count as whitespace:
|
||||
<code>\a</code> and <code>\b</code> are both counted whitespace(!), even though the relevant man pages
|
||||
on these systems omit these characters from the description.</p>
|
||||
<p>This program follows FreeBSD and macOS, the arbiters of correct for these purposes.</p>
|
||||
<h3 id="limits">Limits:</h3>
|
||||
<p>Requires the C locale and ASCII character set. Input should be less
|
||||
than ten million octets “toavoidthisproblem”.</p>
|
||||
<p>Requires the C locale and ASCII character set.
|
||||
Input should be less than ten million octets “toavoidthisproblem”.</p>
|
||||
<h3 id="see-also">See Also:</h3>
|
||||
<p>You can enjoy this code from beginning to end. No whitespace was
|
||||
harmed in the creation of this program. All your base belong to us, but
|
||||
the constants seem a bit … off?</p>
|
||||
<p>You can enjoy this code from beginning to end.
|
||||
No whitespace was harmed in the creation of this program.
|
||||
All your base belong to us, but the constants seem a bit … off?</p>
|
||||
<h3 id="bonus">Bonus</h3>
|
||||
<p>The script <a href="cow.sh">cow.sh</a> provides a closer analog, and
|
||||
perhaps a more useful interface.</p>
|
||||
<p>The script <a href="cow.sh">cow.sh</a> provides a closer analog, and perhaps a more useful
|
||||
interface.</p>
|
||||
<p>Included is a version without compilation warnings:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cc</span> <span class="at">-Wall</span> <span class="at">-Wextra</span> <span class="at">-Weverything</span> <span class="at">-pedantic</span> <span class="at">-include</span> stdio.h <span class="at">-o</span> prog.clean prog.clean.c</span></code></pre></div>
|
||||
<h3 id="bugs">Bugs</h3>
|
||||
<p>The flags are not supported. Although they could easily be added into
|
||||
<code>cow.sh</code>. This exercise left to the reader.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<p>The flags are not supported. Although they could easily be added into <code>cow.sh</code>.
|
||||
This exercise left to the reader.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019burton"><a name="inventory"></a>Inventory for
|
||||
2019/burton</h1>
|
||||
<h1 id="inventory-for-2019burton"><a name="inventory"></a>Inventory for 2019/burton</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/check.sh">check.sh</a>
|
||||
- test suite</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/cow.sh">cow.sh</a>
|
||||
- an alternate implementation with a useful interface</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/on.one.liners.txt">on.one.liners.txt</a>
|
||||
- on writing an IOCCC one-liner</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/prog.clean.c">prog.clean.c</a>
|
||||
- version of source without compilation warnings</li>
|
||||
<li><a href="2019_burton.tar.bz2">2019_burton.tar.bz2</a> - download
|
||||
entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/check.sh">check.sh</a> - test suite</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/cow.sh">cow.sh</a> - an alternate implementation with a useful interface</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/on.one.liners.txt">on.one.liners.txt</a> - on writing an IOCCC one-liner</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/prog.clean.c">prog.clean.c</a> - version of source without compilation warnings</li>
|
||||
<li><a href="2019_burton.tar.bz2">2019_burton.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a href="256">256</a> - test suite data</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/newlines">newlines</a>
|
||||
- more useful interface.</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/README.md">README.md</a> - markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/burton/newlines">newlines</a> - more useful interface.</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+100
-168
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Marcin_Ciura">Marcin Ciura</a><br>
|
||||
Location: <a href="../../location.html#PL">PL</a> - <em>Republic of
|
||||
Poland</em> (<em>Poland</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#PL">PL</a> - <em>Republic of Poland</em> (<em>Poland</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -141,21 +141,19 @@ Poland</em> (<em>Poland</em>) <br><br></li>
|
||||
|
||||
<h2 id="to-build">To build:</h2>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>There is an alternate version available. See <a
|
||||
href="#alternate-code">Alternate code</a> below.</p>
|
||||
<p>There is an alternate version available. See <a href="#alternate-code">Alternate code</a>
|
||||
below.</p>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_ciura">2019 ciura bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_ciura">2019 ciura bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./getwords.sh</span> en <span class="kw">|</span> <span class="fu">grep</span> .. <span class="kw">|</span> <span class="ex">./prog</span> string</span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<h2 id="alternate-code">Alternate code:</h2>
|
||||
<p>There is an alternate version of this code that flushes
|
||||
<code>stdout</code> after writing a newline. See the Author’s remarks
|
||||
for more information.</p>
|
||||
<p>There is an alternate version of this code that flushes <code>stdout</code> after writing a
|
||||
newline. See the Author’s remarks for more information.</p>
|
||||
<h3 id="alternate-build">Alternate build:</h3>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> alt</span></code></pre></div>
|
||||
<h3 id="alternate-use">Alternate use:</h3>
|
||||
@@ -163,13 +161,13 @@ for more information.</p>
|
||||
<h3 id="alternate-try">Alternate try:</h3>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.alt.sh</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>A few letters, one at a time, with no repeats. How many different
|
||||
ways can this be done?</p>
|
||||
<p>While a quick brown fox might jump over the lazy dog, it has too many
|
||||
repeat letters to allow this entry to repeat. It is better that Mr Jock,
|
||||
TV quiz PhD, bags few lynx.</p>
|
||||
<p>Speaking of jumping, can you rewrite the code to remove all of the
|
||||
goto jumps in this code?</p>
|
||||
<p>A few letters, one at a time, with no repeats. How many different ways can this
|
||||
be done?</p>
|
||||
<p>While a quick brown fox might jump over the lazy dog, it has too many repeat
|
||||
letters to allow this entry to repeat. It is better that Mr Jock, TV quiz PhD,
|
||||
bags few lynx.</p>
|
||||
<p>Speaking of jumping, can you rewrite the code to remove all of the goto jumps in
|
||||
this code?</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="what-is-this">What is this? <a name="wit"></a></h3>
|
||||
<p>This entry reads from standard input a list of words in any language
|
||||
@@ -196,191 +194,125 @@ of the alphabet exactly once.</p>
|
||||
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a><span class="ex">quiz</span> jamb pyx vs kc growl fed nth</span></code></pre></div>
|
||||
<p>Rearranging the words into more or less meaningful expressions is the
|
||||
user’s duty.</p>
|
||||
<p>This entry implements Algorithm X (<em>Exact cover via dancing
|
||||
links</em>) from Section 7.2.2.1 in fascicle 5C of <em>The Art of
|
||||
Computer Programming</em> by Donald E. Knuth. As of June 2019, you can
|
||||
download an incomplete draft of the fascicle from <a
|
||||
href="https://www-cs-faculty.stanford.edu/~knuth/fasc5c.ps.gz">Knuth’s
|
||||
website</a>, converted to PDF as <a href="fasc5c.pdf">fasc5c.pdf</a> for
|
||||
your convenience.</p>
|
||||
<p>This entry implements Algorithm X (<em>Exact cover via dancing links</em>)
|
||||
from Section 7.2.2.1 in fascicle 5C of <em>The Art of Computer
|
||||
Programming</em> by Donald E. Knuth. As of June 2019, you can download an
|
||||
incomplete draft of the fascicle from <a href="https://www-cs-faculty.stanford.edu/~knuth/fasc5c.ps.gz">Knuth’s
|
||||
website</a>, converted to
|
||||
PDF as <a href="fasc5c.pdf">fasc5c.pdf</a> for your convenience.</p>
|
||||
<h3 id="usage">Usage:</h3>
|
||||
<p><code>./prog LETTERS [N]</code></p>
|
||||
<p>reads allowed words from standard input and writes perfect pangrams
|
||||
with at most <code>N</code> words composed of <code>LETTERS</code> to
|
||||
standard output, one per line. If <code>N</code> is not given, the
|
||||
number of words in the pangrams is unlimited. The characters in
|
||||
<code>LETTERS</code> must not repeat. The length of <code>LETTERS</code>
|
||||
must not exceed 97 characters.</p>
|
||||
with at most <code>N</code> words composed of <code>LETTERS</code> to standard output, one
|
||||
per line. If <code>N</code> is not given, the number of words in the pangrams is
|
||||
unlimited. The characters in <code>LETTERS</code> must not repeat. The length of
|
||||
<code>LETTERS</code> must not exceed 97 characters.</p>
|
||||
<p>The exit status is 0 if no error occurred, 1 if the input word list
|
||||
is too long, and 2 if the command-line arguments are missing.</p>
|
||||
<h3 id="helper-scripts">Helper scripts:</h3>
|
||||
<ul>
|
||||
<li><p><a href="getwords.sh">getwords.sh</a></p>
|
||||
<p><code>./getwords.sh LANGUAGE_CODE</code></p>
|
||||
<p>outputs a sorted list of unique words in a given language, one per
|
||||
line. It requires <code>aspell</code> with a dictionary for
|
||||
<em>LANGUAGE_CODE</em>.</p></li>
|
||||
<p>outputs a sorted list of unique words in a given language, one per line. It
|
||||
requires <code>aspell</code> with a dictionary for <em>LANGUAGE_CODE</em>.</p></li>
|
||||
<li><p><a href="wrapprog.py">wrapprog.py</a></p>
|
||||
<p><code>./wrapprog.py LETTERS [N]</code></p>
|
||||
<p>works similarly to <code>./prog LETTERS [N]</code> except that it
|
||||
merges pangrams before passing them to <code>prog</code> and expands
|
||||
them in <code>prog</code>’s output. This way, it finishes the job faster
|
||||
than <code>prog</code> when there are millions of perfect pangrams. It
|
||||
requires a UTF-8 locale.</p></li>
|
||||
<li><p><a href="de.sh">de.sh</a>, <a href="en.sh">en.sh</a>, <a
|
||||
href="fr.sh">fr.sh</a>, <a href="it.sh">it.sh</a>, <a
|
||||
href="pl.sh">pl.sh</a>, and <a href="ru.sh">ru.sh</a> output German,
|
||||
English, French, Italian, Polish, and Russian perfect pangrams,
|
||||
respectively. They require a UTF-8 locale.</p></li>
|
||||
<p>works similarly to <code>./prog LETTERS [N]</code> except that it merges pangrams
|
||||
before passing them to <code>prog</code> and expands them in <code>prog</code>’s output. This way,
|
||||
it finishes the job faster than <code>prog</code> when there are millions of perfect
|
||||
pangrams. It requires a UTF-8 locale.</p></li>
|
||||
<li><p><a href="de.sh">de.sh</a>, <a href="en.sh">en.sh</a>, <a href="fr.sh">fr.sh</a>, <a href="it.sh">it.sh</a>,
|
||||
<a href="pl.sh">pl.sh</a>, and <a href="ru.sh">ru.sh</a> output German,
|
||||
English, French, Italian, Polish, and Russian perfect pangrams, respectively.
|
||||
They require a UTF-8 locale.</p></li>
|
||||
</ul>
|
||||
<h3 id="miscellaneous-remarks">Miscellaneous remarks:</h3>
|
||||
<p>I dare submit this entry to categories <em>algorithms</em>,
|
||||
<em>internationalization</em> (I have not found active use of
|
||||
<code><wchar.h></code> among the programs that won IOCCC in the
|
||||
past), and <em>obscure bugs</em> (see the questions about Linux core
|
||||
dumps below).</p>
|
||||
<p>To a casual eye, this entry may look similar to <a
|
||||
href="../../2005/klausler/index.html">2005/klausler</a>. However,
|
||||
<code>prog</code> is internationalized and way faster. On my machine,
|
||||
<code>./klausler abcdefghijklmnopqrstuvwxyz</code> printed only 3,965
|
||||
perfect pangrams until I killed it after 144 hours running, while the
|
||||
<em>internationalization</em> (I have not found active use of <code><wchar.h></code>
|
||||
among the programs that won IOCCC in the past), and <em>obscure bugs</em> (see
|
||||
the questions about Linux core dumps below).</p>
|
||||
<p>To a casual eye, this entry may look similar to
|
||||
<a href="../../2005/klausler/index.html">2005/klausler</a>.
|
||||
However, <code>prog</code> is internationalized and way faster. On my machine,
|
||||
<code>./klausler abcdefghijklmnopqrstuvwxyz</code> printed only 3,965 perfect
|
||||
pangrams until I killed it after 144 hours running, while the
|
||||
equivalent
|
||||
<code>tr A-Z a-z < /usr/share/dict/words | egrep -v '^[^ais]$' | ./prog abcdefghijklmnopqrstuvwxyz | wc -l</code>
|
||||
finished in 62 minutes, reporting 1,640,569,315 perfect pangrams, and
|
||||
the example from section <a href="#wit">What is this?</a> finished in
|
||||
1.35 seconds. On the other hand, <code>prog</code> can only output
|
||||
series of words with non-repeating characters, unlike
|
||||
<code>klausler</code>.</p>
|
||||
<p>In contrast to <a href="prog.alt.c">prog.alt.c</a>, <a
|
||||
href="prog.c">prog.c</a> does not call <code>fflush(stdout)</code> after
|
||||
outputting each line, thus running faster. I am grateful to Witold
|
||||
Jarnicki for suggesting this change. The original <code>prog</code>
|
||||
finished the example above in 100 minutes instead of 62 minutes.</p>
|
||||
the example from section <a href="#wit">What is this?</a> finished in 1.35
|
||||
seconds. On the other hand, <code>prog</code> can only output series of words
|
||||
with non-repeating characters, unlike <code>klausler</code>.</p>
|
||||
<p>In contrast to <a href="prog.alt.c">prog.alt.c</a>, <a href="prog.c">prog.c</a> does not call
|
||||
<code>fflush(stdout)</code> after outputting each line, thus running faster.
|
||||
I am grateful to Witold Jarnicki for suggesting this change.
|
||||
The original <code>prog</code> finished the example above in 100 minutes
|
||||
instead of 62 minutes.</p>
|
||||
<p>If your word list contains meaningless one-letter words, pipe
|
||||
<code>grep .. [FILE]</code> through <code>prog</code> to eliminate the
|
||||
pangrams that contain them.</p>
|
||||
<p>According to <code>prog</code> and <code>aspell</code>, some
|
||||
languages, e.g. Spanish, have no perfect pangrams.</p>
|
||||
<p>Why does <code>yes | ./prog y</code> hang on Linux? Change
|
||||
<code>static int</code> to <code>int</code> and
|
||||
<code>static wchar_t</code> to <code>wchar_t</code>, and recompile
|
||||
<code>prog</code>. Why does <code>yes | ./prog y</code> dump core now?
|
||||
Change the line <code>#define P 9<<23^1</code> to
|
||||
<code>#define P 9<<23</code> and recompile <code>prog</code>. Why
|
||||
does <code>yes | ./prog y</code> exit gracefully?</p>
|
||||
<p>Answer: As of June 2019, thus manifest bugs in <code>glibc</code>
|
||||
2.22–2.29: <a
|
||||
href="https://sourceware.org/bugzilla/show_bug.cgi?id=20568">1</a> naq
|
||||
<a
|
||||
href="https://sourceware.org/bugzilla/show_bug.cgi?id=20632">2</a>.</p>
|
||||
<p>The source code uses <code>goto</code> three times. While it could
|
||||
easily get by without <code>goto M</code> and <code>goto H</code>, I
|
||||
challenge the adherents of structured programming to refactor
|
||||
<code>goto T</code>, which jumps back into a nested <code>if</code>
|
||||
block.</p>
|
||||
<p>With the supplied <a href="Makefile">Makefile</a>, both
|
||||
<code>gcc</code> and <code>clang</code> compile <a
|
||||
href="prog.c">prog.c</a> without warnings in C11 and C99 mode. For a
|
||||
clean compilation with <code>gcc -std=c90</code>, add
|
||||
<code>-Wno-format</code> to <code>CSILENCE</code> in
|
||||
<code>Makefile</code>.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<code>grep .. [FILE]</code> through <code>prog</code> to eliminate the pangrams that
|
||||
contain them.</p>
|
||||
<p>According to <code>prog</code> and <code>aspell</code>, some languages, e.g. Spanish,
|
||||
have no perfect pangrams.</p>
|
||||
<p>Why does <code>yes | ./prog y</code> hang on Linux? Change <code>static int</code> to
|
||||
<code>int</code> and <code>static wchar_t</code> to <code>wchar_t</code>, and recompile
|
||||
<code>prog</code>. Why does <code>yes | ./prog y</code> dump core now? Change the line
|
||||
<code>#define P 9<<23^1</code> to <code>#define P 9<<23</code> and recompile
|
||||
<code>prog</code>. Why does <code>yes | ./prog y</code> exit gracefully?</p>
|
||||
<p>Answer: As of June 2019, thus manifest bugs in <code>glibc</code> 2.22–2.29:
|
||||
<a href="https://sourceware.org/bugzilla/show_bug.cgi?id=20568">1</a> naq
|
||||
<a href="https://sourceware.org/bugzilla/show_bug.cgi?id=20632">2</a>.</p>
|
||||
<p>The source code uses <code>goto</code> three times. While it could easily get
|
||||
by without <code>goto M</code> and <code>goto H</code>, I challenge the adherents of
|
||||
structured programming to refactor <code>goto T</code>, which jumps back into a
|
||||
nested <code>if</code> block.</p>
|
||||
<p>With the supplied <a href="Makefile">Makefile</a>, both <code>gcc</code> and <code>clang</code> compile
|
||||
<a href="prog.c">prog.c</a> without warnings in C11 and C99 mode. For a clean
|
||||
compilation with <code>gcc -std=c90</code>, add <code>-Wno-format</code> to
|
||||
<code>CSILENCE</code> in <code>Makefile</code>.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019ciura"><a name="inventory"></a>Inventory for
|
||||
2019/ciura</h1>
|
||||
<h1 id="inventory-for-2019ciura"><a name="inventory"></a>Inventory for 2019/ciura</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/prog.alt.c">prog.alt.c</a>
|
||||
- alternative source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/de.alt.sh">de.alt.sh</a>
|
||||
- how to run alternative code in Germain</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/en.alt.sh">en.alt.sh</a>
|
||||
- how to run alternative code in English</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/getwords.sh">getwords.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/it.alt.sh">it.alt.sh</a>
|
||||
- how to run alternative code in Italian</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/pl.alt.sh">pl.alt.sh</a>
|
||||
- how to run alternative code in Polish</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/ru.alt.sh">ru.alt.sh</a>
|
||||
- how to run alternative code in Russian</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/try.alt.sh">try.alt.sh</a>
|
||||
- how to run alternative code</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/wrapprog.py">wrapprog.py</a>
|
||||
- merge pangrams before passing them to prog</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/de.sh">de.sh</a>
|
||||
- run with German data</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/en.sh">en.sh</a>
|
||||
- run with English data</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/fr.alt.sh">fr.alt.sh</a>
|
||||
- how to run alternative code in French</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/fr.sh">fr.sh</a>
|
||||
- run with French data</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/it.sh">it.sh</a>
|
||||
- run with Italian data</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/pl.sh">pl.sh</a>
|
||||
- run with Polish data</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/ru.sh">ru.sh</a>
|
||||
- run with Russian data</li>
|
||||
<li><a href="fasc5c.pdf">fasc5c.pdf</a> - The Art of Computer
|
||||
Programming vol 4 draft</li>
|
||||
<li><a href="2019_ciura.tar.bz2">2019_ciura.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/prog.alt.c">prog.alt.c</a> - alternative source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/de.alt.sh">de.alt.sh</a> - how to run alternative code in Germain</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/en.alt.sh">en.alt.sh</a> - how to run alternative code in English</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/getwords.sh">getwords.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/it.alt.sh">it.alt.sh</a> - how to run alternative code in Italian</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/pl.alt.sh">pl.alt.sh</a> - how to run alternative code in Polish</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/ru.alt.sh">ru.alt.sh</a> - how to run alternative code in Russian</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/try.alt.sh">try.alt.sh</a> - how to run alternative code</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/wrapprog.py">wrapprog.py</a> - merge pangrams before passing them to prog</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/de.sh">de.sh</a> - run with German data</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/en.sh">en.sh</a> - run with English data</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/fr.alt.sh">fr.alt.sh</a> - how to run alternative code in French</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/fr.sh">fr.sh</a> - run with French data</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/it.sh">it.sh</a> - run with Italian data</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/pl.sh">pl.sh</a> - run with Polish data</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/ru.sh">ru.sh</a> - run with Russian data</li>
|
||||
<li><a href="fasc5c.pdf">fasc5c.pdf</a> - The Art of Computer Programming vol 4 draft</li>
|
||||
<li><a href="2019_ciura.tar.bz2">2019_ciura.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/ciura/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
@@ -129,9 +129,9 @@
|
||||
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Volker_Diels-Grabsch">Volker
|
||||
Diels-Grabsch</a><br> Location: <a href="../../location.html#DE">DE</a>
|
||||
- <em>Federal Republic of Germany</em> (<em>Germany</em>) <br><br></li>
|
||||
<li>Name: <a href="../../authors.html#Volker_Diels-Grabsch">Volker Diels-Grabsch</a><br>
|
||||
Location: <a href="../../location.html#DE">DE</a> - <em>Federal Republic of Germany</em> (<em>Germany</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -146,14 +146,13 @@ Diels-Grabsch</a><br> Location: <a href="../../location.html#DE">DE</a>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Finally, IOCCC now has its own text compression program, and it is
|
||||
short enough to qualify for the Best Short Program award! That said, can
|
||||
you compress it down to a one-liner, still producing files in the UNIX
|
||||
compress format, albeit sacrificing the compression ratio?</p>
|
||||
<p>Can you explain why the <code>/dev/zero</code> file compresses
|
||||
identically by the entry and the standard <code>compress(1)</code> tool
|
||||
(see <a href="try.sh">try.sh</a>), but the text file compresses
|
||||
differently? The judges know. :)</p>
|
||||
<p>Finally, IOCCC now has its own text compression program, and it is short enough
|
||||
to qualify for the Best Short Program award! That said, can you compress it down
|
||||
to a one-liner, still producing files in the UNIX compress format, albeit
|
||||
sacrificing the compression ratio?</p>
|
||||
<p>Can you explain why the <code>/dev/zero</code> file compresses identically by the entry and
|
||||
the standard <code>compress(1)</code> tool (see <a href="try.sh">try.sh</a>), but the text file
|
||||
compresses differently? The judges know. :)</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="a-tiny-compress-tool">A tiny “compress” tool:</h3>
|
||||
<h4 id="usage">Usage:</h4>
|
||||
@@ -163,74 +162,47 @@ differently? The judges know. :)</p>
|
||||
<h4 id="check-for-correctness">Check for correctness:</h4>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zcat</span> guidelines.txt.Z <span class="op">></span> guidelines2.txt</span>
|
||||
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="fu">diff</span> <span class="at">-s</span> guidelines.txt guidelines2.txt</span></code></pre></div>
|
||||
<p>Of course you can also use <a
|
||||
href="../../2015/mills2/mills2.c">2015/mills2</a> instead of
|
||||
<code>zcat</code> to verify the output file. The achieved compression
|
||||
ratio roughly matches that of the classic Unix <code>compress(1)</code>
|
||||
tool. And the source code is very compressed, too: It has exactly the
|
||||
same size as the paragraph you are reading right now. And exactly the
|
||||
same shape. Nevertheless, it is portable C99 code that runs on 32-bit
|
||||
and 64-bit platforms. It compiles without warnings on both GCC and Clang
|
||||
even with <code>-Wextra and -Weverything</code>.</p>
|
||||
<p>Of course you can also use <a href="../../2015/mills2/mills2.c">2015/mills2</a> instead of
|
||||
<code>zcat</code> to verify the output file. The achieved compression ratio roughly matches
|
||||
that of the classic Unix <code>compress(1)</code> tool. And the source code is very
|
||||
compressed, too: It has exactly the same size as the paragraph you are reading
|
||||
right now. And exactly the same shape. Nevertheless, it is portable C99 code
|
||||
that runs on 32-bit and 64-bit platforms. It compiles without warnings on both
|
||||
GCC and Clang even with <code>-Wextra and -Weverything</code>.</p>
|
||||
<blockquote>
|
||||
<p>2023 note: the above paragraph might not be true as far as number of
|
||||
bytes goes.</p>
|
||||
<p>2023 note: the above paragraph might not be true as far as number of bytes
|
||||
goes.</p>
|
||||
</blockquote>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1
|
||||
id="inventory-for-2019diels-grabsch1"><a name="inventory"></a>Inventory
|
||||
for 2019/diels-grabsch1</h1>
|
||||
<h1 id="inventory-for-2019diels-grabsch1"><a name="inventory"></a>Inventory for 2019/diels-grabsch1</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/guidelines.txt">guidelines.txt</a>
|
||||
- input data from 2018 IOCCC guidelines</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/Shakespeare.txt">Shakespeare.txt</a>
|
||||
- Coriolanus by Shakespeare</li>
|
||||
<li><a
|
||||
href="2019_diels-grabsch1.tar.bz2">2019_diels-grabsch1.tar.bz2</a> -
|
||||
download entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/guidelines.txt">guidelines.txt</a> - input data from 2018 IOCCC guidelines</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/Shakespeare.txt">Shakespeare.txt</a> - Coriolanus by Shakespeare</li>
|
||||
<li><a href="2019_diels-grabsch1.tar.bz2">2019_diels-grabsch1.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch1/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+98
-128
@@ -129,9 +129,9 @@
|
||||
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Volker_Diels-Grabsch">Volker
|
||||
Diels-Grabsch</a><br> Location: <a href="../../location.html#DE">DE</a>
|
||||
- <em>Federal Republic of Germany</em> (<em>Germany</em>) <br><br></li>
|
||||
<li>Name: <a href="../../authors.html#Volker_Diels-Grabsch">Volker Diels-Grabsch</a><br>
|
||||
Location: <a href="../../location.html#DE">DE</a> - <em>Federal Republic of Germany</em> (<em>Germany</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -146,30 +146,27 @@ Diels-Grabsch</a><br> Location: <a href="../../location.html#DE">DE</a>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Before running this one, stay calm. Chill out, have a cup of tea. Is
|
||||
this bad?</p>
|
||||
<p>To understand what is going on here, please check if you are
|
||||
dreaming, or are you dreaming that you are dreaming? Or is it, wake up
|
||||
from the simulation?</p>
|
||||
<p>Before running this one, stay calm. Chill out, have a cup of tea. Is this bad?</p>
|
||||
<p>To understand what is going on here, please check if you are dreaming, or are you dreaming
|
||||
that you are dreaming? Or is it, wake up from the simulation?</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="almost-a-hash-collision">Almost a hash collision:</h3>
|
||||
<p>This program prints its own SHA-512 hash. To verify, run:</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sha512sum prog.c<span class="kw">;</span> <span class="ex">./prog</span></span>
|
||||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="ex">43bd0c4381a5078d2850fca9ae5e0647596bcc03cd67d8d973ad02ff35c316c728e7b347ca70abe6c74e745e63646cc7643cb0cffcd3d9a969cbf31a7ce5bf68</span> prog.c</span>
|
||||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="ex">43bd0c4381a5078d2850fca9ae5e0647596bcc03cd67d8d973ad02ff35c316c728e7b347ca70abe6c74e745e63646cc7643cb0cffcd3d9a969cbf31a7ce5bf68</span></span></code></pre></div>
|
||||
<p>It started as a complicated “hello world” program that prints some
|
||||
random hex digits instead of “hello world”. Then, the digits were
|
||||
adjusted until the resulting program matched its own SHA-512 hash, via
|
||||
brute force through all 2^512 possibilities. Just kidding.</p>
|
||||
<p>This wasn’t brute force, but involved quite some math, using a
|
||||
variant of Jane Doe’s algorithm for generating SHA-512 collisions
|
||||
efficiently. If you still don’t believe me, you are right.</p>
|
||||
<p>It started as a complicated “hello world” program that prints some random hex
|
||||
digits instead of “hello world”. Then, the digits were adjusted until the
|
||||
resulting program matched its own SHA-512 hash, via brute force through all
|
||||
2^512 possibilities. Just kidding.</p>
|
||||
<p>This wasn’t brute force, but involved quite some math, using a variant of Jane
|
||||
Doe’s algorithm for generating SHA-512 collisions efficiently. If you still
|
||||
don’t believe me, you are right.</p>
|
||||
<p>No crypto was broken in the making of this program!</p>
|
||||
<p>The trick is that under the hood, this program is a quine! That is,
|
||||
it is aware of its own source code in string representation. But instead
|
||||
of printing that string (its own source), its SHA-512 hash is computed
|
||||
and printed. So two major steps were needed to obfuscate this
|
||||
program:</p>
|
||||
<p>The trick is that under the hood, this program is a quine! That is, it is aware
|
||||
of its own source code in string representation. But instead of printing that
|
||||
string (its own source), its SHA-512 hash is computed and printed. So two major
|
||||
steps were needed to obfuscate this program:</p>
|
||||
<ol type="1">
|
||||
<li>Hide the quine.</li>
|
||||
<li>Hide the SHA-512 computation.</li>
|
||||
@@ -177,28 +174,26 @@ program:</p>
|
||||
<p>Note that both steps were achieved mostly algorithmically. The code
|
||||
is otherwise as short and as clean as possible. The implementation is
|
||||
portable C99 code for 32-bit and 64-bit systems that compiles without
|
||||
any warnings on current GCC and Clang versions even with
|
||||
<code>-Wextra -Weverything</code>. The program is composed of mostly
|
||||
pure functions, and the <code>#define</code>s are only used to shorten
|
||||
redundant parts of the code, they are not meant to obfuscate much.
|
||||
Having that out of the way, how are step 1 and step 2 achieved then?</p>
|
||||
any warnings on current GCC and Clang versions even with <code>-Wextra -Weverything</code>. The program is composed of mostly pure functions, and
|
||||
the <code>#define</code>s are only used to shorten redundant parts of the code,
|
||||
they are not meant to obfuscate much. Having that out of the way, how
|
||||
are step 1 and step 2 achieved then?</p>
|
||||
<p>Regarding step 1, note that the large string literal</p>
|
||||
<pre><code>"`x{bh}ndbq..."</code></pre>
|
||||
<p>in the last line doesn’t look like C code. Moreover, it is too short
|
||||
to contain even a compressed representation of all preceding and
|
||||
subsequent code. Instead, the preceding code including the
|
||||
<code>"</code> character has already been run through the SHA-512
|
||||
computation by an external script. The internal state of the SHA-512
|
||||
computation at that point has been extracted and encoded into the
|
||||
string. This works because the preceding code is exactly 1280 bytes,
|
||||
which is a multiple of 1024 bits, the block size of SHA-512. The program
|
||||
itself then just continues the SHA-512 computation from that point,
|
||||
adding the last 1024-bit block, finalizing the hash and printing it. The
|
||||
last block is taken directly from the string literal at runtime, plus
|
||||
the subsequent code which consists of just <code>"</code>,
|
||||
<code>;</code> and <code>\n</code>. Those 3 characters are short enough
|
||||
to be hidden in … well, let’s leave this as an exercise for the
|
||||
reader.</p>
|
||||
subsequent code. Instead, the preceding code including the <code>"</code>
|
||||
character has already been run through the SHA-512 computation by an
|
||||
external script. The internal state of the SHA-512 computation at
|
||||
that point has been extracted and encoded into the string. This works
|
||||
because the preceding code is exactly 1280 bytes, which is a multiple
|
||||
of 1024 bits, the block size of SHA-512. The program itself then just
|
||||
continues the SHA-512 computation from that point, adding the last
|
||||
1024-bit block, finalizing the hash and printing it. The last block
|
||||
is taken directly from the string literal at runtime, plus the
|
||||
subsequent code which consists of just <code>"</code>, <code>;</code> and <code>\n</code>. Those 3
|
||||
characters are short enough to be hidden in … well, let’s leave this
|
||||
as an exercise for the reader.</p>
|
||||
<p>To summarize, the main trick here is to move the string constant to
|
||||
the end, so the preceding code can be pre-calculated and the subsequent
|
||||
code is short enough to be hidden anywhere.</p>
|
||||
@@ -206,134 +201,109 @@ code is short enough to be hidden anywhere.</p>
|
||||
meaningless single-letter names. Moreover, the SHA-512 computation is
|
||||
reduced to the special case of adding just one block and immediately
|
||||
finalizing it, where the total size is known in advance.</p>
|
||||
<p>But this is not enough! For SHA-512 we need 8 initial hash values and
|
||||
80 round constants, which are very characteristic. If any of them
|
||||
appeared in the source, a quick web search (e.g. for
|
||||
<code>0x428a2f98d728ae22</code>) would tell the reader immediately
|
||||
what’s going on. Because of the pre-computation, the 8 initial hash
|
||||
<p>But this is not enough! For SHA-512 we need 8 initial hash values and 80 round
|
||||
constants, which are very characteristic. If any of them appeared in the
|
||||
source, a quick web search (e.g. for <code>0x428a2f98d728ae22</code>) would tell the reader
|
||||
immediately what’s going on. Because of the pre-computation, the 8 initial hash
|
||||
values are not needed, but the 80 round constants are.</p>
|
||||
<p>It is almost impossible to hide those 640 bytes in the source.
|
||||
Luckily, the round constants where not chosen by fair dice rolls. They
|
||||
are the fractional parts of certain irrational numbers, namely, the cube
|
||||
roots of the first 80 primes. So the round constants are calculated at
|
||||
runtime, which makes the program shorter and adds another layer of
|
||||
obfuscation.</p>
|
||||
<p>While this sounds like just iterating primes and executing
|
||||
<code>pow(3)</code>, this turned out to be harder than expected. If we
|
||||
were computing SHA-256, it would have been as simple as that, because
|
||||
the round constants would have been 32-bit values. However, SHA-512
|
||||
needs the cube roots at 64-bit precision, while <code>double</code> has
|
||||
only 53-bit mantissa precision.</p>
|
||||
Luckily, the round constants where not chosen by fair dice rolls.
|
||||
They are the fractional parts of certain irrational numbers, namely,
|
||||
the cube roots of the first 80 primes. So the round constants are
|
||||
calculated at runtime, which makes the program shorter and adds
|
||||
another layer of obfuscation.</p>
|
||||
<p>While this sounds like just iterating primes and executing <code>pow(3)</code>, this
|
||||
turned out to be harder than expected. If we were computing SHA-256,
|
||||
it would have been as simple as that, because the round constants
|
||||
would have been 32-bit values. However, SHA-512 needs the cube roots
|
||||
at 64-bit precision, while <code>double</code> has only 53-bit mantissa precision.</p>
|
||||
<p>Using higher-precision floating point is no option here, because the
|
||||
program is meant to be portable C99. And implementing
|
||||
arbitrary-precision arithmetic would have been overkill and would have
|
||||
increased the program size dramatically.</p>
|
||||
program is meant to be portable C99. And implementing arbitrary-precision
|
||||
arithmetic would have been overkill and would have increased the program size
|
||||
dramatically.</p>
|
||||
<p>Instead, the program just multiplies. That is, it computes cubes
|
||||
instead of cube roots. It steps through cube root candidates via
|
||||
bisection, and calculates their cubes until those match the given prime.
|
||||
Thus, we don’t need floating point and can use 64-bit integers instead.
|
||||
But that still doesn’t solve the problem as it poses the following new
|
||||
challenges:</p>
|
||||
bisection, and calculates their cubes until those match the given
|
||||
prime. Thus, we don’t need floating point and can use 64-bit integers
|
||||
instead. But that still doesn’t solve the problem as it poses the
|
||||
following new challenges:</p>
|
||||
<ul>
|
||||
<li>Challenge 1: We can multiply at most two 32-bit numbers at
|
||||
once.</li>
|
||||
<li>Challenge 2: We need to calculate with at least 67-bit
|
||||
precision.</li>
|
||||
<li>Challenge 1: We can multiply at most two 32-bit numbers at once.</li>
|
||||
<li>Challenge 2: We need to calculate with at least 67-bit precision.</li>
|
||||
<li>Challenge 3: We need to truncate the cube root result.</li>
|
||||
</ul>
|
||||
<p>The reason for challenge 1 is that in portable C99, the result must
|
||||
fit into the same data type. To multiply two 64-bit integers we would
|
||||
need a 128-bit integer for the result. So we can at most multiply two
|
||||
32-bit integers to get the 64-bit product at full precision. While GCC
|
||||
and Clang both support 128-bit arithmetics, that isn’t standard and
|
||||
wouldn’t have been portable C99.</p>
|
||||
32-bit integers to get the 64-bit product at full precision. While
|
||||
GCC and Clang both support 128-bit arithmetics, that isn’t standard
|
||||
and wouldn’t have been portable C99.</p>
|
||||
<p>The reason for challenge 2 is that cube root of the 80th prime is
|
||||
around 7, so we need to compute with 3 bits for the integral part and 64
|
||||
bits for the fractional part.</p>
|
||||
around 7, so we need to compute with 3 bits for the integral part and
|
||||
64 bits for the fractional part.</p>
|
||||
<p>The reason for challenge 3 is that the cube of a 67-bit number is
|
||||
<code>3*67=201</code> bits, but fortunately we only need to check if it
|
||||
is close enough to the actual prime. It won’t be exactly
|
||||
<code>409.0000...</code> anyway, but must be accurate enough to
|
||||
distinguish the correct cube root from its neighbours, e.g. the same
|
||||
number with the 64th fractional digit increased.</p>
|
||||
<code>3*67=201</code> bits, but fortunately we only need to check if it is close
|
||||
enough to the actual prime. It won’t be exactly <code>409.0000...</code>
|
||||
anyway, but must be accurate enough to distinguish the correct cube
|
||||
root from its neighbours, e.g. the same number with the 64th
|
||||
fractional digit increased.</p>
|
||||
<p>The solution here is to split the 67-bit input into 3 integers of
|
||||
24-bit each. Those are cubed using the multiplication formulas numbers
|
||||
with 3 “digits” of base <code>2^24</code> each. During that calculation,
|
||||
24-bit each. Those are cubed using the multiplication formulas
|
||||
numbers with 3 “digits” of base <code>2^24</code> each. During that calculation,
|
||||
at most two values are multiplied at once, and the accuracy of
|
||||
intermediate values is reduced using right-shifts as far as allowable
|
||||
for the computation. Finding working right-shift values was mostly
|
||||
trial-and-error, producing correct results for the first 80 primes, but
|
||||
not much more. Moreover, for some terms it was possible to leave them
|
||||
out entirely, especially higher-order terms of the last digits. Luckily,
|
||||
in the end, all intermediate results did fit into 64-bit integer
|
||||
addition and multiplication, but that was not obvious at the
|
||||
trial-and-error, producing correct results for the first 80 primes,
|
||||
but not much more. Moreover, for some terms it was possible to leave
|
||||
them out entirely, especially higher-order terms of the last digits.
|
||||
Luckily, in the end, all intermediate results did fit into 64-bit
|
||||
integer addition and multiplication, but that was not obvious at the
|
||||
beginning.</p>
|
||||
<p>That’s it.</p>
|
||||
<p>Well, I could continue with details about the encoding of the
|
||||
internal state values into the string, how to avoid escaping issues, how
|
||||
to find short notations for various loops, how to get rid of
|
||||
<code>if()</code>, where the final <code>"\";\n"</code> is stored, how
|
||||
to eliminate intermediate values and arrays by reordering of operations,
|
||||
and so on. But those were all minor issues compared to the challenges
|
||||
described above. What’s documented here is all you need to know to write
|
||||
your own version of that program.</p>
|
||||
<p>Well, I could continue with details about the encoding of the internal
|
||||
state values into the string, how to avoid escaping issues, how to
|
||||
find short notations for various loops, how to get rid of <code>if()</code>, where
|
||||
the final <code>"\";\n"</code> is stored, how to eliminate intermediate values and
|
||||
arrays by reordering of operations, and so on. But those were all
|
||||
minor issues compared to the challenges described above. What’s
|
||||
documented here is all you need to know to write your own version of
|
||||
that program.</p>
|
||||
<p>I’d like to finish with an open problem:</p>
|
||||
<p>Is it possible for the cubing and bisection to be implemented with
|
||||
just two parts instead of three? That would simplify the formulas a lot.
|
||||
For example, one could split the 67-value into two 34-bit parts, but
|
||||
whenever one multiplies two of them, one needs to right-shift one of
|
||||
them by at least 4 bits, or both by 2. Or, one splits the 67 bits
|
||||
just two parts instead of three? That would simplify the formulas a
|
||||
lot. For example, one could split the 67-value into two 34-bit parts,
|
||||
but whenever one multiplies two of them, one needs to right-shift one
|
||||
of them by at least 4 bits, or both by 2. Or, one splits the 67 bits
|
||||
asymmetrically? I was unable to make it work with 2 parts, but that
|
||||
doesn’t have to mean anything.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1
|
||||
id="inventory-for-2019diels-grabsch2"><a name="inventory"></a>Inventory
|
||||
for 2019/diels-grabsch2</h1>
|
||||
<h1 id="inventory-for-2019diels-grabsch2"><a name="inventory"></a>Inventory for 2019/diels-grabsch2</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="2019_diels-grabsch2.tar.bz2">2019_diels-grabsch2.tar.bz2</a> -
|
||||
download entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="2019_diels-grabsch2.tar.bz2">2019_diels-grabsch2.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/diels-grabsch2/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+172
-253
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Gil_Dogon">Gil Dogon</a><br>
|
||||
Location: <a href="../../location.html#IL">IL</a> - <em>State of
|
||||
Israel</em> (<em>Israel</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#IL">IL</a> - <em>State of Israel</em> (<em>Israel</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -144,311 +144,230 @@ Israel</em> (<em>Israel</em>) <br><br></li>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: uses gets() - change to fgets() if possible</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_dogon">2019 dogon bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_dogon">2019 dogon bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> pattern.mc</span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<p>Make sure that you keep focus of windows in mind when going back and
|
||||
forth to the program and the script.</p>
|
||||
<p>Make sure that you keep focus of windows in mind when going back and forth to
|
||||
the program and the script.</p>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p><a href="../../years.html#1991_davidguy">1991/davidguy</a>, <a
|
||||
href="../../years.html#2011_blakely">2011/blakely</a>, …</p>
|
||||
<p>…This entry likely concludes the IOCCC category “Cellular automata
|
||||
simulators”; it would be very hard to beat it on its field.</p>
|
||||
<p>FYI: The <code>.mc</code> extension stands for
|
||||
<code>Golly macrocell</code> format.</p>
|
||||
<p><a href="../../years.html#1991_davidguy">1991/davidguy</a>,
|
||||
<a href="../../years.html#2011_blakely">2011/blakely</a>, …</p>
|
||||
<p>…This entry likely concludes the IOCCC category “Cellular automata simulators”;
|
||||
it would be very hard to beat it on its field.</p>
|
||||
<p>FYI: The <code>.mc</code> extension stands for <code>Golly macrocell</code> format.</p>
|
||||
<p>We truly have not much more to add, except two things:</p>
|
||||
<ul>
|
||||
<li><p>If a large sparse pattern is given, at the start of the program
|
||||
you are much more likely to see a blank board rather than the loaded
|
||||
configuration, and to see it, you may need to zoom out a few
|
||||
times.</p></li>
|
||||
<li><p>If you’re using a virtual machine with less than 4 Gb of
|
||||
available model RAM, you’d want to reduce the value of the Z define in
|
||||
the Makefile to <code>0x10000000</code>, otherwise the entry will
|
||||
promptly crash. To do this you can do:</p>
|
||||
you are much more likely to see a blank board rather than the loaded configuration,
|
||||
and to see it, you may need to zoom out a few times.</p></li>
|
||||
<li><p>If you’re using a virtual machine with less than 4 Gb of available
|
||||
model RAM, you’d want to reduce the value of the Z define in the Makefile
|
||||
to <code>0x10000000</code>, otherwise the entry will promptly crash. To do this you can do:</p>
|
||||
<p>make clobber MEMORY=0x10000000 all</p>
|
||||
<p>Notice that that value must be a power of two!</p></li>
|
||||
</ul>
|
||||
<p>In the interest of saving lives, this entry was not fuzzed.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="what-is-it">What is it?</h3>
|
||||
<p>Just run with no arguments on an X11-compatible system using one of
|
||||
the supplied input <code>.mc</code> files as standard input. Press
|
||||
<code>-</code> several time to zoom out if necessary, then press space.
|
||||
For acceleration press <code>]</code> several times. That’s rather quick
|
||||
don’t you think?</p>
|
||||
<p>Just run with no arguments on an X11-compatible system using one of the supplied
|
||||
input <code>.mc</code> files as standard input. Press <code>-</code> several time to zoom out if
|
||||
necessary, then press space. For acceleration press <code>]</code> several times. That’s
|
||||
rather quick don’t you think?</p>
|
||||
<h3 id="historical-timeline">Historical Timeline</h3>
|
||||
<ul>
|
||||
<li>Circa 3.77 - 4.28 Billion years ago: Microorganisms appear on
|
||||
Earth.</li>
|
||||
<li>3000 BC: Ankh symbol is used in Egyptian hieroglyph to represent
|
||||
life.</li>
|
||||
<li>1940s: John Von Neumann and Stanislav Ulam are interested in
|
||||
artificial life eventually kick starting research on Cellular
|
||||
Automata.</li>
|
||||
<li>1970: J.H. Conway’s research discovers a rather minimal set of rules
|
||||
that seems quite interesting. <a
|
||||
href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway’s
|
||||
Game of Life</a> gets published in <a
|
||||
href="https://web.stanford.edu/class/sts145/Library/life.pdf">Martin
|
||||
Gardner’s Scientific American column</a>.</li>
|
||||
<li>1970s: According to Knuth, a significant portion of computer time in
|
||||
the world is spent simulating GOL, mostly without the awareness of the
|
||||
people footing the bill.</li>
|
||||
<li>1984: Bill Gosper invents the <a
|
||||
href="https://en.wikipedia.org/wiki/Hashlife">Hashlife</a> algorithm.
|
||||
His implementation runs on Symbolics Lisp Machines. Unrelated to that,
|
||||
but in a cosmic coincidence the <a href="../../years.html#1984">first
|
||||
IOCCC</a> is run!</li>
|
||||
<li>December 2000: Tom Rokicki has a breakthrough implementing <a
|
||||
href="https://en.wikipedia.org/wiki/Hashlife">Hashlife</a> in C,
|
||||
efficient, stable and production ready for modern machines.</li>
|
||||
<li>2006: First version of Golly by Andrew Trevorrow and Tomas Rokicki.
|
||||
Brings the delights of <a
|
||||
href="https://en.wikipedia.org/wiki/Hashlife">hashlife</a> to the
|
||||
masses.</li>
|
||||
<li>Circa 3.77 - 4.28 Billion years ago: Microorganisms appear on Earth.</li>
|
||||
<li>3000 BC: Ankh symbol is used in Egyptian hieroglyph to represent life.</li>
|
||||
<li>1940s: John Von Neumann and Stanislav Ulam are interested in artificial life
|
||||
eventually kick starting research on Cellular Automata.</li>
|
||||
<li>1970: J.H. Conway’s research discovers a rather minimal set of rules that
|
||||
seems quite interesting. <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway’s Game of
|
||||
Life</a> gets published in
|
||||
<a href="https://web.stanford.edu/class/sts145/Library/life.pdf">Martin Gardner’s Scientific American
|
||||
column</a>.</li>
|
||||
<li>1970s: According to Knuth, a significant portion of computer time in the
|
||||
world is spent simulating GOL, mostly without the awareness of the people
|
||||
footing the bill.</li>
|
||||
<li>1984: Bill Gosper invents the
|
||||
<a href="https://en.wikipedia.org/wiki/Hashlife">Hashlife</a> algorithm. His
|
||||
implementation runs on Symbolics Lisp Machines. Unrelated to that, but in a
|
||||
cosmic coincidence the <a href="../../years.html#1984">first IOCCC</a> is run!</li>
|
||||
<li>December 2000: Tom Rokicki has a breakthrough implementing
|
||||
<a href="https://en.wikipedia.org/wiki/Hashlife">Hashlife</a> in C, efficient, stable and
|
||||
production ready for modern machines.</li>
|
||||
<li>2006: First version of Golly by Andrew Trevorrow and Tomas Rokicki. Brings
|
||||
the delights of <a href="https://en.wikipedia.org/wiki/Hashlife">hashlife</a> to the masses.</li>
|
||||
</ul>
|
||||
<p>Which brings us to the present moment in time.</p>
|
||||
<h3 id="full-documentation-and-keys-ui">Full documentation and keys
|
||||
UI</h3>
|
||||
<p>Yes, this program is a Conway’s Game of Life graphic simulator
|
||||
implementing Bill Gosper’s hashlife algorithm. The entry’s UI is rather
|
||||
terse and somewhat obfuscated, as it should be. Also, when you,
|
||||
accidentally or not, press any of the keys not specified below, some
|
||||
stuff will happen or not, there is no guarantee whatsoever.</p>
|
||||
<h3 id="full-documentation-and-keys-ui">Full documentation and keys UI</h3>
|
||||
<p>Yes, this program is a Conway’s Game of Life graphic simulator implementing Bill
|
||||
Gosper’s hashlife algorithm. The entry’s UI is rather terse and somewhat
|
||||
obfuscated, as it should be. Also, when you, accidentally or not, press any of
|
||||
the keys not specified below, some stuff will happen or not, there is no
|
||||
guarantee whatsoever.</p>
|
||||
<p>The program should be used as follows:</p>
|
||||
<p>The standard input should contain a Golly macrocell format file for a
|
||||
two state automaton. See: <a
|
||||
href="http://golly.sourceforge.net/Help/formats.html"
|
||||
class="uri">http://golly.sourceforge.net/Help/formats.html</a>. Of
|
||||
course only Conway’s GOL rules are supported, so rules in the files are
|
||||
ignored. The supplied input examples should be quite interesting. Except
|
||||
one, all are taken from Golly’s standard distribution. Information and
|
||||
credits to their designer are in the header comment of each.</p>
|
||||
<p>The standard input should contain a Golly macrocell format file for a two state
|
||||
automaton. See: <a href="http://golly.sourceforge.net/Help/formats.html" class="uri">http://golly.sourceforge.net/Help/formats.html</a>. Of course only
|
||||
Conway’s GOL rules are supported, so rules in the files are ignored. The supplied
|
||||
input examples should be quite interesting. Except one, all are taken from
|
||||
Golly’s standard distribution. Information and credits to their designer are in
|
||||
the header comment of each.</p>
|
||||
<ul>
|
||||
<li>For image navigation use the arrow keys, and zoom in and out by the
|
||||
<code>+</code>/<code>-</code> keys (without pressing the shift on the
|
||||
<code>+</code>)</li>
|
||||
<li>For image navigation use the arrow keys, and zoom in and out by the <code>+</code>/<code>-</code> keys
|
||||
(without pressing the shift on the <code>+</code>)</li>
|
||||
<li>Space : Toggle start/stop.</li>
|
||||
<li>0 (zero): Toggle single step/free run mode.</li>
|
||||
<li>Backspace: Toggle direction for the arrow of time.</li>
|
||||
<li><code>]</code>: Increase speed (time step) by a factor of 2.</li>
|
||||
<li><code>[</code>: Decrease speed (time step) by a factor of 2.</li>
|
||||
</ul>
|
||||
<p>Notice that when going backward in time we ignore the current time
|
||||
step setting and just jump by the amount that was specified before.
|
||||
However going forward is always using the current time step.</p>
|
||||
<p>There is a minimal text printout by the program, so you can know what
|
||||
Generation your are in (<code>G:</code>), Internal memory allocated till
|
||||
now (<code>M:</code>), and then which Level is the current macrocell
|
||||
(<code>L</code>) and which zoom Scale you are watching
|
||||
(<code>S</code>).</p>
|
||||
<p>Notice that when going backward in time we ignore the current time step setting
|
||||
and just jump by the amount that was specified before. However going forward is
|
||||
always using the current time step.</p>
|
||||
<p>There is a minimal text printout by the program, so you can know what Generation
|
||||
your are in (<code>G:</code>), Internal memory allocated till now (<code>M:</code>), and then which Level
|
||||
is the current macrocell (<code>L</code>) and which zoom Scale you are watching (<code>S</code>).</p>
|
||||
<h3 id="portability-issues">Portability issues</h3>
|
||||
<p>This entry is quite portable hopefully on most modern platforms. It
|
||||
assumes X Window support of course. More than 2GB of memory is
|
||||
recommended. Configuration through <a href="Makefile">Makefile</a> is
|
||||
provided for the display windows size and for the memory usage. The
|
||||
Makefile provided configuration (<code>Z=0x20000000</code>) will need a
|
||||
system with 4GB DRAM to run nicely. There are several other salient
|
||||
assumptions though:</p>
|
||||
<p>This entry is quite portable hopefully on most modern platforms. It assumes X
|
||||
Window support of course. More than 2GB of memory is recommended. Configuration
|
||||
through <a href="Makefile">Makefile</a> is provided for the display windows size and for
|
||||
the memory usage. The Makefile provided configuration (<code>Z=0x20000000</code>) will need a
|
||||
system with 4GB DRAM to run nicely. There are several other salient assumptions
|
||||
though:</p>
|
||||
<ul>
|
||||
<li>The entry assumes <code>sizeof(long)==8</code>. However it actually
|
||||
almost avoids using any pointers which are 64 bits these days, in order
|
||||
to save space. On machines with <code>sizeof(long)==4</code> try adding
|
||||
<code>#define long long long</code> …</li>
|
||||
<li>The entry assumes the X11 displays default visual has 24 bit depth
|
||||
(RGB).</li>
|
||||
<li>The entry assumes little endianness (in only one place though! If
|
||||
you have PowerPC you can try and find that place to make it work), but
|
||||
more than this it assumes unaligned loads of 64 bits <code>long</code>s
|
||||
are supported, i.e. it assumes that a <code>long</code> can be loaded
|
||||
from any address that could hold an <code>int</code> otherwise. On non
|
||||
<li>The entry assumes <code>sizeof(long)==8</code>. However it actually almost avoids using any
|
||||
pointers which are 64 bits these days, in order to save space. On machines with
|
||||
<code>sizeof(long)==4</code> try adding <code>#define long long long</code> …</li>
|
||||
<li>The entry assumes the X11 displays default visual has 24 bit depth (RGB).</li>
|
||||
<li>The entry assumes little endianness (in only one place though! If you have
|
||||
PowerPC you can try and find that place to make it work), but more than this it
|
||||
assumes unaligned loads of 64 bits <code>long</code>s are supported, i.e. it assumes that a
|
||||
<code>long</code> can be loaded from any address that could hold an <code>int</code> otherwise. On non
|
||||
antiquated X86 you’ll be fine.</li>
|
||||
<li>The entry heavily relies on bitwise arithmetic (you don’t
|
||||
say!).</li>
|
||||
<li>The entry heavily relies on bitwise arithmetic (you don’t say!).</li>
|
||||
</ul>
|
||||
<h3 id="limitations">Limitations:</h3>
|
||||
<p>Foremost the entry is very strict, unsafe and picky regarding its
|
||||
input. Anything straying from the standard Golly macrocell legal format
|
||||
will result in undefined behavior, meaning mostly a very defined core
|
||||
dump. Since aforementioned core is rather large by default (about 4GG)
|
||||
it is highly recommended to set the core dump size limit to 0 in the
|
||||
shell before playing with fire …</p>
|
||||
<p>This entry needs quite a lot of memory to be effective, but by modern
|
||||
standards that is not too much. It does not do any garbage collection,
|
||||
so sooner or later memory will run out, resulting, surprise, surprise,
|
||||
in a core dump. On the plus side, this enables the nice time reversal
|
||||
feature… Anyway the amount of memory used can be controlled by the
|
||||
Makefile <code>-DZ=...</code> argument. With the default <code>Z</code>,
|
||||
the program will support in total about 240 million 64bit
|
||||
<code>long</code>s for the internal memory, which should be sufficient
|
||||
for about 100 million nodes+leafs, as each node is 3 <code>long</code>s
|
||||
and each leaf is 2.</p>
|
||||
<p><em>Important:</em> Makefile <code>Z</code> define must be a power of
|
||||
two!</p>
|
||||
<p>Zooming out past about S58 scale will enter a buggy twilight zone as
|
||||
only <code>long</code> integers are used in the drawing code. Reverting
|
||||
to <code>double</code>s could have remedied that, but then I’d need to
|
||||
use a lot of <code>ldexp()</code>s which would take the program over the
|
||||
size limit. Also the program will crash once the universe goes past
|
||||
level 64, though this is simply fixed by modifying a single constant in
|
||||
the program, can you find it ? Anyway <code>2^58</code> squared is quite
|
||||
a big enough universe for such a tiny program to simulate, no ?</p>
|
||||
<p>In case cell memory did not run out, or your pattern did not grow too
|
||||
big, and you have had patience enough and did not increase speed too
|
||||
much, you can run out of the history buffer after <code>33333</code>
|
||||
steps.</p>
|
||||
<p>If all of the above did not happen and result in the expected core
|
||||
dump, you will encounter the final limitation, which is the absence of
|
||||
an escape key. Just close the window or use <code>^C</code>/intr to exit
|
||||
….</p>
|
||||
<p>Foremost the entry is very strict, unsafe and picky regarding its input.
|
||||
Anything straying from the standard Golly macrocell legal format will result in
|
||||
undefined behavior, meaning mostly a very defined core dump. Since
|
||||
aforementioned core is rather large by default (about 4GG) it is highly
|
||||
recommended to set the core dump size limit to 0 in the shell before playing
|
||||
with fire …</p>
|
||||
<p>This entry needs quite a lot of memory to be effective, but by modern standards
|
||||
that is not too much. It does not do any garbage collection, so sooner or later
|
||||
memory will run out, resulting, surprise, surprise, in a core dump. On the plus
|
||||
side, this enables the nice time reversal feature… Anyway the amount of memory
|
||||
used can be controlled by the Makefile <code>-DZ=...</code> argument. With the default <code>Z</code>,
|
||||
the program will support in total about 240 million 64bit <code>long</code>s for the internal
|
||||
memory, which should be sufficient for about 100 million nodes+leafs, as each
|
||||
node is 3 <code>long</code>s and each leaf is 2.</p>
|
||||
<p><em>Important:</em> Makefile <code>Z</code> define must be a power of two!</p>
|
||||
<p>Zooming out past about S58 scale will enter a buggy twilight zone as only <code>long</code>
|
||||
integers are used in the drawing code. Reverting to <code>double</code>s could have remedied
|
||||
that, but then I’d need to use a lot of <code>ldexp()</code>s which would take the program
|
||||
over the size limit. Also the program will crash once the universe goes past
|
||||
level 64, though this is simply fixed by modifying a single constant in the
|
||||
program, can you find it ? Anyway <code>2^58</code> squared is quite a big enough universe
|
||||
for such a tiny program to simulate, no ?</p>
|
||||
<p>In case cell memory did not run out, or your pattern did not grow too big, and
|
||||
you have had patience enough and did not increase speed too much, you can run
|
||||
out of the history buffer after <code>33333</code> steps.</p>
|
||||
<p>If all of the above did not happen and result in the expected core dump, you
|
||||
will encounter the final limitation, which is the absence of an escape key. Just
|
||||
close the window or use <code>^C</code>/intr to exit ….</p>
|
||||
<h3 id="warnings">Warnings</h3>
|
||||
<p>Oh don’t get me started on the torrent of litanies gcc emits when
|
||||
used with <code>-Wall</code>! Does it think I have not memorized by
|
||||
heart C’s precious operator precedence table (or at least have a cheat
|
||||
sheet nearby) that it dares suggest extra parentheses that would take
|
||||
the program over the limit ? And what if I do not use a variable here or
|
||||
there, do I have to pay extra tax for every orphaned variable?</p>
|
||||
<p>There is the reasonable warning about some <code>long</code>s printed
|
||||
as <code>int</code>s but its OK too, trust me.</p>
|
||||
<p>Then there’s the warning about <code>gets(3)</code> being unsafe,
|
||||
which is indeed the only one that appears by default in some versions of
|
||||
gcc linker. Yes Virginia, I know it is unsafe, and I would not recommend
|
||||
anyone using this entry as part of a web daemon, or a spaceship, no,
|
||||
seriously don’ do that.</p>
|
||||
<p>Oh don’t get me started on the torrent of litanies gcc emits when used with
|
||||
<code>-Wall</code>! Does it think I have not memorized by heart C’s precious operator
|
||||
precedence table (or at least have a cheat sheet nearby) that it dares suggest
|
||||
extra parentheses that would take the program over the limit ? And what if I do
|
||||
not use a variable here or there, do I have to pay extra tax for every orphaned
|
||||
variable?</p>
|
||||
<p>There is the reasonable warning about some <code>long</code>s printed as <code>int</code>s but its OK too,
|
||||
trust me.</p>
|
||||
<p>Then there’s the warning about <code>gets(3)</code> being unsafe, which is indeed the only one
|
||||
that appears by default in some versions of gcc linker. Yes Virginia, I know it
|
||||
is unsafe, and I would not recommend anyone using this entry as part of a web
|
||||
daemon, or a spaceship, no, seriously don’ do that.</p>
|
||||
<h3 id="obfuscations">Obfuscations:</h3>
|
||||
<p>Well almost none of the obfuscations are done on purpose, but mostly
|
||||
out of necessity, so all identifiers possible to be one character, are,
|
||||
and they are mercilessly reused. In the <code>main()</code> function
|
||||
there’s even a nice little identifier first used as a global and then
|
||||
reused (shadowed) in the <em>same</em> scope, and this did not produce
|
||||
even a little squeak of a warning from the compiler! Macro compression
|
||||
is rather sparingly used, however magic numbers abound everywhere, and
|
||||
bit twiddling is magical too. Do you know for example why we have
|
||||
<code>unsigned F=-1</code> ? (No warning there of course :) Hint: Later
|
||||
in the program you have <code>F/=17</code>. Did that make any sense?
|
||||
Further hint: print the resulting <code>F</code> in hexadecimal…</p>
|
||||
<p>And yes, the layout hint involves a mix of the most trendy
|
||||
typographical character juxtaposed against a very ancient one, not to
|
||||
mention the program includes some famous name dropping and documents
|
||||
itself as usual.</p>
|
||||
<h3 id="further-spoilers-engineering-and-obfuscation-galore">Further
|
||||
spoilers, engineering, and obfuscation galore:</h3>
|
||||
<p>Those wait for you, curious and intrepid reader, in the attached <a
|
||||
href="apholife.c">apholife.c</a> file, which is a partially obfuscated
|
||||
version of the program I wrote with a lot of helpful annotations and
|
||||
comments for myself and posterity, revealing some of the magic under the
|
||||
hood. This program is also a somewhat improved version which uses
|
||||
<code>ldexp()</code>s in the draw routine and has bigger constants, so
|
||||
it can zoom up to level 1024 if memory allows, and it tries its best to
|
||||
avoid dumping core on the poor user when its memory runs out, rather it
|
||||
enters freeze mode where you can still travel in calculated frozen
|
||||
space-time. Well, it’s not nice and tame, it even has an escape key,
|
||||
usage message, and to top it all it even avoids
|
||||
<code>gets(3)</code>!</p>
|
||||
<p>Well almost none of the obfuscations are done on purpose, but mostly out of
|
||||
necessity, so all identifiers possible to be one character, are, and they are
|
||||
mercilessly reused. In the <code>main()</code> function there’s even a nice little
|
||||
identifier first used as a global and then reused (shadowed) in the <em>same</em>
|
||||
scope, and this did not produce even a little squeak of a warning from the
|
||||
compiler! Macro compression is rather sparingly used, however magic numbers
|
||||
abound everywhere, and bit twiddling is magical too. Do you know for example why
|
||||
we have <code>unsigned F=-1</code> ? (No warning there of course :) Hint: Later in the
|
||||
program you have <code>F/=17</code>. Did that make any sense? Further hint: print the
|
||||
resulting <code>F</code> in hexadecimal…</p>
|
||||
<p>And yes, the layout hint involves a mix of the most trendy typographical
|
||||
character juxtaposed against a very ancient one, not to mention the program
|
||||
includes some famous name dropping and documents itself as usual.</p>
|
||||
<h3 id="further-spoilers-engineering-and-obfuscation-galore">Further spoilers, engineering, and obfuscation galore:</h3>
|
||||
<p>Those wait for you, curious and intrepid reader, in the attached
|
||||
<a href="apholife.c">apholife.c</a> file, which is a partially obfuscated version of the
|
||||
program I wrote with a lot of helpful annotations and comments for myself and
|
||||
posterity, revealing some of the magic under the hood. This program is also a
|
||||
somewhat improved version which uses <code>ldexp()</code>s in the draw routine and has
|
||||
bigger constants, so it can zoom up to level 1024 if memory allows, and it tries
|
||||
its best to avoid dumping core on the poor user when its memory runs out, rather
|
||||
it enters freeze mode where you can still travel in calculated frozen
|
||||
space-time. Well, it’s not nice and tame, it even has an escape key, usage
|
||||
message, and to top it all it even avoids <code>gets(3)</code>!</p>
|
||||
<h3 id="special-thanks">Special thanks:</h3>
|
||||
<p>To Tom Rockiki, the original co-writer of Golly, a personal friend
|
||||
and hashlife master, who reviewed some earlier versions of the entry and
|
||||
freely shared some of his vast knowledge regarding GOL programming and
|
||||
hashlife. As a free bonus, Tom has allowed me to show his code which is
|
||||
probably the most efficient yet most obfuscated way of calculating the
|
||||
GOL function on a 64 bits <code>8*8</code> leaf:</p>
|
||||
<p>To Tom Rockiki, the original co-writer of Golly, a personal friend and hashlife
|
||||
master, who reviewed some earlier versions of the entry and freely shared some
|
||||
of his vast knowledge regarding GOL programming and hashlife. As a free bonus,
|
||||
Tom has allowed me to show his code which is probably the most efficient yet
|
||||
most obfuscated way of calculating the GOL function on a 64 bits <code>8*8</code> leaf:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="dt">unsigned</span> <span class="dt">long</span> life8x8<span class="op">(</span><span class="dt">long</span> a<span class="op">)</span> <span class="op">{</span> <span class="dt">unsigned</span> <span class="dt">long</span> aw <span class="op">=</span> a <span class="op"><<</span> <span class="dv">1</span><span class="op">,</span> ae <span class="op">=</span> a <span class="op">>></span> <span class="dv">1</span><span class="op">,</span> s0 <span class="op">=</span> aw</span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="op">^</span> ae<span class="op">,</span> s1 <span class="op">=</span> aw <span class="op">&</span> ae<span class="op">,</span> hs0 <span class="op">=</span> s0 <span class="op">^</span> a<span class="op">,</span> hs1 <span class="op">=</span> <span class="op">(</span>s0 <span class="op">&</span> a<span class="op">)</span> <span class="op">|</span> s1<span class="op">,</span> hs0w8 <span class="op">=</span> hs0 <span class="op">>></span> <span class="dv">8</span><span class="op">,</span> hs0e8 <span class="op">=</span></span>
|
||||
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>hs0 <span class="op"><<</span> <span class="dv">8</span><span class="op">,</span> hs1w8 <span class="op">=</span> hs1 <span class="op">>></span> <span class="dv">8</span><span class="op">,</span> hs1e8 <span class="op">=</span> hs1 <span class="op"><<</span> <span class="dv">8</span><span class="op">,</span> ts0 <span class="op">=</span> hs0w8 <span class="op">^</span> hs0e8<span class="op">,</span> ts1 <span class="op">=</span> <span class="op">(</span>hs0w8</span>
|
||||
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="op">&</span> hs0e8<span class="op">)</span> <span class="op">|</span> <span class="op">(</span>ts0 <span class="op">&</span> s0<span class="op">);</span> <span class="cf">return</span> <span class="op">(</span>hs1w8 <span class="op">^</span> hs1e8 <span class="op">^</span> ts1 <span class="op">^</span> s1<span class="op">)</span> <span class="op">&</span> <span class="op">((</span>hs1w8 <span class="op">|</span> hs1e8<span class="op">)</span> <span class="op">^</span></span>
|
||||
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="op">(</span>ts1 <span class="op">|</span> s1<span class="op">))</span> <span class="op">&</span> <span class="op">((</span>ts0 <span class="op">^</span> s0<span class="op">)</span> <span class="op">|</span> a<span class="op">);</span> <span class="op">}</span></span></code></pre></div>
|
||||
<p>This uses only 19 bitwise operations and six shifts to calculate the
|
||||
inner 6x6 next generation bits of the input 8x8 !</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<p>This uses only 19 bitwise operations and six shifts to calculate the inner 6x6
|
||||
next generation bits of the input 8x8 !</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019dogon"><a name="inventory"></a>Inventory for
|
||||
2019/dogon</h1>
|
||||
<h1 id="inventory-for-2019dogon"><a name="inventory"></a>Inventory for 2019/dogon</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/glider.mc">glider.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/gotts-dots.mc">gotts-dots.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite.mc">infinite.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite_10cell.mc">infinite_10cell.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite_5x5.mc">infinite_5x5.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite_minimal.mc">infinite_minimal.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/jagged.mc">jagged.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/message.mc">message.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/metacatacryst.mc">metacatacryst.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/metapixel-parity64.mc">metapixel-parity64.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/mosquito5.mc">mosquito5.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/unlimited-novelty.mc">unlimited-novelty.mc</a>
|
||||
- Golly macrocell input file</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/apholife.c">apholife.c</a>
|
||||
- partially obfuscated source</li>
|
||||
<li><a href="2019_dogon.tar.bz2">2019_dogon.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/glider.mc">glider.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/gotts-dots.mc">gotts-dots.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite.mc">infinite.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite_10cell.mc">infinite_10cell.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite_5x5.mc">infinite_5x5.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/infinite_minimal.mc">infinite_minimal.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/jagged.mc">jagged.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/message.mc">message.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/metacatacryst.mc">metacatacryst.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/metapixel-parity64.mc">metapixel-parity64.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/mosquito5.mc">mosquito5.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/unlimited-novelty.mc">unlimited-novelty.mc</a> - Golly macrocell input file</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/apholife.c">apholife.c</a> - partially obfuscated source</li>
|
||||
<li><a href="2019_dogon.tar.bz2">2019_dogon.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/dogon/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+105
-162
@@ -129,9 +129,9 @@
|
||||
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Etienne_Duble">Etienne
|
||||
Duble</a><br> Location: <a href="../../location.html#FR">FR</a> -
|
||||
<em>French Republic</em> (<em>France</em>) <br><br></li>
|
||||
<li>Name: <a href="../../authors.html#Etienne_Duble">Etienne Duble</a><br>
|
||||
Location: <a href="../../location.html#FR">FR</a> - <em>French Republic</em> (<em>France</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -141,14 +141,12 @@ Duble</a><br> Location: <a href="../../location.html#FR">FR</a> -
|
||||
|
||||
<h2 id="to-build">To build:</h2>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>There is an alternate version, the original, which does not work well
|
||||
in macOS. See <a href="#alternate-code">Alternate code</a> below if you
|
||||
are curious.</p>
|
||||
<p>There is an alternate version, the original, which does not work well in macOS.
|
||||
See <a href="#alternate-code">Alternate code</a> below if you are curious.</p>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_duble">2019 duble bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_duble">2019 duble bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> file</span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
@@ -164,15 +162,12 @@ href="../../bugs.html#2019_duble">2019 duble bugs</a>.</p>
|
||||
<hr />
|
||||
<ul>
|
||||
<li><strong>Arrow keys</strong>: move cursor.</li>
|
||||
<li><code>p</code> key: enter <em>pen</em> mode (type <strong>p</strong>
|
||||
again to return to the default <em>move</em> mode).</li>
|
||||
<li><code>l</code> key: enter <em>line</em> mode (type
|
||||
<strong>l</strong> again to validate the line and return to the
|
||||
<em>move</em> mode).</li>
|
||||
<li><code>c</code> key: cycle through a small set of different
|
||||
<em>colors</em>.</li>
|
||||
<li><code>q</code> key: quit the editor. The drawing is automatically
|
||||
saved.</li>
|
||||
<li><code>p</code> key: enter <em>pen</em> mode (type <strong>p</strong> again to return to the default <em>move</em>
|
||||
mode).</li>
|
||||
<li><code>l</code> key: enter <em>line</em> mode (type <strong>l</strong> again to validate the line and return
|
||||
to the <em>move</em> mode).</li>
|
||||
<li><code>c</code> key: cycle through a small set of different <em>colors</em>.</li>
|
||||
<li><code>q</code> key: quit the editor. The drawing is automatically saved.</li>
|
||||
</ul>
|
||||
<p>The mode and current color is indicated at the bottom left corner of
|
||||
the editor.</p>
|
||||
@@ -180,202 +175,150 @@ the editor.</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">/tmp/drawing</span></span></code></pre></div>
|
||||
<p>i.e. execute the file.</p>
|
||||
<hr />
|
||||
<p>WARNING: if the file is deleted it might lock any session still in
|
||||
use. These will have to be killed from another shell session or by
|
||||
closing the terminal tab (in other words don’t do this from the
|
||||
console!). If the file cannot be opened in the beginning this will also
|
||||
happen. This is discussed in <a href="../../bugs.html#2019_duble">2019
|
||||
duble bugs</a>.</p>
|
||||
<p>NOTE: this entry might leave sockets lying about in the current
|
||||
working directory which you’ll have to delete manually. This is also
|
||||
discussed in <a href="../../bugs.html#2019_duble">2019 duble
|
||||
bugs</a>.</p>
|
||||
<p>WARNING: if the file is deleted it might lock any session still in use. These
|
||||
will have to be killed from another shell session or by closing the terminal tab
|
||||
(in other words don’t do this from the console!). If the file cannot be opened
|
||||
in the beginning this will also happen. This is discussed in
|
||||
<a href="../../bugs.html#2019_duble">2019 duble bugs</a>.</p>
|
||||
<p>NOTE: this entry might leave sockets lying about in the current working
|
||||
directory which you’ll have to delete manually. This is also discussed in
|
||||
<a href="../../bugs.html#2019_duble">2019 duble bugs</a>.</p>
|
||||
<h2 id="alternate-code">Alternate code:</h2>
|
||||
<p>An alternate version of this entry, <a
|
||||
href="prog.alt.c">prog.alt.c</a>, is provided. This alternate code might
|
||||
not work as well in macOS.</p>
|
||||
<p>An alternate version of this entry, <a href="prog.alt.c">prog.alt.c</a>, is provided. This
|
||||
alternate code might not work as well in macOS.</p>
|
||||
<h3 id="alternate-build">Alternate build:</h3>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> alt</span></code></pre></div>
|
||||
<h3 id="alternate-use">Alternate use:</h3>
|
||||
<p>Use <code>prog.alt</code> as you would <code>prog</code> above.</p>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>After starting the program, use the cursor keys, then try some modes,
|
||||
like <code>p</code> or <code>l</code> (they toggle).</p>
|
||||
<p>After starting the program, use the cursor keys, then try some modes, like <code>p</code>
|
||||
or <code>l</code> (they toggle).</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="introduction">Introduction:</h3>
|
||||
<p>This program is a <strong>graphics editor</strong>, running in the
|
||||
terminal.</p>
|
||||
<p>It provides <strong>collaborative</strong> features: one can join the
|
||||
drawing session of someone else by just opening the same file!</p>
|
||||
<p>This program is a <strong>graphics editor</strong>, running in the terminal.</p>
|
||||
<p>It provides <strong>collaborative</strong> features: one can join the drawing session
|
||||
of someone else by just opening the same file!</p>
|
||||
<h3 id="getting-started">Getting started:</h3>
|
||||
<p>The program can run on Linux, FreeBSD, macOS, and in most terminals.
|
||||
See section <a href="#limits-portability">Limits, Portability</a> for
|
||||
more info.</p>
|
||||
<p>To build, type <code>make</code> (assuming gcc) or
|
||||
<code>make CC=clang</code>.</p>
|
||||
<p>Then you can start the program. It expects a file path as its first
|
||||
argument:</p>
|
||||
<div class="sourceCode" id="cb10"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> /tmp/drawing</span></code></pre></div>
|
||||
<p>(If not started this way, with a file, <code>prog</code> will refuse
|
||||
to start.)</p>
|
||||
See section <a href="#limits-portability">Limits, Portability</a> for more info.</p>
|
||||
<p>To build, type <code>make</code> (assuming gcc) or <code>make CC=clang</code>.</p>
|
||||
<p>Then you can start the program. It expects a file path as its first argument:</p>
|
||||
<div class="sourceCode" id="cb10"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> /tmp/drawing</span></code></pre></div>
|
||||
<p>(If not started this way, with a file, <code>prog</code> will refuse to start.)</p>
|
||||
<p>If the file does not exist, you will start with a blank drawing.</p>
|
||||
<p>If someone else (or another <em>instance of yourself</em>, maybe?) is
|
||||
already editing this file, you will join the session!</p>
|
||||
<p>If someone else (or another <em>instance of yourself</em>, maybe?) is already
|
||||
editing this file, you will join the session!</p>
|
||||
<h3 id="edit-features">Edit features:</h3>
|
||||
<ul>
|
||||
<li><strong>arrow keys</strong>: move cursor.</li>
|
||||
<li><code>p</code> key: enter <em>pen</em> mode (type <strong>p</strong>
|
||||
again to return to the default <em>move</em> mode).</li>
|
||||
<li><code>l</code> key: enter <em>line</em> mode (type
|
||||
<strong>l</strong> again to validate the line and return to the
|
||||
<em>move</em> mode).</li>
|
||||
<li><code>c</code> key: cycle through a small set of different
|
||||
<em>colors</em>.</li>
|
||||
<li><code>q</code> key: quit the editor. The drawing is automatically
|
||||
saved.</li>
|
||||
<li><code>p</code> key: enter <em>pen</em> mode (type <strong>p</strong> again to return to the default <em>move</em> mode).</li>
|
||||
<li><code>l</code> key: enter <em>line</em> mode (type <strong>l</strong> again to validate the line and return to the <em>move</em> mode).</li>
|
||||
<li><code>c</code> key: cycle through a small set of different <em>colors</em>.</li>
|
||||
<li><code>q</code> key: quit the editor. The drawing is automatically saved.</li>
|
||||
</ul>
|
||||
<p>The mode and current color is indicated at the bottom left corner of
|
||||
the editor.</p>
|
||||
<h3 id="bonus-features">Bonus features:</h3>
|
||||
<ul>
|
||||
<li>If you just want to display the content of a drawing file, you do
|
||||
not need to start the editor. Just <strong>execute the drawing
|
||||
file</strong>: <code>./<the-file></code>. (This will fail if
|
||||
someone is still editing the file, though.)</li>
|
||||
<li><code>ls --color <drawing-files...></code> will probably
|
||||
select different colors to indicate whether a drawing file is being
|
||||
edited or not. :-)</li>
|
||||
<li>If you just want to display the content of a drawing file, you do not
|
||||
need to start the editor. Just <strong>execute the drawing file</strong>: <code>./<the-file></code>.
|
||||
(This will fail if someone is still editing the file, though.)</li>
|
||||
<li><code>ls --color <drawing-files...></code> will probably select different colors
|
||||
to indicate whether a drawing file is being edited or not. :-)</li>
|
||||
</ul>
|
||||
<h3 id="obfuscation">Obfuscation:</h3>
|
||||
<p>You will probably have a hard time analyzing this entry, because:</p>
|
||||
<ul>
|
||||
<li>Analyzing a system made of several communicating programs is known
|
||||
to be a complex task. (And if you think that observing a single-user
|
||||
drawing session will be a good starting point, read on.)</li>
|
||||
<li>Code coverage of single vs multi-user sessions is more or less the
|
||||
same. :-)</li>
|
||||
<li>Code coverage when using <em>move</em>, <em>pen</em> or
|
||||
<em>line</em> modes is almost the same. (so, is there a Bresenham
|
||||
algorithm somewhere??)</li>
|
||||
<li>Some OS resource values and <code>stdlib.h</code> call results are
|
||||
inferred.</li>
|
||||
<li>Analyzing a system made of several communicating programs is known to
|
||||
be a complex task. (And if you think that observing a single-user drawing
|
||||
session will be a good starting point, read on.)</li>
|
||||
<li>Code coverage of single vs multi-user sessions is more or less the same. :-)</li>
|
||||
<li>Code coverage when using <em>move</em>, <em>pen</em> or <em>line</em> modes is almost the same.
|
||||
(so, is there a Bresenham algorithm somewhere??)</li>
|
||||
<li>Some OS resource values and <code>stdlib.h</code> call results are inferred.</li>
|
||||
<li>Whenever possible, variable names are reused.</li>
|
||||
<li>You might start analyzing escape code sequences right now, but
|
||||
warming up your brain is actually recommended. Start with a simple
|
||||
question such as: <em>in inverse video mode, will a space char show the
|
||||
foreground color or background color?</em></li>
|
||||
<li>You might start analyzing escape code sequences right now, but warming up
|
||||
your brain is actually recommended. Start with a simple question such as:
|
||||
<em>in inverse video mode, will a space char show the foreground color or
|
||||
background color?</em></li>
|
||||
</ul>
|
||||
<h3 id="a-few-more-things">A few more things:</h3>
|
||||
<p>Did you notice the <code>enum</code> declaration? Could it be just an
|
||||
<code>int</code> or <code>const int</code> variable, instead? (spoiler:
|
||||
<a href="http://c-faq.com/ansi/constasconst.html"
|
||||
class="uri">http://c-faq.com/ansi/constasconst.html</a>)</p>
|
||||
<p>If your keyboard has no arrow keys, you can probably find alternate
|
||||
keys by reading the source code.</p>
|
||||
<p>Did you notice the <code>enum</code> declaration? Could it be just an <code>int</code> or <code>const int</code>
|
||||
variable, instead? (spoiler: <a href="http://c-faq.com/ansi/constasconst.html" class="uri">http://c-faq.com/ansi/constasconst.html</a>)</p>
|
||||
<p>If your keyboard has no arrow keys, you can probably find alternate keys by
|
||||
reading the source code.</p>
|
||||
<h3 id="limits-portability">Limits, Portability:</h3>
|
||||
<p>I tested the program on several Linux systems, on FreeBSD 12, and on
|
||||
macOS (Mojave).</p>
|
||||
<p>On Linux, the program uses an OS-specific detail to hide
|
||||
communication artefacts, and avoids the need to remove them on exit.
|
||||
<p>On Linux, the program uses an OS-specific detail to hide communication
|
||||
artefacts, and avoids the need to remove them on exit.
|
||||
Since this is Linux-specific, it was not possible on FreeBSD or macOS.
|
||||
Its behavior is a little more <em>dirty</em> there.</p>
|
||||
<p>The program should work on most terminals that support 8-bit colors,
|
||||
inverse video mode, and movement escape codes, e.g. <code>xterm</code>,
|
||||
<code>gnome-terminal</code>, <code>terminator</code>, etc.</p>
|
||||
<p>Note: the drawing files <code>prog</code> generates are probably even
|
||||
more portable than <code>prog</code> itself!</p>
|
||||
inverse video mode, and movement escape codes, e.g. <code>xterm</code>, <code>gnome-terminal</code>,
|
||||
<code>terminator</code>, etc.</p>
|
||||
<p>Note: the drawing files <code>prog</code> generates are probably even more portable than
|
||||
<code>prog</code> itself!</p>
|
||||
<h3 id="drawing-area-size">Drawing area size:</h3>
|
||||
<h4 id="the-drawing-area-size-is-set-at-compilation-time">The drawing
|
||||
area size is set at compilation time:</h4>
|
||||
<p>The default size is the one of my xterm (see top of Makefile). You
|
||||
may set it to the full size of your terminal window by typing:</p>
|
||||
<div class="sourceCode" id="cb11"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> clobber fullscreen</span></code></pre></div>
|
||||
<h4 id="the-drawing-area-size-is-set-at-compilation-time">The drawing area size is set at compilation time:</h4>
|
||||
<p>The default size is the one of my xterm (see top of Makefile).
|
||||
You may set it to the full size of your terminal window by typing:</p>
|
||||
<div class="sourceCode" id="cb11"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> clobber fullscreen</span></code></pre></div>
|
||||
<p>IMPORTANT NOTES:</p>
|
||||
<ul>
|
||||
<li><strong>The program compiled with a given size will fail to reload a
|
||||
drawing file with a different size!</strong></li>
|
||||
<li>No scrolling is implemented (sorry but that would be too much for
|
||||
rule2!), so any peer reaching the session should have a terminal with
|
||||
the same size or larger.</li>
|
||||
<li><strong>The program compiled with a given size will fail to reload a drawing file
|
||||
with a different size!</strong></li>
|
||||
<li>No scrolling is implemented (sorry but that would be too much for rule2!),
|
||||
so any peer reaching the session should have a terminal with the same
|
||||
size or larger.</li>
|
||||
</ul>
|
||||
<h3 id="prog.c-vs-prog.alt.c"><a href="prog.c">prog.c</a> vs <a
|
||||
href="prog.alt.c">prog.alt.c</a></h3>
|
||||
<p>The file <a href="prog.alt.c">prog.alt.c</a> is the one I
|
||||
submitted.</p>
|
||||
<p>The judges proposed a small update: the program was using macro
|
||||
<code>FD_SET</code> inside an expression, which breaks compilation on
|
||||
macOS. Wrapping this macro into a function was enough to fix this
|
||||
compilation issue.</p>
|
||||
<p>However, that was not enough to make the program work on macOS. If
|
||||
you analyse the program you will see that it heavily relies on OS
|
||||
resources. And, for this first version of the program, you even needed
|
||||
to increase default <code>sysctl</code> parameters to make it work on
|
||||
FreeBSD (this was the purpose of file <a
|
||||
href="check-os.sh">check-os.sh</a>). I tried hard to tune macOS the
|
||||
same, but failed.</p>
|
||||
<p>The simple fact the Judges proposed this update meant they wish it
|
||||
could work on Mac. And if the judges wish something, it <strong>has
|
||||
to</strong> be done. ;) So I refactored a little more the program to
|
||||
reduce OS resources consumption. Or maybe not reduce consumption, but
|
||||
consume them differently… And I obtained <a href="prog.c">prog.c</a>.
|
||||
With this version, no need to touch <code>sysctl</code> parameters, and
|
||||
it works on macOS too! I must confess it was challenging to remain below
|
||||
the size limit with this little change.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<h3 id="prog.c-vs-prog.alt.c"><a href="prog.c">prog.c</a> vs <a href="prog.alt.c">prog.alt.c</a></h3>
|
||||
<p>The file <a href="prog.alt.c">prog.alt.c</a> is the one I submitted.</p>
|
||||
<p>The judges proposed a small update: the program was using macro <code>FD_SET</code> inside an
|
||||
expression, which breaks compilation on macOS. Wrapping this macro into a
|
||||
function was enough to fix this compilation issue.</p>
|
||||
<p>However, that was not enough to make the program work on macOS. If you analyse
|
||||
the program you will see that it heavily relies on OS resources. And, for this
|
||||
first version of the program, you even needed to increase default <code>sysctl</code>
|
||||
parameters to make it work on FreeBSD (this was the purpose of file
|
||||
<a href="check-os.sh">check-os.sh</a>). I tried hard to tune macOS the same, but failed.</p>
|
||||
<p>The simple fact the Judges proposed this update meant they wish it could work on
|
||||
Mac. And if the judges wish something, it <strong>has to</strong> be done. ;) So I
|
||||
refactored a little more the program to reduce OS resources consumption. Or
|
||||
maybe not reduce consumption, but consume them differently… And I obtained
|
||||
<a href="prog.c">prog.c</a>. With this version, no need to touch <code>sysctl</code> parameters, and
|
||||
it works on macOS too! I must confess it was challenging to remain below the
|
||||
size limit with this little change.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019duble"><a name="inventory"></a>Inventory for
|
||||
2019/duble</h1>
|
||||
<h1 id="inventory-for-2019duble"><a name="inventory"></a>Inventory for 2019/duble</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/prog.alt.c">prog.alt.c</a>
|
||||
- alternative source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/check-os.sh">check-os.sh</a>
|
||||
- check the operating system for compatibility</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/fullscreen.sh">fullscreen.sh</a>
|
||||
- determine full screen size for make fullscreen</li>
|
||||
<li><a href="2019_duble.tar.bz2">2019_duble.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/prog.alt.c">prog.alt.c</a> - alternative source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/check-os.sh">check-os.sh</a> - check the operating system for compatibility</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/fullscreen.sh">fullscreen.sh</a> - determine full screen size for make fullscreen</li>
|
||||
<li><a href="2019_duble.tar.bz2">2019_duble.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/duble/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+23
-51
@@ -141,31 +141,25 @@ Location: <a href="../../location.html#JP">JP</a> - <em>Japan</em>
|
||||
|
||||
<h2 id="to-build">To build:</h2>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>NOTE: the use of the C compiler optimiser was disabled and
|
||||
<code>-g</code> was enabled for this entry because it is SUPPOSED to
|
||||
crash and it needs debugging symbols.</p>
|
||||
<p>NOTE: the use of the C compiler optimiser was disabled and <code>-g</code> was enabled for
|
||||
this entry because it is SUPPOSED to crash and it needs debugging symbols.</p>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_endoh">2019 endoh bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_endoh">2019 endoh bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span></span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
<p>If you have <code>gdb(1)</code> installed:</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<p>Note that in macOS installing <code>gdb(1)</code> takes multiple
|
||||
steps - it’s not just a matter of installing <code>gdb(1)</code> and
|
||||
that’s that. The <a href="try.sh">try.sh</a> script has only been tested
|
||||
with linux.</p>
|
||||
<p>Note that in macOS installing <code>gdb(1)</code> takes multiple steps - it’s not just a
|
||||
matter of installing <code>gdb(1)</code> and that’s that. The <a href="try.sh">try.sh</a> script has
|
||||
only been tested with linux.</p>
|
||||
<p>You might also wish to try:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">gdb</span> ./prog <span class="kw">||</span> <span class="ex">lldb</span> ./prog</span></code></pre></div>
|
||||
<p>and then type in <code>r</code> (to run program) and then
|
||||
<code>bt</code> (for backtrace).</p>
|
||||
<p>and then type in <code>r</code> (to run program) and then <code>bt</code> (for backtrace).</p>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>The purpose of this program is to crash. You’ll want to have
|
||||
memorized <code>man 7 ascii</code> when debugging it to reveal its
|
||||
purpose.</p>
|
||||
<p>The purpose of this program is to crash. You’ll want to have memorized <code>man 7 ascii</code> when debugging it to reveal its purpose.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="backtrace-quine">backtrace quine:</h3>
|
||||
<p>Compile prog.c with no optimization.</p>
|
||||
@@ -217,59 +211,37 @@ Program received signal SIGSEGV, Segmentation fault.
|
||||
#7 0x0000555555555747 in x65 () at prog.c:101
|
||||
...</code></pre>
|
||||
<p>By using this, you can confirm that it is actually a quine.</p>
|
||||
<div class="sourceCode" id="cb12"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">gdb</span> <span class="at">-q</span> <span class="at">-x</span> prog.c ./prog <span class="kw">|</span> <span class="fu">sed</span> <span class="at">-n</span> <span class="at">-r</span> <span class="st">'s/#.*:([0-9]+)/\1/p'</span> <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'{printf "%c",$1}'</span> <span class="op">></span> prog2.c</span>
|
||||
<div class="sourceCode" id="cb12"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">gdb</span> <span class="at">-q</span> <span class="at">-x</span> prog.c ./prog <span class="kw">|</span> <span class="fu">sed</span> <span class="at">-n</span> <span class="at">-r</span> <span class="st">'s/#.*:([0-9]+)/\1/p'</span> <span class="kw">|</span> <span class="fu">awk</span> <span class="st">'{printf "%c",$1}'</span> <span class="op">></span> prog2.c</span>
|
||||
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="fu">diff</span> prog.c prog2.c</span></code></pre></div>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019endoh"><a name="inventory"></a>Inventory for
|
||||
2019/endoh</h1>
|
||||
<h1 id="inventory-for-2019endoh"><a name="inventory"></a>Inventory for 2019/endoh</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/ascii.c">ascii.c</a>
|
||||
- shows character value of ASCII</li>
|
||||
<li><a href="2019_endoh.tar.bz2">2019_endoh.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/ascii.c">ascii.c</a> - shows character value of ASCII</li>
|
||||
<li><a href="2019_endoh.tar.bz2">2019_endoh.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/endoh/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+148
-210
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Edward_Giles">Edward Giles</a><br>
|
||||
Location: <a href="../../location.html#AU">AU</a> - <em>Commonwealth of
|
||||
Australia</em> (<em>Australia</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#AU">AU</a> - <em>Commonwealth of Australia</em> (<em>Australia</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -145,279 +145,217 @@ Australia</em> (<em>Australia</em>) <br><br></li>
|
||||
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> infile.wav outfile.wav</span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<p>NOTE: <code>play</code>, which <a href="try.sh">try.sh</a> uses,
|
||||
comes from SoX, the Swiss Army Knife of sound processing programs. If
|
||||
you don’t have this installed, see <a href="../../faq.html#sox">FAQ
|
||||
3.10: How do I compile and use an IOCCC entry that requires
|
||||
sound</a>.</p>
|
||||
<p>NOTE: <code>play</code>, which <a href="try.sh">try.sh</a> uses, comes from SoX, the Swiss Army Knife
|
||||
of sound processing programs. If you don’t have this installed, see <a href="../../faq.html#sox">FAQ 3.10:
|
||||
How do I compile and use an IOCCC entry that requires sound</a>.</p>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Do you need to pretend enjoying a more spacious living environment
|
||||
than you actually are in, or the great outdoors with mountains and
|
||||
canyons, when recording your outgoing voicemail message? Then don’t
|
||||
waste another minute! Record yourself, send the audio file through this
|
||||
entry, and let your callers be surprised.</p>
|
||||
<p>Do you need to pretend enjoying a more spacious living environment than you
|
||||
actually are in, or the great outdoors with mountains and canyons, when
|
||||
recording your outgoing voicemail message? Then don’t waste another minute!
|
||||
Record yourself, send the audio file through this entry, and let your callers be
|
||||
surprised.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="description">Description:</h3>
|
||||
<p>This program takes a WAV audio file as input, and applies an
|
||||
artificial reverberation effect to it. It works by feeding the audio
|
||||
through a number of delay lines of various lengths, with various amounts
|
||||
of feedback, to create a smooth echo that fades away over time. A number
|
||||
of parameters of the effect can be altered, to change its sonic
|
||||
characteristics.</p>
|
||||
<p><a href="BlockDiagram.png">BlockDiagram.png</a> is a block-diagram of
|
||||
the internal structure of the reverb algorithm, which is most likely
|
||||
easier to understand than the source code.</p>
|
||||
<p><a href="MonodyVocals.wav">MonodyVocals.wav</a> is for testing the
|
||||
program: It is an extract of the unprocessed vocals from <a
|
||||
href="https://www.youtube.com/watch?v=B7xai5u_tnk">Monody by TheFatRat,
|
||||
featuring Laura Brehm</a>. The track was published under a free
|
||||
license.</p>
|
||||
<p>This program has also been successfully compiled on Windows, with
|
||||
both the <a href="https://bellard.org/tcc/">Tiny C Compiler</a> and
|
||||
Microsoft’s C/C++ compiler. However, the latter reports warnings about
|
||||
loss of information when converting <code>float</code>s, and that
|
||||
<code>void (*)()</code> and <code>void (*)(void)</code> are not the same
|
||||
thing.</p>
|
||||
<p>Interesting fact: The size of the program from
|
||||
<code>./iocccsize -i</code> is 2019.</p>
|
||||
<p>This program takes a WAV audio file as input, and applies an artificial
|
||||
reverberation effect to it. It works by feeding the audio through a number of
|
||||
delay lines of various lengths, with various amounts of feedback, to create a
|
||||
smooth echo that fades away over time. A number of parameters of the effect can
|
||||
be altered, to change its sonic characteristics.</p>
|
||||
<p><a href="BlockDiagram.png">BlockDiagram.png</a> is a block-diagram of the internal
|
||||
structure of the reverb algorithm, which is most likely easier to understand
|
||||
than the source code.</p>
|
||||
<p><a href="MonodyVocals.wav">MonodyVocals.wav</a> is for testing the program: It is an
|
||||
extract of the unprocessed vocals from <a href="https://www.youtube.com/watch?v=B7xai5u_tnk">Monody by TheFatRat, featuring Laura
|
||||
Brehm</a>. The track was published
|
||||
under a free license.</p>
|
||||
<p>This program has also been successfully compiled on Windows, with both the <a href="https://bellard.org/tcc/">Tiny
|
||||
C Compiler</a> and Microsoft’s C/C++ compiler. However,
|
||||
the latter reports warnings about loss of information when converting <code>float</code>s,
|
||||
and that <code>void (*)()</code> and <code>void (*)(void)</code> are not the same thing.</p>
|
||||
<p>Interesting fact: The size of the program from <code>./iocccsize -i</code> is 2019.</p>
|
||||
<h4 id="how-to-use">How to use:</h4>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input [output [size [dry [wet <span class="pp">[</span><span class="ss">damping</span><span class="pp">]</span>]]]]</span>
|
||||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="ex">prog.exe</span> input [output [size [dry [wet <span class="pp">[</span><span class="ss">damping</span><span class="pp">]</span>]]]]</span></code></pre></div>
|
||||
<ul>
|
||||
<li><code>input</code>: The path to the input file. Required.</li>
|
||||
<li><code>output</code>: The path to the output file. Optional, defaults
|
||||
to <code>out.wav</code>.</li>
|
||||
<li><code>size</code>: The perceived size of the room, i.e. the
|
||||
approximate amount of time taken for the echo to fade away. Optional,
|
||||
default 1.6 seconds.</li>
|
||||
<li><code>dry</code>: The amount of unprocessed signal (“dry” in audio
|
||||
terminology) to add to the output. Optional, default 0.3 or 30%.</li>
|
||||
<li><code>wet</code>: The amount of processed (“wet”) signal to add to
|
||||
the output. Optional, default 0.5 or 50%.</li>
|
||||
<li><code>damping</code>: The amount by which high frequencies are
|
||||
damped out as the echo continues. This models the tendency for higher
|
||||
frequencies to be absorbed more than lower ones. Increasing this value
|
||||
causes the echo to be less “harsh” and more “muffled”. Optional, default
|
||||
0.06 or 6%.</li>
|
||||
<li><code>output</code>: The path to the output file. Optional, defaults to <code>out.wav</code>.</li>
|
||||
<li><code>size</code>: The perceived size of the room, i.e. the approximate amount of time
|
||||
taken for the echo to fade away. Optional, default 1.6 seconds.</li>
|
||||
<li><code>dry</code>: The amount of unprocessed signal (“dry” in audio terminology) to add to
|
||||
the output. Optional, default 0.3 or 30%.</li>
|
||||
<li><code>wet</code>: The amount of processed (“wet”) signal to add to the output. Optional,
|
||||
default 0.5 or 50%.</li>
|
||||
<li><code>damping</code>: The amount by which high frequencies are damped out as the echo
|
||||
continues. This models the tendency for higher frequencies to be absorbed more
|
||||
than lower ones. Increasing this value causes the echo to be less “harsh” and
|
||||
more “muffled”. Optional, default 0.06 or 6%.</li>
|
||||
</ul>
|
||||
<p>The values <code>size</code>, <code>dry</code>, <code>wet</code>, and
|
||||
<code>damping</code> can be specified either as decimal numbers
|
||||
(e.g. 0.35) or as percentages (e.g. 35%).</p>
|
||||
<p>The default settings are designed to make the effect obvious rather
|
||||
than subtle, so it may be a good idea to adjust the ratio of “dry” to
|
||||
“wet”, to give a more pleasant result:</p>
|
||||
<p>The values <code>size</code>, <code>dry</code>, <code>wet</code>, and <code>damping</code> can be specified either as
|
||||
decimal numbers (e.g. 0.35) or as percentages (e.g. 35%).</p>
|
||||
<p>The default settings are designed to make the effect obvious rather than subtle,
|
||||
so it may be a good idea to adjust the ratio of “dry” to “wet”, to give a more
|
||||
pleasant result:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> in.wav out.wav 1.8 80% 15%</span></code></pre></div>
|
||||
<p>The program only supports WAV files, and only mostly. Other audio
|
||||
formats, such as MP3, are not supported because they are difficult to
|
||||
decode, but there are free programs such as <code>ffmpeg</code> that can
|
||||
perform the conversion. Some of the advanced features of the WAV file
|
||||
format are also not supported, such as metadata, 3 or more channels, or
|
||||
a bit depth other than 16 bits. Fortunately, WAV files that don’t use
|
||||
these features are very common. The program validates the input file, so
|
||||
passing it a file it can’t process will cause the program to print
|
||||
<code>Bad input file</code> or
|
||||
<code>Wave file must be 16 bits,1-2 channels.</code> depending on what
|
||||
it thinks the problem is. If the output file cannot be opened, the
|
||||
program will print <code>Can't open output file</code>.</p>
|
||||
<p>The program only supports WAV files, and only mostly. Other audio formats, such
|
||||
as MP3, are not supported because they are difficult to decode, but there are
|
||||
free programs such as <code>ffmpeg</code> that can perform the conversion. Some of the
|
||||
advanced features of the WAV file format are also not supported, such as
|
||||
metadata, 3 or more channels, or a bit depth other than 16 bits. Fortunately,
|
||||
WAV files that don’t use these features are very common. The program validates
|
||||
the input file, so passing it a file it can’t process will cause the program to
|
||||
print <code>Bad input file</code> or <code>Wave file must be 16 bits,1-2 channels.</code> depending on
|
||||
what it thinks the problem is. If the output file cannot be opened, the program
|
||||
will print <code>Can't open output file</code>.</p>
|
||||
<h3 id="assumptions">Assumptions:</h3>
|
||||
<ol type="1">
|
||||
<li>The code is compiled using the C99 or C11 standard.</li>
|
||||
<li>Values are stored in memory in little-endian order.</li>
|
||||
<li><code>float</code> is a floating-point type of any size, such that
|
||||
all zero bits represents the number zero.</li>
|
||||
<li><code>int16_t</code> and <code>int32_t</code> are 2’s-complement,
|
||||
<code>sizeof(int16_t) == 2</code> and
|
||||
<li><code>float</code> is a floating-point type of any size, such that all zero bits
|
||||
represents the number zero.</li>
|
||||
<li><code>int16_t</code> and <code>int32_t</code> are 2’s-complement, <code>sizeof(int16_t) == 2</code> and
|
||||
<code>sizeof(int32_t) == 4</code>.</li>
|
||||
</ol>
|
||||
<h3 id="obfuscations">Obfuscations</h3>
|
||||
<p>The main obfuscation is that digital signal processing algorithms are
|
||||
inherently opaque. They just consist of iterating through a list of
|
||||
floating-point numbers and performing a series of arithmetic operations
|
||||
on each value. Even if this entry were entirely cleaned of all other
|
||||
obfuscation, it will appear to the average programmer to do the
|
||||
following:</p>
|
||||
<p>The main obfuscation is that digital signal processing algorithms are inherently
|
||||
opaque. They just consist of iterating through a list of floating-point numbers
|
||||
and performing a series of arithmetic operations on each value. Even if this
|
||||
entry were entirely cleaned of all other obfuscation, it will appear to the
|
||||
average programmer to do the following:</p>
|
||||
<ul>
|
||||
<li>Read and validate command-line arguments.</li>
|
||||
<li>Read and validate the header portion of the input file, and print
|
||||
some errors if that fails.</li>
|
||||
<li>Read and validate the header portion of the input file, and print some errors
|
||||
if that fails.</li>
|
||||
<li>Write a modified form of that header into the output file.</li>
|
||||
<li>Print the parameters read from the command-line arguments, in a
|
||||
human-readable format.</li>
|
||||
<li>Dynamically allocate some arrays of floating-point numbers, to be
|
||||
used later, with lengths based on the <code>size</code> parameter.</li>
|
||||
<li>Print the parameters read from the command-line arguments, in a human-readable
|
||||
format.</li>
|
||||
<li>Dynamically allocate some arrays of floating-point numbers, to be used later,
|
||||
with lengths based on the <code>size</code> parameter.</li>
|
||||
<li>Read 16-bit audio samples from the input file, converting them to
|
||||
floating-point.</li>
|
||||
<li>For each audio sample, do a weird combination of addition,
|
||||
subtraction, and multiplication by constants, using the
|
||||
previously-allocated arrays to store results between iterations. Write
|
||||
the resulting audio samples to the output file, converting them back to
|
||||
16-bit integers.</li>
|
||||
<li>For each audio sample, do a weird combination of addition, subtraction, and
|
||||
multiplication by constants, using the previously-allocated arrays to store
|
||||
results between iterations. Write the resulting audio samples to the output
|
||||
file, converting them back to 16-bit integers.</li>
|
||||
<li>Close all of the file handles and free the memory.</li>
|
||||
</ul>
|
||||
<p>Note that no part of the above description of the code’s function had
|
||||
anything to do with echoes in a room. The purpose of the code is
|
||||
therefore hidden.</p>
|
||||
<p>The source code, on cursory inspection, appears to be a jumbled
|
||||
series of characters arranged into three arcs, representing sound waves.
|
||||
The overall layout distracts people from the fact that it is source code
|
||||
rather than only ASCII art, and the random appearance of the code
|
||||
discourages people from trying to decipher it.</p>
|
||||
<p><code>#define</code>s are used to abbreviate the code, which has a
|
||||
side effect of making it very slightly harder to read.</p>
|
||||
<p>Note that no part of the above description of the code’s function had anything
|
||||
to do with echoes in a room. The purpose of the code is therefore hidden.</p>
|
||||
<p>The source code, on cursory inspection, appears to be a jumbled series of
|
||||
characters arranged into three arcs, representing sound waves. The overall
|
||||
layout distracts people from the fact that it is source code rather than only
|
||||
ASCII art, and the random appearance of the code discourages people from trying
|
||||
to decipher it.</p>
|
||||
<p><code>#define</code>s are used to abbreviate the code, which has a side effect of making it
|
||||
very slightly harder to read.</p>
|
||||
<ul>
|
||||
<li><code>k</code> is just a general-purpose replacement for
|
||||
<code>16</code>.</li>
|
||||
<li><code>i</code> is the number of delay-lines to allocate and use
|
||||
(currently <code>24</code>).</li>
|
||||
<li><code>q</code> is an abbreviation for multiplying two elements of
|
||||
<code>w[]</code> together.</li>
|
||||
<li><code>u()</code> is used to display percentages with proper
|
||||
rounding.</li>
|
||||
<li><code>j()</code> imposes an upper limit on a floating-point value,
|
||||
and then negates it. This operation is used eight times.</li>
|
||||
<li><code>D()</code> abbreviates a call to <code>setvbuf</code>, used to
|
||||
speed up file I/O.</li>
|
||||
<li><code>l()</code> is used to clip audio samples to the acceptable
|
||||
range, and convert them to 16-bit integers for output.</li>
|
||||
<li><code>k</code> is just a general-purpose replacement for <code>16</code>.</li>
|
||||
<li><code>i</code> is the number of delay-lines to allocate and use (currently <code>24</code>).</li>
|
||||
<li><code>q</code> is an abbreviation for multiplying two elements of <code>w[]</code> together.</li>
|
||||
<li><code>u()</code> is used to display percentages with proper rounding.</li>
|
||||
<li><code>j()</code> imposes an upper limit on a floating-point value, and then negates it.
|
||||
This operation is used eight times.</li>
|
||||
<li><code>D()</code> abbreviates a call to <code>setvbuf</code>, used to speed up file I/O.</li>
|
||||
<li><code>l()</code> is used to clip audio samples to the acceptable range, and convert them
|
||||
to 16-bit integers for output.</li>
|
||||
<li><code>g()</code> handles errors.</li>
|
||||
<li><code>C()</code> contains the bulk of the signal-processing code, as
|
||||
well as a preprocessor obfuscation trick: If you were to read the body
|
||||
of the macro out of context, it will appear to have multiple mismatched
|
||||
square brackets, since <code>[</code> occurs more than <code>]</code>.
|
||||
However, this macro is always invoked with arguments such as
|
||||
<code>C(v],+10)</code> which contain an unmatched <code>]</code>
|
||||
character. When the macro is used in this manner, the extra
|
||||
<code>[</code>s in the macro’s body are matched with the <code>]</code>s
|
||||
<li><code>C()</code> contains the bulk of the signal-processing code, as well as a
|
||||
preprocessor obfuscation trick: If you were to read the body of the macro out of
|
||||
context, it will appear to have multiple mismatched square brackets, since <code>[</code>
|
||||
occurs more than <code>]</code>. However, this macro is always invoked with arguments such
|
||||
as <code>C(v],+10)</code> which contain an unmatched <code>]</code> character. When the macro is used
|
||||
in this manner, the extra <code>[</code>s in the macro’s body are matched with the <code>]</code>s
|
||||
added through the first argument.</li>
|
||||
</ul>
|
||||
<p>Every variable name is one letter long. This allows the code to fit
|
||||
into the IOCCC size limit, and it also makes the purpose of a given
|
||||
variable much less clear. For example, it is not evident from the name
|
||||
of the variable <code>t</code> that it contains pointers to the
|
||||
delay-line arrays.</p>
|
||||
<p>As many values as possible have been crammed into arrays.
|
||||
<code>float w[]</code> contains:</p>
|
||||
<p>Every variable name is one letter long. This allows the code to fit into the
|
||||
IOCCC size limit, and it also makes the purpose of a given variable much less
|
||||
clear. For example, it is not evident from the name of the variable <code>t</code> that it
|
||||
contains pointers to the delay-line arrays.</p>
|
||||
<p>As many values as possible have been crammed into arrays. <code>float w[]</code> contains:</p>
|
||||
<ul>
|
||||
<li>the input parameters (<code>w[0]</code> to <code>w[3]</code>)</li>
|
||||
<li>various constants needed for the reverb algorithm (<code>w[4]</code>
|
||||
to <code>w[9]</code>)</li>
|
||||
<li>temporary storage of floating-point audio samples
|
||||
(<code>w[10]</code> to <code>w[20]</code>)</li>
|
||||
<li>various constants needed for the reverb algorithm (<code>w[4]</code> to <code>w[9]</code>)</li>
|
||||
<li>temporary storage of floating-point audio samples (<code>w[10]</code> to <code>w[20]</code>)</li>
|
||||
</ul>
|
||||
<p><code>int32_t f[]</code> is even more multi-purpose. It contains:</p>
|
||||
<ul>
|
||||
<li>the header of the input file (<code>f[0]</code> to
|
||||
<code>f[11]</code>)</li>
|
||||
<li>the header of the input file (<code>f[0]</code> to <code>f[11]</code>)</li>
|
||||
<li>the number of channels in the input file (<code>f[12]</code>)</li>
|
||||
<li>the number of samples of output to generate
|
||||
(<code>f[13]</code>)</li>
|
||||
<li>the number of samples of output to generate (<code>f[13]</code>)</li>
|
||||
<li>an end-of-file flag (<code>f[14]</code>)</li>
|
||||
<li>a variable that I forgot the exact purpose of
|
||||
(<code>f[15]</code>)</li>
|
||||
<li>indices into the circular buffers where audio samples should be
|
||||
inserted (<code>f[16]</code> to <code>f[39]</code>)</li>
|
||||
<li>indices where audio samples should be read out (<code>f[40]</code>
|
||||
to <code>f[63]</code>)</li>
|
||||
<li>lengths of the buffers (<code>f[64]</code> to
|
||||
<code>f[87]</code>)</li>
|
||||
<li>a variable that I forgot the exact purpose of (<code>f[15]</code>)</li>
|
||||
<li>indices into the circular buffers where audio samples should be inserted
|
||||
(<code>f[16]</code> to <code>f[39]</code>)</li>
|
||||
<li>indices where audio samples should be read out (<code>f[40]</code> to <code>f[63]</code>)</li>
|
||||
<li>lengths of the buffers (<code>f[64]</code> to <code>f[87]</code>)</li>
|
||||
</ul>
|
||||
<p>All of the strings are concatenated together and “encrypted” by
|
||||
breaking the string into 4-byte chunks (by casting it to an
|
||||
<code>int32_t*</code>), and then XORing the sequence of
|
||||
<code>int</code>s with a known numeric sequence. The “decryption” is not
|
||||
done in-place, to avoid writing over the string constant.</p>
|
||||
<p><code>int32_t *c</code> is a pointer that points into
|
||||
<code>f[]</code>, except that it is often incremented or decremented
|
||||
when it is accessed. In order to determine which indices of
|
||||
<code>f[]</code> are being accessed through <code>c</code> at any given
|
||||
point in the code, you would have to locate the places where
|
||||
<code>c</code> is modified.</p>
|
||||
<p>In order for this program to read and write WAV files, it needs to
|
||||
parse the header. The necessary information, such as the sample rate and
|
||||
channel count, is defined by the standard to be in somewhat arbitrary
|
||||
locations within the file. Therefore, even if you know which indices of
|
||||
<code>f[]</code> are being accessed, it takes extra effort to look up
|
||||
the WAV file format and determine which field that corresponds to.</p>
|
||||
<p>Some array accesses (which make up most of the program) have been
|
||||
replaced with harder-to-interpret equivalents, for example:</p>
|
||||
<p>All of the strings are concatenated together and “encrypted” by breaking the
|
||||
string into 4-byte chunks (by casting it to an <code>int32_t*</code>), and then XORing the
|
||||
sequence of <code>int</code>s with a known numeric sequence. The “decryption” is not done
|
||||
in-place, to avoid writing over the string constant.</p>
|
||||
<p><code>int32_t *c</code> is a pointer that points into <code>f[]</code>, except that it is often
|
||||
incremented or decremented when it is accessed. In order to determine which
|
||||
indices of <code>f[]</code> are being accessed through <code>c</code> at any given point in the code,
|
||||
you would have to locate the places where <code>c</code> is modified.</p>
|
||||
<p>In order for this program to read and write WAV files, it needs to parse the
|
||||
header. The necessary information, such as the sample rate and channel count, is
|
||||
defined by the standard to be in somewhat arbitrary locations within the file.
|
||||
Therefore, even if you know which indices of <code>f[]</code> are being accessed, it takes
|
||||
extra effort to look up the WAV file format and determine which field that
|
||||
corresponds to.</p>
|
||||
<p>Some array accesses (which make up most of the program) have been replaced with
|
||||
harder-to-interpret equivalents, for example:</p>
|
||||
<ul>
|
||||
<li><code>X[1]</code> -> <code>1[X]</code></li>
|
||||
<li><code>f[14]</code> -> <code>10[f+4]</code></li>
|
||||
<li><code>X[0]</code> -> <code>*X</code></li>
|
||||
</ul>
|
||||
<p>Assignments return the assigned value, allowing them to be included
|
||||
into later expressions:
|
||||
<code>10[f]=f[13]<<2; f[1]=20+10[f]+k;</code> is replaced with
|
||||
<p>Assignments return the assigned value, allowing them to be included into later
|
||||
expressions: <code>10[f]=f[13]<<2; f[1]=20+10[f]+k;</code> is replaced with
|
||||
<code>f[1]=20+(10[f]=f[13]<<2)+k;</code>.</p>
|
||||
<p>This technique is used in conjunction with the comma operator to
|
||||
further obscure where the data ends up. For example:</p>
|
||||
<p>This technique is used in conjunction with the comma operator to further obscure
|
||||
where the data ends up. For example:</p>
|
||||
<ul>
|
||||
<li><code>12[f]=4[++c]>>k;</code> was incorporated into
|
||||
<code>w[0]*=6[f];</code> to yield
|
||||
<li><code>12[f]=4[++c]>>k;</code> was incorporated into <code>w[0]*=6[f];</code> to yield
|
||||
<code>w[0]*=(12[f]=4[++c]>>k,6[f]);</code></li>
|
||||
<li><code>w[15]=w[k]=e[12[f]]; w[11]=w[10]=e[1];</code> becomes
|
||||
<code>w[11]=(w[15]=w[k]=e[12[f]],w[10]=e[1]);</code></li>
|
||||
</ul>
|
||||
<p>A few other miscellaneous obfuscations have also been done:</p>
|
||||
<ul>
|
||||
<li><code>while(++f[15]<12);</code> is used instead of
|
||||
<code>f[15]=12;</code></li>
|
||||
<li><code>for(s=14[f]=0;s<f[13];s++)</code> is used instead of
|
||||
<code>f[14]=0; for(s=0;s<f[13];s++)</code></li>
|
||||
<li>The line that contains <code>printf("Hello, world!");</code> is
|
||||
mostly commented out.</li>
|
||||
<li><code>while(++f[15]<12);</code> is used instead of <code>f[15]=12;</code></li>
|
||||
<li><code>for(s=14[f]=0;s<f[13];s++)</code> is used instead of <code>f[14]=0; for(s=0;s<f[13];s++)</code></li>
|
||||
<li>The line that contains <code>printf("Hello, world!");</code> is mostly commented out.</li>
|
||||
</ul>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019giles"><a name="inventory"></a>Inventory for
|
||||
2019/giles</h1>
|
||||
<h1 id="inventory-for-2019giles"><a name="inventory"></a>Inventory for 2019/giles</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a href="BlockDiagram.png">BlockDiagram.png</a> - reverb algorithm
|
||||
block-diagram of internal structure</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a href="MonodyVocals.wav">MonodyVocals.wav</a> - Monody by
|
||||
TheFatRat featuring Laura Brehm</li>
|
||||
<li><a href="2019_giles.tar.bz2">2019_giles.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="BlockDiagram.png">BlockDiagram.png</a> - reverb algorithm block-diagram of internal structure</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="MonodyVocals.wav">MonodyVocals.wav</a> - Monody by TheFatRat featuring Laura Brehm</li>
|
||||
<li><a href="2019_giles.tar.bz2">2019_giles.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/giles/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+50
-79
@@ -123,32 +123,27 @@
|
||||
<!-- END: this line ends content from: inc/before-content.default.html -->
|
||||
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
|
||||
<h1 id="twenty-sixth-international-obfuscated-c-code-contest">Twenty
|
||||
Sixth International Obfuscated C Code Contest</h1>
|
||||
<h1 id="twenty-sixth-international-obfuscated-c-code-contest">Twenty Sixth International Obfuscated C Code Contest</h1>
|
||||
<h2 id="standard-ioccc-stuff">Standard IOCCC stuff</h2>
|
||||
<p>View the <code>index.html</code> web page for the given winning entry
|
||||
for information on how on how to compile it and how to run the winning
|
||||
program. Look at the winning source and try to figure how it does what
|
||||
it does! You may then wish to look at the Author’s remarks for even more
|
||||
details.</p>
|
||||
<p>The primary site can be found at <a
|
||||
href="https://www.ioccc.org">www.ioccc.org</a>.</p>
|
||||
<p>Use <code>make</code> to compile entries. It is possible that on
|
||||
non-Unix / non-Linux systems the Makefile needs to be changed. See the
|
||||
Makefile for details.</p>
|
||||
<p>Read over the Makefile and index.html files for compile/build issues.
|
||||
Your system may require certain changes (add or remove a library, add or
|
||||
remove a <code>#define</code>).</p>
|
||||
<p>View the <code>index.html</code> web page for the given winning entry for information on how
|
||||
on how to compile it and how to run the winning program.
|
||||
Look at the winning source and try to figure how it does what it does!
|
||||
You may then wish to look at the Author’s remarks for even more details.</p>
|
||||
<p>The primary site can be found at <a href="https://www.ioccc.org">www.ioccc.org</a>.</p>
|
||||
<p>Use <code>make</code> to compile entries. It is possible that on non-Unix / non-Linux
|
||||
systems the Makefile needs to be changed. See the Makefile for details.</p>
|
||||
<p>Read over the Makefile and index.html files for compile/build issues. Your
|
||||
system may require certain changes (add or remove a library, add or remove a
|
||||
<code>#define</code>).</p>
|
||||
<p>Some C compilers are not quite as good as they should be. If yours is
|
||||
lacking, you may need to compile using clang or gcc instead of your
|
||||
local compiler.</p>
|
||||
<h2 id="remarks-on-some-of-the-winning-entries">Remarks on some of the
|
||||
winning entries</h2>
|
||||
lacking, you may need to compile using clang or gcc instead of your local
|
||||
compiler.</p>
|
||||
<h2 id="remarks-on-some-of-the-winning-entries">Remarks on some of the winning entries</h2>
|
||||
<p>This year’s winning entries are impressive!</p>
|
||||
<p>The <a href="endoh/index.html">“Most in need of debugging”
|
||||
(endoh)</a> is very inventive in a way it produces its own text!</p>
|
||||
<p>The <a href="ciura/index.html">“Most likely to be awarded”
|
||||
(ciura)</a> has an amazing vocabulary!</p>
|
||||
<p>The <a href="endoh/index.html">“Most in need of debugging” (endoh)</a> is very inventive in
|
||||
a way it produces its own text!</p>
|
||||
<p>The <a href="ciura/index.html">“Most likely to be awarded” (ciura)</a> has an amazing
|
||||
vocabulary!</p>
|
||||
<p>There are again nods to entries of the years:</p>
|
||||
<pre><code>[1991/davidguy](../years.html#1991_davidguy)
|
||||
[2011/blakely](../years.html#2011_blakely)</code></pre>
|
||||
@@ -156,79 +151,55 @@ winning entries</h2>
|
||||
<pre><code>We tend to dislike programs that:
|
||||
...
|
||||
are rather similar to previous entries</code></pre>
|
||||
<p>because the entry <a href="2019/dogon/index.html">2019/dogon</a>
|
||||
appropriately pays homage to past entries without blatantly reusing
|
||||
their code.</p>
|
||||
<p>…We’ll stop spouting spoilers now. Have fun exploring all the
|
||||
entries!</p>
|
||||
<h2 id="remarks-on-some-of-submissions-that-did-not-win">Remarks on some
|
||||
of submissions that did not win</h2>
|
||||
<p>because the entry <a href="2019/dogon/index.html">2019/dogon</a> appropriately pays homage
|
||||
to past entries without blatantly reusing their code.</p>
|
||||
<p>…We’ll stop spouting spoilers now. Have fun exploring all the entries!</p>
|
||||
<h2 id="remarks-on-some-of-submissions-that-did-not-win">Remarks on some of submissions that did not win</h2>
|
||||
<p>Some entries tried to get around the size limit by submitting a data
|
||||
file that was really C code and then blindly including code in
|
||||
prog.c.</p>
|
||||
file that was really C code and then blindly including code in prog.c.</p>
|
||||
<p>Quite a few entries suffered from undefined behavior like accessing
|
||||
uninitialized locals and/or reading-writing below the stack. We advise
|
||||
running your entry through valgrind to make sure those mistakes are
|
||||
avoided.</p>
|
||||
<p>Using extra arguments to <code>main</code>, or arguments of wrong
|
||||
types as a quick and dirty way of declaring variables is now passé.
|
||||
Clang, for example, rejects them outright.</p>
|
||||
uninitialized locals and/or reading-writing below the stack.
|
||||
We advise running your entry through valgrind to make sure those mistakes
|
||||
are avoided.</p>
|
||||
<p>Using extra arguments to <code>main</code>, or arguments of wrong types as a quick and dirty
|
||||
way of declaring variables is now passé. Clang, for example, rejects them outright.</p>
|
||||
<p>We hope the authors of some of those entries will fix and re-submit
|
||||
them for the next IOCCC.</p>
|
||||
<p>Some entries seemed to have a good idea, but the implementation of
|
||||
the idea was limited in scope.</p>
|
||||
<h2 id="final-comments">Final Comments</h2>
|
||||
<p><strong>IMPORTANT NOTE</strong>: See <a
|
||||
href="../contact.html">contact.html</a> for up to date contact details
|
||||
as well as details on how to provide fixes to any of the entries. See
|
||||
also <a href="../faq.html">the IOCCC FAQ</a> for addition information on
|
||||
the IOCCC.</p>
|
||||
<p><strong>IMPORTANT NOTE</strong>: See <a href="../contact.html">contact.html</a> for up to date contact details
|
||||
as well as details on how to provide fixes to any of the entries.
|
||||
See also <a href="../faq.html">the IOCCC FAQ</a> for addition information on the IOCCC.</p>
|
||||
<h1 id="copyright-and-license">Copyright and License</h1>
|
||||
<p>Copyright (c) 2019,2023, Landon Curt Noll and Leonid A. Broukhis. All
|
||||
Rights Reserved. This work is licensed under a <a
|
||||
href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons
|
||||
CC BY-SA 4.0 DEED Attribution-ShareAlike 4.0 International</a> license.
|
||||
If you do use this work in some form, the <a href="../judges.html">IOCCC
|
||||
judges</a> would appreciate (but does not require) if you were to <a
|
||||
href="../contact.html">send us a note about your use</a>.</p>
|
||||
<p>Copyright (c) 2019,2023, Landon Curt Noll and Leonid A. Broukhis. All Rights Reserved.
|
||||
This work is licensed under a <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons CC BY-SA 4.0 DEED Attribution-ShareAlike
|
||||
4.0 International</a> license.
|
||||
If you do use this work in some form, the <a href="../judges.html">IOCCC judges</a> would appreciate
|
||||
(but does not require) if you were to <a href="../contact.html">send us a note about your use</a>.</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-year-index.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-year-index.sh -->
|
||||
|
||||
<h1
|
||||
id="winning-entries-of-2019---the-26th-ioccc"><a name=inventory></a><a name=2019></a>Winning
|
||||
Entries of 2019 - The 26th IOCCC</h1>
|
||||
<p><strong>Download IOCCC</strong> <a
|
||||
href="2019/ioccc.2019.tar.bz2">2019 entry source</a></p>
|
||||
<h1 id="winning-entries-of-2019---the-26th-ioccc"><a name=inventory></a><a name=2019></a>Winning Entries of 2019 - The 26th IOCCC</h1>
|
||||
<p><strong>Download IOCCC</strong> <a href="2019/ioccc.2019.tar.bz2">2019 entry source</a></p>
|
||||
<ul>
|
||||
<li><a href="adamovsky/index.html">2019/adamovsky</a> - Most functional
|
||||
interpreter</li>
|
||||
<li><a href="adamovsky/index.html">2019/adamovsky</a> - Most functional interpreter</li>
|
||||
<li><a href="burton/index.html">2019/burton</a> - Best one-liner</li>
|
||||
<li><a href="ciura/index.html">2019/ciura</a> - Most alphabetic</li>
|
||||
<li><a href="diels-grabsch1/index.html">2019/diels-grabsch1</a> - Best
|
||||
small program</li>
|
||||
<li><a href="diels-grabsch2/index.html">2019/diels-grabsch2</a> - Most
|
||||
self-aware</li>
|
||||
<li><a href="dogon/index.html">2019/dogon</a> - Best use of space and
|
||||
time</li>
|
||||
<li><a href="duble/index.html">2019/duble</a> - Best collaborative
|
||||
graphics</li>
|
||||
<li><a href="endoh/index.html">2019/endoh</a> - Most in need of
|
||||
debugging</li>
|
||||
<li><a href="giles/index.html">2019/giles</a> - Most in need of wide
|
||||
space</li>
|
||||
<li><a href="karns/index.html">2019/karns</a> - Most in need of
|
||||
whitespace</li>
|
||||
<li><a href="lynn/index.html">2019/lynn</a> - Most functional
|
||||
compiler</li>
|
||||
<li><a href="mills/index.html">2019/mills</a> - Most in need to be
|
||||
tweeted</li>
|
||||
<li><a href="poikola/index.html">2019/poikola</a> - Most
|
||||
calendrical</li>
|
||||
<li><a href="yang/index.html">2019/yang</a> - Most in need of
|
||||
transparency</li>
|
||||
<li><a href="diels-grabsch1/index.html">2019/diels-grabsch1</a> - Best small program</li>
|
||||
<li><a href="diels-grabsch2/index.html">2019/diels-grabsch2</a> - Most self-aware</li>
|
||||
<li><a href="dogon/index.html">2019/dogon</a> - Best use of space and time</li>
|
||||
<li><a href="duble/index.html">2019/duble</a> - Best collaborative graphics</li>
|
||||
<li><a href="endoh/index.html">2019/endoh</a> - Most in need of debugging</li>
|
||||
<li><a href="giles/index.html">2019/giles</a> - Most in need of wide space</li>
|
||||
<li><a href="karns/index.html">2019/karns</a> - Most in need of whitespace</li>
|
||||
<li><a href="lynn/index.html">2019/lynn</a> - Most functional compiler</li>
|
||||
<li><a href="mills/index.html">2019/mills</a> - Most in need to be tweeted</li>
|
||||
<li><a href="poikola/index.html">2019/poikola</a> - Most calendrical</li>
|
||||
<li><a href="yang/index.html">2019/yang</a> - Most in need of transparency</li>
|
||||
</ul>
|
||||
<p> <strong>Jump to:</strong> <a href="#">top</a></p>
|
||||
|
||||
|
||||
+48
-76
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Joshua_Karns">Joshua Karns</a><br>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of
|
||||
America</em> (<em>United States</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -141,51 +141,45 @@ America</em> (<em>United States</em>) <br><br></li>
|
||||
|
||||
<h2 id="to-build">To build:</h2>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>NOTE: we disable the optimiser because this program has problems with
|
||||
it enabled.</p>
|
||||
<p>NOTE: we disable the optimiser because this program has problems with it
|
||||
enabled.</p>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_karns">2019 karns bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_karns">2019 karns bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> textfile_that_fits_on_the_screen</span></code></pre></div>
|
||||
<p>You might want to type:</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">reset</span></span></code></pre></div>
|
||||
<p>after running the program to restore the terminal to its previous
|
||||
state.</p>
|
||||
<p>after running the program to restore the terminal to its previous state.</p>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<p>If you have more time you might want to try:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> README.md</span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>If you typically get lost in mazes, watching this program run might –
|
||||
or might not, YMMV – teach you how to find your way in a maze. The
|
||||
algorithm is well-known but the drawing is amazing!</p>
|
||||
<p>Before running, make sure that your terminal can accommodate the
|
||||
whole file. Before running <code>make test</code>, make it about 120x40
|
||||
to be safe, ensuring that you see the <code>@</code> sign as well as the
|
||||
exclamation mark.</p>
|
||||
<p>If you typically get lost in mazes, watching this program run might – or might
|
||||
not, YMMV – teach you how to find your way in a maze. The algorithm is
|
||||
well-known but the drawing is amazing!</p>
|
||||
<p>Before running, make sure that your terminal can accommodate the whole file.
|
||||
Before running <code>make test</code>, make it about 120x40 to be safe, ensuring that you
|
||||
see the <code>@</code> sign as well as the exclamation mark.</p>
|
||||
<p>…Oh, and the first <code>M</code> in YMMV stands for “mazing”.</p>
|
||||
<p>A puzzle for the reader: Can you change the program to consider a
|
||||
diagonal movement as one step?</p>
|
||||
<p>A puzzle for the reader: Can you change the program to consider a diagonal
|
||||
movement as one step?</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="the-program">The Program:</h3>
|
||||
<p>This program is pretty simple! It performs a <a
|
||||
href="https://en.wikipedia.org/wiki/Breadth-first_search">breadth first
|
||||
search</a> on the specified graph. The graph can be any ASCII text file
|
||||
that has an ‘at’ (<code>@</code>) character, which is going to be the
|
||||
starting location, and a <code>!</code> character which will be the
|
||||
destination.</p>
|
||||
<p>The nodes on this graph that are spaces are connected with any
|
||||
directly adjacent nodes that are also spaces. Nodes that aren’t spaces
|
||||
are not connected with anything.</p>
|
||||
<p>This program is pretty simple! It performs a <a href="https://en.wikipedia.org/wiki/Breadth-first_search">breadth first
|
||||
search</a> on the
|
||||
specified graph. The graph can be any ASCII text file that has an ‘at’ (<code>@</code>)
|
||||
character, which is going to be the starting location, and a <code>!</code> character
|
||||
which will be the destination.</p>
|
||||
<p>The nodes on this graph that are spaces are connected with any directly
|
||||
adjacent nodes that are also spaces. Nodes that aren’t spaces are not
|
||||
connected with anything.</p>
|
||||
<h3 id="compiling-and-running">Compiling and Running:</h3>
|
||||
<p>This program usually compiles under both GCC and clang. Build
|
||||
with:</p>
|
||||
<p>This program usually compiles under both GCC and clang. Build with:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="va">$(</span><span class="ex">CC</span><span class="va">)</span> <span class="at">-std</span><span class="op">=</span>c99 <span class="at">-o</span> tbfs prog.c</span></code></pre></div>
|
||||
<p>where <code>$(CC)</code> is cc, gcc, clang, or some other C
|
||||
compiler.</p>
|
||||
<p>where <code>$(CC)</code> is cc, gcc, clang, or some other C compiler.</p>
|
||||
<p>You can then run it with:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cat</span> <span class="op"><</span>input file<span class="op">></span> <span class="kw">|</span> <span class="ex">./tbfs</span></span></code></pre></div>
|
||||
<p>Examples:</p>
|
||||
@@ -193,72 +187,50 @@ compiler.</p>
|
||||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="ex">./tbfs</span> <span class="op"><</span> prog.c</span></code></pre></div>
|
||||
<h3 id="issues">Issues</h3>
|
||||
<ul>
|
||||
<li>The program must be ran in a terminal that supports ANSI escape
|
||||
codes for moving the cursor and changing colors.</li>
|
||||
<li>The program must be ran in a terminal that supports ANSI escape codes for
|
||||
moving the cursor and changing colors.</li>
|
||||
<li>Segfaults happen sometimes.</li>
|
||||
<li>I don’t know what memory management there is, if any.</li>
|
||||
<li>The program will not compile by an ANSI C compiler: it uses for
|
||||
loops, and it uses C++ style comments. It should compile cleanly using a
|
||||
C99 standard.</li>
|
||||
<li>Breadth first search is slow (and very slow on certain maps), but my
|
||||
A star version of this program is too big.</li>
|
||||
<li>Lots of extra whitespace may be needed if you want to feed in an
|
||||
arbitrary file.</li>
|
||||
<li>It fails to compile on GCC sometimes (according to a friend of mine,
|
||||
I’ve not encountered this myself).</li>
|
||||
<li>The program will not compile by an ANSI C compiler: it uses for loops, and
|
||||
it uses C++ style comments. It should compile cleanly using a C99 standard.</li>
|
||||
<li>Breadth first search is slow (and very slow on certain maps), but my A star
|
||||
version of this program is too big.</li>
|
||||
<li>Lots of extra whitespace may be needed if you want to feed in an arbitrary
|
||||
file.</li>
|
||||
<li>It fails to compile on GCC sometimes (according to a friend of mine, I’ve
|
||||
not encountered this myself).</li>
|
||||
<li>The program could be obfuscated much further.</li>
|
||||
<li>The program contains some unused code and data.</li>
|
||||
</ul>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019karns"><a name="inventory"></a>Inventory for
|
||||
2019/karns</h1>
|
||||
<h1 id="inventory-for-2019karns"><a name="inventory"></a>Inventory for 2019/karns</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/maze">maze</a>
|
||||
- input maze map</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a href="2019_karns.tar.bz2">2019_karns.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/maze">maze</a> - input maze map</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="2019_karns.tar.bz2">2019_karns.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/karns/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+153
-226
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Ben_Lynn">Ben Lynn</a><br>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of
|
||||
America</em> (<em>United States</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -144,32 +144,28 @@ America</em> (<em>United States</em>) <br><br></li>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_lynn">2019 lynn bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_lynn">2019 lynn bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span></span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>A fully functional compiler. The example prints out the 30th <a
|
||||
href="https://en.wikipedia.org/wiki/Fibonacci_sequence">Fibonacci
|
||||
<p>A fully functional compiler. The example prints out the 30th <a href="https://en.wikipedia.org/wiki/Fibonacci_sequence">Fibonacci
|
||||
number</a>.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="remarks">Remarks:</h3>
|
||||
<p>A Haskell compiler. Supports a subset of Haskell more than large
|
||||
enough to self-host. Like GHC with custom language extensions:</p>
|
||||
<p>A Haskell compiler. Supports a subset of Haskell more than large enough to
|
||||
self-host. Like GHC with custom language extensions:</p>
|
||||
<ul>
|
||||
<li><p><code>WeDontServeYourType</code>: Compilation failing because of
|
||||
inscrutable type checking rules? Confused by the ever-growing mire of
|
||||
extensions to the type system? The solution is simple: no type checking.
|
||||
It also means no typeclasses. Just pass dictionaries
|
||||
explicitly.</p></li>
|
||||
<li><p><code>ZeroPauseGarbageCollection</code>: Instead of disruptive
|
||||
stop-the-world garbage collection, we only tidy up when the world stops
|
||||
on its own accord, that is, on program termination.</p></li>
|
||||
<li><p><code>OneHundredPercentPure</code>: Gone is the catch-all lawless
|
||||
IO monad. And no trace of those scary <code>unsafeThisAndThat</code>
|
||||
functions. All functions must be pure.</p></li>
|
||||
<li><p><code>WeDontServeYourType</code>: Compilation failing because of inscrutable type
|
||||
checking rules? Confused by the ever-growing mire of extensions to the type
|
||||
system? The solution is simple: no type checking. It also means no
|
||||
typeclasses. Just pass dictionaries explicitly.</p></li>
|
||||
<li><p><code>ZeroPauseGarbageCollection</code>: Instead of disruptive stop-the-world garbage
|
||||
collection, we only tidy up when the world stops on its own accord, that is,
|
||||
on program termination.</p></li>
|
||||
<li><p><code>OneHundredPercentPure</code>: Gone is the catch-all lawless IO monad. And no
|
||||
trace of those scary <code>unsafeThisAndThat</code> functions. All functions must be pure.</p></li>
|
||||
<li><p><code>SyntaxForTheMasses</code>: See below.</p></li>
|
||||
</ul>
|
||||
<h3 id="building">Building:</h3>
|
||||
@@ -179,102 +175,82 @@ functions. All functions must be pure.</p></li>
|
||||
<h4 id="fibonacci-numbers">Fibonacci numbers:</h4>
|
||||
<p>Test the compiler on <a href="fib.hs">fib.hs</a>:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">(</span><span class="ex">./prog</span> <span class="op"><</span> fib.hs <span class="kw">;</span> <span class="fu">cat</span> prog.c<span class="kw">)</span> <span class="op">></span> fib.c</span></code></pre></div>
|
||||
<p>Compiling the output produces a binary that prints the 30th Fibonacci
|
||||
number.</p>
|
||||
<p>The file <a href="ghcfib.hs">ghcfib.hs</a> includes <a
|
||||
href="fib.hs">fib.hs</a> with some glue code, and shows GHC also accepts
|
||||
our subset of Haskell:</p>
|
||||
<p>Compiling the output produces a binary that prints the 30th Fibonacci number.</p>
|
||||
<p>The file <a href="ghcfib.hs">ghcfib.hs</a> includes <a href="fib.hs">fib.hs</a> with some glue code,
|
||||
and shows GHC also accepts our subset of Haskell:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">ghc</span> ghcfib.hs</span></code></pre></div>
|
||||
<h4 id="self-hosting-compiler">Self-hosting compiler:</h4>
|
||||
<p>To avoid spoiling this entry by revealing the original Haskell
|
||||
source, we instead provide <a href="hint.hs">hint.hs</a>, the output of
|
||||
a certain stage of the compiler when run on itself. This intermediate
|
||||
output is hopefully difficult to understand, yet is accepted by our
|
||||
compiler:</p>
|
||||
<p>To avoid spoiling this entry by revealing the original Haskell source, we
|
||||
instead provide <a href="hint.hs">hint.hs</a>, the output of a certain stage of the
|
||||
compiler when run on itself. This intermediate output is hopefully difficult to
|
||||
understand, yet is accepted by our compiler:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">(</span><span class="ex">./prog</span> <span class="op"><</span> hint.hs <span class="kw">;</span> <span class="fu">cat</span> prog.c<span class="kw">)</span> <span class="op">></span> hint.c</span>
|
||||
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> hint</span>
|
||||
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="ex">./hint</span></span></code></pre></div>
|
||||
<p>The output program behaves like the compiler itself.</p>
|
||||
<p>Unlike the original source from which it is derived, GHC fails to
|
||||
compile <a href="hint.hs">hint.hs</a>. This is because values have been
|
||||
replaced with their <a
|
||||
href="https://en.wikipedia.org/wiki/Mogensen-Scott_encoding">Scott
|
||||
encodings</a> by this stage, which messes up type-checks; we’d need
|
||||
<code>equirecursive</code> types for it to work.</p>
|
||||
<p>Unlike the original source from which it is derived, GHC fails to compile
|
||||
<a href="hint.hs">hint.hs</a>. This is because values have been replaced with their <a href="https://en.wikipedia.org/wiki/Mogensen-Scott_encoding">Scott
|
||||
encodings</a>
|
||||
by this stage, which messes up type-checks; we’d need <code>equirecursive</code> types for
|
||||
it to work.</p>
|
||||
<h4 id="regexes">Regexes:</h4>
|
||||
<p>The file <a href="lol.hs">lol.hs</a> contains an adaptation of <a
|
||||
href="https://www.cs.dartmouth.edu/~doug/nfa.pdf">Doug McIlroy’s elegant
|
||||
code from “Enumerating the strings of regular languages”</a>. We
|
||||
exercise it by showing the first entries of the length-ordered list of
|
||||
all strings consisting of the characters <code>a</code> and
|
||||
<code>b</code> that contain an even number of <code>a</code>s.</p>
|
||||
<p>The file <a href="lol.hs">lol.hs</a> contains an adaptation of <a href="https://www.cs.dartmouth.edu/~doug/nfa.pdf">Doug McIlroy’s elegant code from
|
||||
“Enumerating the strings of regular
|
||||
languages”</a>. We exercise it by
|
||||
showing the first entries of the length-ordered list of all strings consisting
|
||||
of the characters <code>a</code> and <code>b</code> that contain an even number of <code>a</code>s.</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">(</span><span class="ex">./prog</span> <span class="op"><</span> lol.hs <span class="kw">;</span> <span class="fu">cat</span> prog.c<span class="kw">)</span> <span class="op">></span> lol.c</span>
|
||||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> lol</span>
|
||||
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ex">./lol</span></span></code></pre></div>
|
||||
<p>A GHC wrapper is provided:</p>
|
||||
<div class="sourceCode" id="cb10"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">ghc</span> ghclol.hs</span></code></pre></div>
|
||||
<h3 id="strongly-connected-components">Strongly-connected
|
||||
components:</h3>
|
||||
<p>See <a href="scc.hs">scc.hs</a> (and its GHC wrapper <a
|
||||
href="ghcscc.hs">ghcscc.hs</a>) for an elegant way to print the
|
||||
strongly-connected components of a graph in reverse topological
|
||||
<div class="sourceCode" id="cb10"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">ghc</span> ghclol.hs</span></code></pre></div>
|
||||
<h3 id="strongly-connected-components">Strongly-connected components:</h3>
|
||||
<p>See <a href="scc.hs">scc.hs</a> (and its GHC wrapper <a href="ghcscc.hs">ghcscc.hs</a>) for an elegant
|
||||
way to print the strongly-connected components of a graph in reverse topological
|
||||
order.</p>
|
||||
<div class="sourceCode" id="cb11"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">(</span><span class="ex">./prog</span> <span class="op"><</span> scc.hs <span class="kw">;</span> <span class="fu">cat</span> prog.c<span class="kw">)</span> <span class="op">></span> scc.c</span></code></pre></div>
|
||||
<div class="sourceCode" id="cb11"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">(</span><span class="ex">./prog</span> <span class="op"><</span> scc.hs <span class="kw">;</span> <span class="fu">cat</span> prog.c<span class="kw">)</span> <span class="op">></span> scc.c</span></code></pre></div>
|
||||
<p>It expects the input to be in a similar format as a previous entry
|
||||
(2018 vokes). For example:</p>
|
||||
<div class="sourceCode" id="cb12"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> scc</span>
|
||||
<div class="sourceCode" id="cb12"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> scc</span>
|
||||
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="ex">./scc</span> <span class="op"><</span> example-1.txt</span>
|
||||
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="ex">./scc</span> <span class="op"><</span> example-2.txt</span></code></pre></div>
|
||||
<p>The output should agree, though our program omits line numbers and
|
||||
does not sort entries within a line. (Also, our program only treats
|
||||
spaces as whitespace, and supports any non-space character in a vertex
|
||||
name.)</p>
|
||||
<p>The output should agree, though our program omits line numbers and does not
|
||||
sort entries within a line. (Also, our program only treats spaces as
|
||||
whitespace, and supports any non-space character in a vertex name.)</p>
|
||||
<h3 id="syntax">Syntax</h3>
|
||||
<p>Some claim Haskell syntax is frightening because braces and
|
||||
semicolons are optional. Some complain about a zoo of twisty little
|
||||
operators, all alike. Our compiler addresses such concerns by making
|
||||
braces and semicolons compulsory, disabling layout-based rules, making
|
||||
every operator left-associative with same precedence, and only defining
|
||||
6 primitive functions:</p>
|
||||
<p>Some claim Haskell syntax is frightening because braces and semicolons are
|
||||
optional. Some complain about a zoo of twisty little operators, all alike. Our
|
||||
compiler addresses such concerns by making braces and semicolons compulsory,
|
||||
disabling layout-based rules, making every operator left-associative with same
|
||||
precedence, and only defining 6 primitive functions:</p>
|
||||
<pre><code>: + - * / <=</code></pre>
|
||||
<p>The arithmetic operations behave as they do in C on
|
||||
<code>unsigned int</code>s, and <code>(:)</code> is Haskell’s
|
||||
<code>cons</code> function. Like Haskell and unlike C,
|
||||
<code>(<=)</code> returns a <code>Bool</code> (which are Church
|
||||
booleans behind the scenes) and not an <code>Int</code>.</p>
|
||||
<p>No ifs, ands, or buts. Define them yourself. No tuples. Who needs
|
||||
them when algebraic data types delivers a better product? There is no
|
||||
do. No where. No list comprehensions. No unary operators.</p>
|
||||
<p>The arithmetic operations behave as they do in C on <code>unsigned int</code>s, and <code>(:)</code> is
|
||||
Haskell’s <code>cons</code> function. Like Haskell and unlike C, <code>(<=)</code> returns a <code>Bool</code>
|
||||
(which are Church booleans behind the scenes) and not an <code>Int</code>.</p>
|
||||
<p>No ifs, ands, or buts. Define them yourself. No tuples. Who needs them when
|
||||
algebraic data types delivers a better product? There is no do. No where. No
|
||||
list comprehensions. No unary operators.</p>
|
||||
<p>Let expressions and operator sections are supported.</p>
|
||||
<p>Within global scope or a let expression, each definition can only
|
||||
refer to itself or previous definitions. This implies we can only
|
||||
achieve mutual recursion by having one function pass itself to
|
||||
others.</p>
|
||||
<p>Within global scope or a let expression, each definition can only refer to
|
||||
itself or previous definitions. This implies we can only achieve mutual
|
||||
recursion by having one function pass itself to others.</p>
|
||||
<h3 id="caveats">Caveats</h3>
|
||||
<p>The only primitive type is <code>Int</code>. In particular, they
|
||||
represent characters. To interoperate with GHC, our compiler treats any
|
||||
undefined functions as the <code>identity</code> function, so that we
|
||||
may freely use <code>ord</code> and <code>chr</code> (or
|
||||
<code>fromEnum</code> and <code>toEnum</code>) to make our code
|
||||
acceptable to both compilers.</p>
|
||||
<p>The main function is the last function to successfully parse. It
|
||||
should have type <code>[Int] -> [Int]</code>, and our compiler treats
|
||||
this like the function passed into <code>Prelude.interact</code>, that
|
||||
is, the entire standard input is passed to this function, and the result
|
||||
is printed to standard output.</p>
|
||||
<p>The only primitive type is <code>Int</code>. In particular, they represent characters. To
|
||||
interoperate with GHC, our compiler treats any undefined functions as the
|
||||
<code>identity</code> function, so that we may freely use <code>ord</code> and <code>chr</code> (or <code>fromEnum</code> and
|
||||
<code>toEnum</code>) to make our code acceptable to both compilers.</p>
|
||||
<p>The main function is the last function to successfully parse. It should have
|
||||
type <code>[Int] -> [Int]</code>, and our compiler treats this like the function passed
|
||||
into <code>Prelude.interact</code>, that is, the entire standard input is passed to this
|
||||
function, and the result is printed to standard output.</p>
|
||||
<p><code>Bool</code> must be defined as:</p>
|
||||
<pre><code>data Bool = True | False;</code></pre>
|
||||
<p>so that it matches the Scott-encoded booleans internally used by the
|
||||
primitive function <code>(<=)</code>.</p>
|
||||
<p>The alternatives in a <code>case</code> expressions must list every
|
||||
data constructor in the order they are defined. For example, if we
|
||||
have:</p>
|
||||
<p>so that it matches the Scott-encoded booleans internally used by the primitive
|
||||
function <code>(<=)</code>.</p>
|
||||
<p>The alternatives in a <code>case</code> expressions must list every data constructor in
|
||||
the order they are defined. For example, if we have:</p>
|
||||
<pre><code>data Foo a b = Bar a | Baz | Qux Int [b]</code></pre>
|
||||
<p>then a <code>case</code> expression that examines a term of this type
|
||||
must have the form:</p>
|
||||
<p>then a <code>case</code> expression that examines a term of this type must have the form:</p>
|
||||
<pre><code>case x of
|
||||
{ Bar a -> ...
|
||||
; Baz -> ...
|
||||
@@ -282,169 +258,120 @@ must have the form:</p>
|
||||
}</code></pre>
|
||||
<p>We stress braces and semicolons are required. Our fussy parser treats
|
||||
semicolons as separators, not terminators.</p>
|
||||
<p>The effect of erroneous input is undefined. It may be best to develop
|
||||
with GHC, but even then, be mindful of changes needed because of issues
|
||||
caused by the uniform operator precedence and the touchy format of
|
||||
<code>case</code> alternatives.</p>
|
||||
<p>The effect of erroneous input is undefined. It may be best to develop with GHC,
|
||||
but even then, be mindful of changes needed because of issues caused by the
|
||||
uniform operator precedence and the touchy format of <code>case</code> alternatives.</p>
|
||||
<h3 id="why">Why?</h3>
|
||||
<p>One-letter variable names abound in IOCCC entries, and for good
|
||||
reason. These tiny pieces of confetti are hard to read, and leave room
|
||||
for more code. Then why not go further and use zero-letter variable
|
||||
names? That is, tacit programming or point-free style.</p>
|
||||
<p>I had been playing with an algorithm devised by Oleg Kiselyov that
|
||||
effortlessly and efficiently eliminates those pesky variables, leaving
|
||||
behind terms composed from a small set of combinators. No need for
|
||||
lambda lifting or supercombinators.</p>
|
||||
<p>By adding a handful of lines of mostly parsing code, we get a Haskell
|
||||
compiler, or rather, a compiler that accepts a subset of Haskell
|
||||
sufficiently large to self-host. You might say I wrote a tool for this
|
||||
contest, then ran it on itself to make an entry for it.</p>
|
||||
<p>One-letter variable names abound in IOCCC entries, and for good reason. These
|
||||
tiny pieces of confetti are hard to read, and leave room for more code. Then
|
||||
why not go further and use zero-letter variable names? That is, tacit
|
||||
programming or point-free style.</p>
|
||||
<p>I had been playing with an algorithm devised by Oleg Kiselyov that effortlessly
|
||||
and efficiently eliminates those pesky variables, leaving behind terms composed
|
||||
from a small set of combinators. No need for lambda lifting or supercombinators.</p>
|
||||
<p>By adding a handful of lines of mostly parsing code, we get a Haskell compiler,
|
||||
or rather, a compiler that accepts a subset of Haskell sufficiently large to
|
||||
self-host. You might say I wrote a tool for this contest, then ran it on itself
|
||||
to make an entry for it.</p>
|
||||
<h3 id="obfuscation-techniques">Obfuscation techniques:</h3>
|
||||
<p>Even with Kiselyov’s algorithm and some term rewriting, the compiler
|
||||
only fit after compression, which naturally obfuscates the code. More
|
||||
tricks were needed to fit within the size limits.</p>
|
||||
<p>Even with Kiselyov’s algorithm and some term rewriting, the compiler only fit
|
||||
after compression, which naturally obfuscates the code. More tricks were needed
|
||||
to fit within the size limits.</p>
|
||||
<ul>
|
||||
<li>One-letter variables, until enough is done to banish variables
|
||||
completely.</li>
|
||||
<li>Ipse dixit. Near the end, the code declares itself to be an
|
||||
obfuscated program. (There is also an exhortation intended for the
|
||||
judges in a similar format earlier in the source.)</li>
|
||||
<li>Typical C mischief: pre- and post-increment, commutative array
|
||||
indexing, ternary operators, and so on.</li>
|
||||
<li>One-letter variables, until enough is done to banish variables completely.</li>
|
||||
<li>Ipse dixit. Near the end, the code declares itself to be an obfuscated
|
||||
program. (There is also an exhortation intended for the judges in a similar
|
||||
format earlier in the source.)</li>
|
||||
<li>Typical C mischief: pre- and post-increment, commutative array indexing,
|
||||
ternary operators, and so on.</li>
|
||||
<li>Huffman coding.</li>
|
||||
<li>Base-85 because high bits are frowned upon.</li>
|
||||
<li>Mixed radix encoding to game iocccsize. From a past entry (<a
|
||||
href="../../2018/bellard/index.html">2018/bellard</a>), it seems 9 11 12
|
||||
32 are the only whitespace octets that may appear verbatim in string
|
||||
literals.</li>
|
||||
<li>Choosing what to encode in Huffman/base-85 and what to encode in
|
||||
mixed radix was a delicate balancing act. In the end, I only had a few
|
||||
bytes to spare, which I spent on gratuitous confusion.</li>
|
||||
<li>The effects of some functions depend on the order their arguments
|
||||
are evaluated, yet the program works either way. Why?</li>
|
||||
<li>Ugly macros for the runtime system’s jump table for lazy reduction.
|
||||
A previous entry (<a
|
||||
href="../../2013/endoh1/index.html">2013/endoh1</a>) has a cuter
|
||||
solution, which I avoid because of originality concerns and also because
|
||||
my combinators are compressed.</li>
|
||||
<li>Mixed radix encoding to game iocccsize. From a past entry
|
||||
(<a href="../../2018/bellard/index.html">2018/bellard</a>), it seems 9 11 12 32 are the only
|
||||
whitespace octets that may appear verbatim in string literals.</li>
|
||||
<li>Choosing what to encode in Huffman/base-85 and what to encode in mixed radix
|
||||
was a delicate balancing act. In the end, I only had a few bytes to spare, which
|
||||
I spent on gratuitous confusion.</li>
|
||||
<li>The effects of some functions depend on the order their arguments are
|
||||
evaluated, yet the program works either way. Why?</li>
|
||||
<li>Ugly macros for the runtime system’s jump table for lazy reduction. A previous
|
||||
entry (<a href="../../2013/endoh1/index.html">2013/endoh1</a>) has a cuter solution, which I
|
||||
avoid because of originality concerns and also because my combinators are
|
||||
compressed.</li>
|
||||
<li>Relies on the inability of C comments to nest.</li>
|
||||
<li>Cheaper and more complicated to print comma-separated
|
||||
<code>int</code>s (and header and footer) in C.</li>
|
||||
<li>Primitive functions use a trick described in depth by <a
|
||||
href="https://www.cs.york.ac.uk/fp/reduceron/jfp-reduceron.pdf">Naylor
|
||||
and Runciman, “The Reduceron reconfigured and re-evaluated”</a>. We
|
||||
represent the integer <code>n</code> with a term equivalent to
|
||||
<code>Y(BT)n</code>; it works because
|
||||
<li>Cheaper and more complicated to print comma-separated <code>int</code>s (and header and
|
||||
footer) in C.</li>
|
||||
<li>Primitive functions use a trick described in depth by <a href="https://www.cs.york.ac.uk/fp/reduceron/jfp-reduceron.pdf">Naylor and Runciman,
|
||||
“The Reduceron reconfigured and
|
||||
re-evaluated”</a>. We
|
||||
represent the integer <code>n</code> with a term equivalent to <code>Y(BT)n</code>; it works because
|
||||
<code>Y(BT)ne = e(Y(BT)n)</code>.</li>
|
||||
<li>A sentinel in the heap often confused me, so ought to confuse
|
||||
others.</li>
|
||||
<li>A sentinel in the heap often confused me, so ought to confuse others.</li>
|
||||
</ul>
|
||||
<p>Other obfuscation techniques are better appreciated after decoding
|
||||
the compiler. See <a href="hint.hs">hint.hs</a>.</p>
|
||||
<p>Other obfuscation techniques are better appreciated after decoding the
|
||||
compiler. See <a href="hint.hs">hint.hs</a>.</p>
|
||||
<ul>
|
||||
<li>Mercilessly point-free. Everything is a combinator.</li>
|
||||
<li>Scott encoding. Everything is a combinator.</li>
|
||||
<li>Sum types are oddly ordered and may even contain unused data
|
||||
constructors to reduce code duplication. (In C terms,
|
||||
<code>union</code>s may have extra fields, and they’re ordered in such a
|
||||
way so we can reuse code to access certain fields.)</li>
|
||||
<li>The <code>undefined</code> function compiles to the <code>(.)</code>
|
||||
function.</li>
|
||||
<li>Replaced the only <code>(&&)</code> with <code>(||)</code>
|
||||
and <code>not</code> using De Morgan’s law, which makes some comparisons
|
||||
less comprehensible.</li>
|
||||
<li><a href="http://okmij.org/ftp/tagless-final/ski.pdf">Kiselyov only
|
||||
published “λ to SKI, Semantically” last year</a>.</li>
|
||||
<li>Recursion via the fixpoint (<code>Y</code>) combinator, which is
|
||||
represented by the variable <code>""</code> during one stage of
|
||||
compilation.</li>
|
||||
<li>Involves theory that may be less familiar to C programmers: maps,
|
||||
folds, parser combinators, lambda calculus, bracket abstraction,
|
||||
denotational semantics, etc.</li>
|
||||
<li>Sum types are oddly ordered and may even contain unused data constructors to
|
||||
reduce code duplication. (In C terms, <code>union</code>s may have extra fields, and they’re
|
||||
ordered in such a way so we can reuse code to access certain fields.)</li>
|
||||
<li>The <code>undefined</code> function compiles to the <code>(.)</code> function.</li>
|
||||
<li>Replaced the only <code>(&&)</code> with <code>(||)</code> and <code>not</code> using De Morgan’s law, which
|
||||
makes some comparisons less comprehensible.</li>
|
||||
<li><a href="http://okmij.org/ftp/tagless-final/ski.pdf">Kiselyov only published “λ to SKI, Semantically” last
|
||||
year</a>.</li>
|
||||
<li>Recursion via the fixpoint (<code>Y</code>) combinator, which is represented by the
|
||||
variable <code>""</code> during one stage of compilation.</li>
|
||||
<li>Involves theory that may be less familiar to C programmers: maps, folds,
|
||||
parser combinators, lambda calculus, bracket abstraction, denotational
|
||||
semantics, etc.</li>
|
||||
</ul>
|
||||
<h3 id="warnings">Warnings:</h3>
|
||||
<p>On my system, it compiles cleanly with <code>-Wall</code> with older
|
||||
standards, e.g. <code>-std=c89</code>, but less cleanly if
|
||||
<code>-pedantic</code> is also supplied.</p>
|
||||
<p>Compiling the compiler output with <code>-Wall</code> triggers a
|
||||
warning about a strange-looking comment.</p>
|
||||
<p>On my system, it compiles cleanly with <code>-Wall</code> with older standards, e.g.
|
||||
<code>-std=c89</code>, but less cleanly if <code>-pedantic</code> is also supplied.</p>
|
||||
<p>Compiling the compiler output with <code>-Wall</code> triggers a warning about a
|
||||
strange-looking comment.</p>
|
||||
<h3 id="behind-the-scenes-commentary">Behind-the-scenes commentary:</h3>
|
||||
<p><a href="https://crypto.stanford.edu/~blynn/compiler/ioccc.html">My
|
||||
website reveals how this compiler works</a>.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<p><a href="https://crypto.stanford.edu/~blynn/compiler/ioccc.html">My website reveals how this compiler
|
||||
works</a>.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019lynn"><a name="inventory"></a>Inventory for
|
||||
2019/lynn</h1>
|
||||
<h1 id="inventory-for-2019lynn"><a name="inventory"></a>Inventory for 2019/lynn</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/example-1.txt">example-1.txt</a>
|
||||
- sample input</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/example-2.txt">example-2.txt</a>
|
||||
- sample input</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/fib.hs">fib.hs</a>
|
||||
- compiler macros</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/ghcfib.hs">ghcfib.hs</a>
|
||||
- compiler macros</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/ghclol.hs">ghclol.hs</a>
|
||||
- compiler macros</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/ghcscc.hs">ghcscc.hs</a>
|
||||
- compiler macros</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/lol.hs">lol.hs</a>
|
||||
- compiler macros</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/scc.hs">scc.hs</a>
|
||||
- compiler macros</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/hint.hs">hint.hs</a>
|
||||
- spoiler for compiler macros</li>
|
||||
<li><a href="2019_lynn.tar.bz2">2019_lynn.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/example-1.txt">example-1.txt</a> - sample input</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/example-2.txt">example-2.txt</a> - sample input</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/fib.hs">fib.hs</a> - compiler macros</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/ghcfib.hs">ghcfib.hs</a> - compiler macros</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/ghclol.hs">ghclol.hs</a> - compiler macros</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/ghcscc.hs">ghcscc.hs</a> - compiler macros</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/lol.hs">lol.hs</a> - compiler macros</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/scc.hs">scc.hs</a> - compiler macros</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/hint.hs">hint.hs</a> - spoiler for compiler macros</li>
|
||||
<li><a href="2019_lynn.tar.bz2">2019_lynn.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/lynn/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+296
-441
@@ -129,9 +129,9 @@
|
||||
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Christopher_Mills">Christopher
|
||||
Mills</a><br> Location: <a href="../../location.html#US">US</a> -
|
||||
<em>United States of America</em> (<em>United States</em>) <br><br></li>
|
||||
<li>Name: <a href="../../authors.html#Christopher_Mills">Christopher Mills</a><br>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -144,88 +144,65 @@ Mills</a><br> Location: <a href="../../location.html#US">US</a> -
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_mills">2019 mills bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_mills">2019 mills bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> cpclean</span>
|
||||
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="co"># Let this run for about about an hour and then kill it:</span></span>
|
||||
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> Shakespeare.txt</span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<p>However, as the binary model files used to produce the output are in
|
||||
an implementation-specific format, your mileage may vary.</p>
|
||||
<p>However, as the binary model files used to produce the output are in an
|
||||
implementation-specific format, your mileage may vary.</p>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Can a machine learn?</p>
|
||||
<p>Some say so.</p>
|
||||
<p>But can a machine learn to write like Shakespeare? Can it write rules
|
||||
and guidelines for the IOCCC?</p>
|
||||
<p>But can a machine learn to write like Shakespeare? Can it write rules and
|
||||
guidelines for the IOCCC?</p>
|
||||
<p>You decide. :-)</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="welcome-to-omlet">Welcome to OMLET! 🍳:</h3>
|
||||
<p>OMLET is the <em>Obfuscated Machine Learning Environment
|
||||
Toolkit</em>, a micro-framework for experimenting with <a
|
||||
href="https://en.wikipedia.org/wiki/Recurrent_neural_network">recurrent
|
||||
neural networks</a> (RNN). OMLET lets you build, train and evaluate <a
|
||||
href="https://en.wikipedia.org/wiki/Deep_learning">deep neural
|
||||
networks</a> (DNN). Why invest hours reading documentation and megabytes
|
||||
of disk space on a full-featured DNN framework like <a
|
||||
href="https://www.tensorflow.org">TensorFlow</a> or <a
|
||||
href="http://torch.ch">Torch</a> when you can have full RNN
|
||||
functionality in less than 4 KB!</p>
|
||||
<p>OMLET is the <em>Obfuscated Machine Learning Environment Toolkit</em>, a
|
||||
micro-framework for experimenting with <a href="https://en.wikipedia.org/wiki/Recurrent_neural_network">recurrent neural networks</a> (RNN).
|
||||
OMLET lets you build, train and evaluate <a href="https://en.wikipedia.org/wiki/Deep_learning">deep neural networks</a> (DNN). Why
|
||||
invest hours reading documentation and megabytes of disk space on a
|
||||
full-featured DNN framework like <a href="https://www.tensorflow.org">TensorFlow</a> or <a href="http://torch.ch">Torch</a> when you can have
|
||||
full RNN functionality in less than 4 KB!</p>
|
||||
<p>OMLET has the following features:</p>
|
||||
<ul>
|
||||
<li>User-programmable network configurations and hyperparameters.</li>
|
||||
<li>Support for various types of recurrent and feed-forward neural
|
||||
networks including vanilla RNNs, LSTMs and GRUs of depths of up to 99
|
||||
layers.</li>
|
||||
<li>No limit on parameter size (except for those imposed by the
|
||||
system).</li>
|
||||
<li>Support for various types of recurrent and feed-forward neural networks
|
||||
including vanilla RNNs, LSTMs and GRUs of depths of up to 99 layers.</li>
|
||||
<li>No limit on parameter size (except for those imposed by the system).</li>
|
||||
<li>Training and inference modes, with periodic checkpointing.</li>
|
||||
<li>Advanced <a href="https://arxiv.org/abs/1412.6980">Adam</a>
|
||||
optimizer with <a
|
||||
href="https://www.fast.ai/2018/07/02/adam-weight-decay/">weight
|
||||
decay</a> for simplified training.</li>
|
||||
<li>Hyperparameters support for batch sizing, learning rate schedule,
|
||||
weight decay and gradient clipping.</li>
|
||||
<li>Easily extensible (requires some expertise in the C programming
|
||||
language).</li>
|
||||
<li>Advanced <a href="https://arxiv.org/abs/1412.6980">Adam</a> optimizer with <a href="https://www.fast.ai/2018/07/02/adam-weight-decay/">weight decay</a> for simplified
|
||||
training.</li>
|
||||
<li>Hyperparameters support for batch sizing, learning rate schedule, weight
|
||||
decay and gradient clipping.</li>
|
||||
<li>Easily extensible (requires some expertise in the C programming language).</li>
|
||||
<li>Friendly markdown documentation.</li>
|
||||
</ul>
|
||||
<p>OMLET is based on <a href="https://karpathy.ai">Andrej Karpathy’s</a>
|
||||
<a href="https://github.com/karpathy/char-rnn">character-level language
|
||||
model</a> as described in his blog post <a
|
||||
href="http://karpathy.github.io/2015/05/21/rnn-effectiveness/"><em>The
|
||||
Unreasonable Effectiveness of Recurrent Neural Networks</em></a>. I’ve
|
||||
included a small sample dataset to use for training, but you can have
|
||||
even more fun by downloading some larger datasets:</p>
|
||||
<p>OMLET is based on <a href="https://karpathy.ai">Andrej Karpathy’s</a> <a href="https://github.com/karpathy/char-rnn">character-level language model</a>
|
||||
as described in his blog post <a href="http://karpathy.github.io/2015/05/21/rnn-effectiveness/"><em>The Unreasonable Effectiveness of Recurrent
|
||||
Neural Networks</em></a>. I’ve included a small sample dataset to use for
|
||||
training, but you can have even more fun by downloading some larger datasets:</p>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://cs.stanford.edu/people/karpathy/char-rnn/linux_input.txt">Linux
|
||||
kernel source</a></li>
|
||||
<li><a
|
||||
href="https://cs.stanford.edu/people/karpathy/char-rnn/warpeace_input.txt"><em>War
|
||||
and Peace</em></a></li>
|
||||
<li><a href="https://github.com/ryanmcdermott/trump-speeches">Donald
|
||||
Trump’s 2016 campaign speeches</a></li>
|
||||
<li><a href="https://cs.stanford.edu/people/karpathy/char-rnn/linux_input.txt">Linux kernel source</a></li>
|
||||
<li><a href="https://cs.stanford.edu/people/karpathy/char-rnn/warpeace_input.txt"><em>War and Peace</em></a></li>
|
||||
<li><a href="https://github.com/ryanmcdermott/trump-speeches">Donald Trump’s 2016 campaign speeches</a></li>
|
||||
</ul>
|
||||
<h3 id="getting-started-with-omlet">Getting started with OMLET</h3>
|
||||
<p>OMLET has three operating modes:</p>
|
||||
<ul>
|
||||
<li><em>Training</em>, which trains a network from scratch.</li>
|
||||
<li><em>Continuation</em>, which trains starting from an existing
|
||||
checkpoint.</li>
|
||||
<li><em>Inference</em>, which uses an existing trained network to make
|
||||
predictions.</li>
|
||||
<li><em>Continuation</em>, which trains starting from an existing checkpoint.</li>
|
||||
<li><em>Inference</em>, which uses an existing trained network to make predictions.</li>
|
||||
</ul>
|
||||
<p>For your first OMLET experiment, we will try training a simple
|
||||
single-level RNN to write some <a
|
||||
href="https://en.wikipedia.org/wiki/William_Shakespeare">Shakespeare</a>
|
||||
plays. Start by typing</p>
|
||||
<p>For your first OMLET experiment, we will try training a simple single-level
|
||||
RNN to write some <a href="https://en.wikipedia.org/wiki/William_Shakespeare">Shakespeare</a> plays. Start by typing</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>After it builds, train it using</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> Shakespere.txt</span></code></pre></div>
|
||||
<p>This will immediately start outputting gibberish to the output,
|
||||
e.g.</p>
|
||||
<p>This will immediately start outputting gibberish to the output, e.g.</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> Shakespere.txt</span></code></pre></div>
|
||||
<p>produces:</p>
|
||||
<pre><code>sins ohennAu
|
||||
@@ -260,14 +237,13 @@ Vh th no dh foud bobt werw:s Aotnf Fhwi't whe, eusu
|
||||
lhh thele wewcond ary soupfy wind tDont couc ths:
|
||||
er fucwald oncli hen bos, f
|
||||
T0:1% 2.878945</code></pre>
|
||||
<p>The gibberish is the networks attempt to write a play. So far, it’s
|
||||
not very successful! Between the chunks of gibberish are training
|
||||
progress reports that look like</p>
|
||||
<p>The gibberish is the networks attempt to write a play. So far, it’s not very
|
||||
successful! Between the chunks of gibberish are training progress reports
|
||||
that look like</p>
|
||||
<pre><code>T0:1% 2.878945</code></pre>
|
||||
<p>This tells you that we are 1% through training epoch 0, and that the
|
||||
training <a href="https://en.wikipedia.org/wiki/Loss_function">loss</a>
|
||||
is about 2.88. As the training continues, the training loss will reduce
|
||||
and the generated snippets will improve quickly:</p>
|
||||
<p>This tells you that we are 1% through training epoch 0, and that the training
|
||||
<a href="https://en.wikipedia.org/wiki/Loss_function">loss</a> is about 2.88. As the training continues, the training loss will
|
||||
reduce and the generated snippets will improve quickly:</p>
|
||||
<pre><code>ses, kuth
|
||||
LAs of the wish,
|
||||
As, I nos you,
|
||||
@@ -293,12 +269,12 @@ rerytund: tich lon hyivetetgor.
|
||||
VOLUONIA:
|
||||
He brich nom dove worthan then wise,
|
||||
T0:13% 2.254926</code></pre>
|
||||
<p>It’s already started to figure out things about Shakespeare plays –
|
||||
how to spell short English words, how long lines tend to be, and that
|
||||
characters take turns speaking with their names capitalized. The
|
||||
training loss has dropped to 2.25 and the improvement is noticeable.</p>
|
||||
<p>Eventually, we will finish with the training data set and move on to
|
||||
a validation cycle:</p>
|
||||
<p>It’s already started to figure out things about Shakespeare plays – how to
|
||||
spell short English words, how long lines tend to be, and that characters take
|
||||
turns speaking with their names capitalized. The training loss has dropped to
|
||||
2.25 and the improvement is noticeable.</p>
|
||||
<p>Eventually, we will finish with the training data set and move on to a
|
||||
validation cycle:</p>
|
||||
<pre><code>y fath onother,
|
||||
I sucess,
|
||||
For I me the west crare.
|
||||
@@ -333,58 +309,49 @@ Willerity.
|
||||
|
||||
First Cumfol of
|
||||
T1:0% 1.885619</code></pre>
|
||||
<p>Validation cycles are used to test the network to see if it has
|
||||
learned to generalize – how well it performs on data it hasn’t seen
|
||||
before (as opposed to the training data that the network will see many
|
||||
times as it trains). Progress on the validation set is also displayed
|
||||
with a validation progress report that looks like</p>
|
||||
<p>Validation cycles are used to test the network to see if it has learned to
|
||||
generalize – how well it performs on data it hasn’t seen before (as opposed to
|
||||
the training data that the network will see many times as it trains). Progress
|
||||
on the validation set is also displayed with a validation progress report that
|
||||
looks like</p>
|
||||
<pre><code>V0:36% 1.716672</code></pre>
|
||||
<p>which means we are 36% of the way through the validation for epoch 0,
|
||||
and the validation loss is about 1.72. Comparing the validation loss and
|
||||
the training loss will give you an idea of how well the network is
|
||||
learning and can let you know if the network is <a
|
||||
href="https://en.wikipedia.org/wiki/Overfitting">overfitting or
|
||||
underfitting</a>.</p>
|
||||
<p>which means we are 36% of the way through the validation for epoch 0, and the
|
||||
validation loss is about 1.72. Comparing the validation loss and the
|
||||
training loss will give you an idea of how well the network is learning and
|
||||
can let you know if the network is <a href="https://en.wikipedia.org/wiki/Overfitting">overfitting or underfitting</a>.</p>
|
||||
<p>As part of the training process, the data set (which for OMLET is the
|
||||
<a href="Shakespeare.txt">Shakespeare.txt</a> file you gave on the
|
||||
command line) is divided into <a
|
||||
href="https://en.wikipedia.org/wiki/Training,_validation,_and_test_sets">training
|
||||
and validation sets</a> (by default, 95% of the data is used for
|
||||
training, but like most OMLET parameters, you can change this at
|
||||
compile-time).</p>
|
||||
<p>At the end of the validation run, OMLET writes out a checkpoint file
|
||||
with a name like <code>cp01_1.970</code>. This saves the state of the
|
||||
run at the start of the epoch 1, after computing a validation loss of
|
||||
1.970. The checkpoint is helpful if you need to stop and restart
|
||||
training. You can stop training by doing <code>Control-C</code>.</p>
|
||||
<a href="Shakespeare.txt">Shakespeare.txt</a> file you gave on the command line) is divided into
|
||||
<a href="https://en.wikipedia.org/wiki/Training,_validation,_and_test_sets">training and validation sets</a> (by default, 95% of the data is used for
|
||||
training, but like most OMLET parameters, you can change this at compile-time).</p>
|
||||
<p>At the end of the validation run, OMLET writes out a checkpoint file with a
|
||||
name like <code>cp01_1.970</code>. This saves the state of the run at the start of the
|
||||
epoch 1, after computing a validation loss of 1.970. The checkpoint is
|
||||
helpful if you need to stop and restart training. You can stop training by
|
||||
doing <code>Control-C</code>.</p>
|
||||
<p>You can continue training from a previous checkpoint by providing the
|
||||
checkpoint file name as the second parameter, for example:</p>
|
||||
<div class="sourceCode" id="cb13"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> Shakespeare.txt cp01_1.970</span></code></pre></div>
|
||||
<p>After the validation cycle finishes, OMLET begins the next epoch by
|
||||
restarting training at the beginning of the training set. Training
|
||||
continues forever, until you quit it with <code>Control-C</code>. You
|
||||
should monitor the checkpoints to see that the validation loss continues
|
||||
to drop. If it rises, the network has probably started to overfit on the
|
||||
training data.</p>
|
||||
<p>Once you’ve trained the validation loss as low as it will go, you can
|
||||
use OMLET to run the network in inference mode which uses the frozen
|
||||
checkpoint parameters to generate data. Inference mode takes the
|
||||
checkpoint file as <em>standard input</em> (not on the command line) and
|
||||
hence must be run with a command like</p>
|
||||
<div class="sourceCode" id="cb14"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> cp55_1.807</span></code></pre></div>
|
||||
<p>Running it produces an infinite amount of generated output, until you
|
||||
hit <code>Control-C</code> to stop it.</p>
|
||||
<p>Note that if you decide to change networks or use a different input
|
||||
file, you will want to delete all the checkpoint files because the
|
||||
format depends on both the network and the input – using the wrong
|
||||
checkpoint is likely to cause a crash.</p>
|
||||
<h3 id="experimenting-with-different-networks">Experimenting with
|
||||
different networks</h3>
|
||||
<p>The default network for OMLET (the one you get if you type
|
||||
<code>make</code> with the executable name <code>prog</code>) is the
|
||||
simplest recurrent neural network. It looks like</p>
|
||||
<div class="sourceCode" id="cb13"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> Shakespeare.txt cp01_1.970</span></code></pre></div>
|
||||
<p>After the validation cycle finishes, OMLET begins the next epoch by restarting
|
||||
training at the beginning of the training set. Training continues forever,
|
||||
until you quit it with <code>Control-C</code>. You should monitor the checkpoints to
|
||||
see that the validation loss continues to drop. If it rises, the network has
|
||||
probably started to overfit on the training data.</p>
|
||||
<p>Once you’ve trained the validation loss as low as it will go, you can use
|
||||
OMLET to run the network in inference mode which uses the frozen checkpoint
|
||||
parameters to generate data. Inference mode takes the checkpoint file as
|
||||
<em>standard input</em> (not on the command line) and hence must be run with a
|
||||
command like</p>
|
||||
<div class="sourceCode" id="cb14"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> cp55_1.807</span></code></pre></div>
|
||||
<p>Running it produces an infinite amount of generated output, until you hit
|
||||
<code>Control-C</code> to stop it.</p>
|
||||
<p>Note that if you decide to change networks or use a different input file, you
|
||||
will want to delete all the checkpoint files because the format depends on
|
||||
both the network and the input – using the wrong checkpoint is likely to
|
||||
cause a crash.</p>
|
||||
<h3 id="experimenting-with-different-networks">Experimenting with different networks</h3>
|
||||
<p>The default network for OMLET (the one you get if you type <code>make</code> with the
|
||||
executable name <code>prog</code>) is the simplest recurrent neural network. It looks
|
||||
like</p>
|
||||
<div class="sourceCode" id="cb15"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>h <span class="op">=</span> tanh<span class="op">(</span>Wxh <span class="op">*</span> x <span class="op">+</span> Whh <span class="op">*</span> h<span class="ch">' </span><span class="er">+ Bh)</span></span>
|
||||
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>y <span class="op">=</span> Why <span class="op">*</span> h <span class="op">+</span> By</span></code></pre></div>
|
||||
<p>where</p>
|
||||
@@ -393,36 +360,24 @@ simplest recurrent neural network. It looks like</p>
|
||||
<li><code>y</code> is the <em>output vector</em></li>
|
||||
<li><code>h</code> is the <em>hidden state vector</em></li>
|
||||
<li><code>h'</code> is the previous value of <code>h</code></li>
|
||||
<li><code>Wxh</code>, <code>Whh</code>, and <code>Why</code> are
|
||||
<em>weight matrices</em></li>
|
||||
<li><code>Wxh</code>, <code>Whh</code>, and <code>Why</code> are <em>weight matrices</em></li>
|
||||
<li><code>Bh</code> and <code>By</code> are <em>bias vectors</em>.</li>
|
||||
<li><code>tanh(3)</code> is the <a
|
||||
href="https://en.wikipedia.org/wiki/Hyperbolic_function">hyperbolic
|
||||
tangent function</a></li>
|
||||
<li><code>tanh(3)</code> is the <a href="https://en.wikipedia.org/wiki/Hyperbolic_function">hyperbolic tangent function</a></li>
|
||||
</ul>
|
||||
<p>The <code>W</code>’s and <code>B</code>’s are the trainable
|
||||
parameters of the network, and the process of training is optimizing the
|
||||
values of these parameters to minimize the loss of the network across
|
||||
the training set.</p>
|
||||
<p>The <code>W</code>’s and <code>B</code>’s are the trainable parameters of the network, and the
|
||||
process of training is optimizing the values of these parameters to minimize
|
||||
the loss of the network across the training set.</p>
|
||||
<p>It is the presence of the hidden state vector that allows the RNN to
|
||||
“remember” the past. We can see what would happen if we removed this
|
||||
hidden state. If you type</p>
|
||||
<div class="sourceCode" id="cb16"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> lin1</span></code></pre></div>
|
||||
<p>OMLET will create an <a
|
||||
href="https://en.wikipedia.org/wiki/ADALINE">ADALINE</a> network that
|
||||
does</p>
|
||||
“remember” the past. We can see what would happen if we removed this hidden
|
||||
state. If you type</p>
|
||||
<div class="sourceCode" id="cb16"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> lin1</span></code></pre></div>
|
||||
<p>OMLET will create an <a href="https://en.wikipedia.org/wiki/ADALINE">ADALINE</a> network that does</p>
|
||||
<div class="sourceCode" id="cb17"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>y <span class="op">=</span> Wxy <span class="op">*</span> x <span class="op">+</span> By</span></code></pre></div>
|
||||
<p>This is a simple <a
|
||||
href="https://en.wikipedia.org/wiki/Linear_map">linear</a> <a
|
||||
href="https://en.wikipedia.org/wiki/Feedforward_neural_network">feed-forward
|
||||
network</a>. You can run it with</p>
|
||||
<div class="sourceCode" id="cb18"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./lin1</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>The linear network won’t be able to get past the gibberish stage,
|
||||
because it lacks history:</p>
|
||||
<div class="sourceCode" id="cb19"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./lin1</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>This is a simple <a href="https://en.wikipedia.org/wiki/Linear_map">linear</a> <a href="https://en.wikipedia.org/wiki/Feedforward_neural_network">feed-forward network</a>. You can run it with</p>
|
||||
<div class="sourceCode" id="cb18"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./lin1</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>The linear network won’t be able to get past the gibberish stage, because it
|
||||
lacks history:</p>
|
||||
<div class="sourceCode" id="cb19"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./lin1</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>produces:</p>
|
||||
<pre><code>UERond w,
|
||||
|
||||
@@ -446,92 +401,68 @@ I'delandinarrstath har aksubly s cath Whern t Is, weciss:
|
||||
GLat s; llde.
|
||||
Y aterit dsthence
|
||||
T14:67% 2.465404</code></pre>
|
||||
<p>It is able to guess at what character is likely to follow the current
|
||||
one (by doing a <a
|
||||
href="https://en.wikipedia.org/wiki/Linear_regression">linear
|
||||
regression</a>), but it lacks any history beyond that to guide it.</p>
|
||||
<p>You might be wondering about the role of the <code>tanh(3)</code>
|
||||
function in the RNN. <code>tanh(3)</code> acts as an <a
|
||||
href="https://en.wikipedia.org/wiki/Activation_function">activation
|
||||
function</a> which adds <a
|
||||
href="https://en.wikipedia.org/wiki/Nonlinear_system">nonlinearity</a>
|
||||
<p>It is able to guess at what character is likely to follow the current one
|
||||
(by doing a <a href="https://en.wikipedia.org/wiki/Linear_regression">linear regression</a>), but it lacks any history beyond that to
|
||||
guide it.</p>
|
||||
<p>You might be wondering about the role of the <code>tanh(3)</code> function in the RNN.
|
||||
<code>tanh(3)</code> acts as an <a href="https://en.wikipedia.org/wiki/Activation_function">activation function</a> which adds <a href="https://en.wikipedia.org/wiki/Nonlinear_system">nonlinearity</a>
|
||||
to the network and allows it to solve complicated problems. Without
|
||||
nonlinearity, all of the linear functions would fold together into a
|
||||
single matrix-vector multiply and you’d effectively regress to the
|
||||
linear network above. Alas, even adding a nonlinearity to the
|
||||
feed-forward network (creating a <a
|
||||
href="https://en.wikipedia.org/wiki/Perceptron">perceptron</a>) does not
|
||||
improve the performance because we still lack the history provided by
|
||||
the hidden state vector (although if you want to try it yourself, you
|
||||
can do so with <code>make per1</code> - note that’s not
|
||||
<code>perl</code> the language but <code>per</code> with the digit
|
||||
1).</p>
|
||||
nonlinearity, all of the linear functions would fold together into a single
|
||||
matrix-vector multiply and you’d effectively regress to the linear network
|
||||
above. Alas, even adding a nonlinearity to the feed-forward network
|
||||
(creating a <a href="https://en.wikipedia.org/wiki/Perceptron">perceptron</a>) does not improve the performance because we
|
||||
still lack the history provided by the hidden state vector (although if you
|
||||
want to try it yourself, you can do so with <code>make per1</code> - note that’s not <code>perl</code>
|
||||
the language but <code>per</code> with the digit 1).</p>
|
||||
<h3 id="going-deeper">Going deeper:</h3>
|
||||
<p>We can try to improve the RNN’s performance by stacking RNN modules
|
||||
atop each other:</p>
|
||||
<p>We can try to improve the RNN’s performance by stacking RNN modules atop each
|
||||
other:</p>
|
||||
<div class="sourceCode" id="cb21"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>h1 <span class="op">=</span> RNN<span class="op">(</span>h1<span class="ch">',</span><span class="er"> x)</span></span>
|
||||
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>h2 <span class="op">=</span> RNN<span class="op">(</span>h2<span class="ch">',</span><span class="er"> h1)</span></span>
|
||||
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>y <span class="op">=</span> Why <span class="op">*</span> h2 <span class="op">+</span> By</span></code></pre></div>
|
||||
<p>with <code>RNN(h, x)</code> defined as above. Each RNN module has its
|
||||
own set of parameters and its own hidden state vector. This will improve
|
||||
the network’s performance, at the cost of a much larger parameter
|
||||
space.</p>
|
||||
<p>with <code>RNN(h, x)</code> defined as above. Each RNN module has its own set of
|
||||
parameters and its own hidden state vector. This will improve the network’s
|
||||
performance, at the cost of a much larger parameter space.</p>
|
||||
<hr />
|
||||
<p><strong>IMPORTANT NOTE</strong>: Since OMLET uses the system stack
|
||||
for network storage, larger networks may cause OMLET to crash (typically
|
||||
with a message like <code>Segmentation fault</code>) unless the system
|
||||
stack size is first increased. The exact command for doing so depends on
|
||||
your shell and your system’s hard limits. On
|
||||
<code>sh</code>/<code>ksh</code>/<code>bash</code> shells, you can view
|
||||
the hard limit with <code>ulimit -Hs</code> and set it with
|
||||
<code>ulimit -s 65532</code> (replacing <code>65532</code> with the
|
||||
actual hard limit). On <code>csh</code>/<code>tcsh</code> shells, you
|
||||
can view the hard limit with <code>limit -h stacksize</code> and set it
|
||||
with <code>limit stacksize 65532</code> (replacing <code>65532</code>
|
||||
with the actual hard limit).</p>
|
||||
<p><strong>IMPORTANT NOTE</strong>: Since OMLET uses the system stack for network storage,
|
||||
larger networks may cause OMLET to crash (typically with a message like
|
||||
<code>Segmentation fault</code>) unless the system stack size is first increased.
|
||||
The exact command for doing so depends on your shell and your system’s
|
||||
hard limits. On <code>sh</code>/<code>ksh</code>/<code>bash</code> shells, you can view the hard limit
|
||||
with <code>ulimit -Hs</code> and set it with <code>ulimit -s 65532</code> (replacing <code>65532</code>
|
||||
with the actual hard limit). On <code>csh</code>/<code>tcsh</code> shells, you can view
|
||||
the hard limit with <code>limit -h stacksize</code> and set it with
|
||||
<code>limit stacksize 65532</code> (replacing <code>65532</code> with the actual hard limit).</p>
|
||||
<hr />
|
||||
<p>You can try the deeper network by doing</p>
|
||||
<div class="sourceCode" id="cb22"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> rnn2</span></code></pre></div>
|
||||
<p>(or even <code>make rnn3</code> if you want a three-layer RNN) and
|
||||
train it with</p>
|
||||
<div class="sourceCode" id="cb23"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./rnn2</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>The additional depth should allow the network to make better
|
||||
predictions (it can represent more complicated history), but it may take
|
||||
a long time to train -- both because the network (being larger) now
|
||||
requires more time to train and because of the <a
|
||||
href="https://en.wikipedia.org/wiki/Vanishing_gradient_problem">vanishing
|
||||
and exploding gradient problem</a>, which might keep it from ever
|
||||
reaching its potential.</p>
|
||||
<div class="sourceCode" id="cb22"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> rnn2</span></code></pre></div>
|
||||
<p>(or even <code>make rnn3</code> if you want a three-layer RNN) and train it with</p>
|
||||
<div class="sourceCode" id="cb23"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./rnn2</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>The additional depth should allow the network to make better predictions (it
|
||||
can represent more complicated history), but it may take a long time to train
|
||||
-- both because the network (being larger) now requires more time to train and
|
||||
because of the <a href="https://en.wikipedia.org/wiki/Vanishing_gradient_problem">vanishing and exploding gradient problem</a>, which might
|
||||
keep it from ever reaching its potential.</p>
|
||||
<h3 id="lstms-and-grus">LSTMs and GRUs</h3>
|
||||
<p>RNNs are particularly hard to train because they are trained using <a
|
||||
href="https://en.wikipedia.org/wiki/Backpropagation_through_time">backpropagation
|
||||
through time</a>. The RNN is trained by effectively converting it into a
|
||||
non-recurrent network by making many copies of it and propagating the
|
||||
hidden state through the copies. During training, the backpropagation
|
||||
through many clones of the network amplifies the gradient, worsening the
|
||||
exploding and vanishing gradient problem.</p>
|
||||
<p><a href="https://en.wikipedia.org/wiki/Long_short-term_memory">Long
|
||||
Short Term Memory</a> networks (also called LSTMs) were developed to
|
||||
solve this problem. Christopher Olah gives a good description of them at
|
||||
his <a
|
||||
href="http://colah.github.io/posts/2015-08-Understanding-LSTMs/">blog
|
||||
posting</a>. You can build a two-level LSTM by doing</p>
|
||||
<div class="sourceCode" id="cb24"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> lstm2</span></code></pre></div>
|
||||
<p>RNNs are particularly hard to train because they are trained using
|
||||
<a href="https://en.wikipedia.org/wiki/Backpropagation_through_time">backpropagation through time</a>. The RNN is trained by effectively
|
||||
converting it into a non-recurrent network by making many copies of it
|
||||
and propagating the hidden state through the copies. During training,
|
||||
the backpropagation through many clones of the network amplifies the
|
||||
gradient, worsening the exploding and vanishing gradient problem.</p>
|
||||
<p><a href="https://en.wikipedia.org/wiki/Long_short-term_memory">Long Short Term Memory</a> networks (also called LSTMs) were developed to
|
||||
solve this problem. Christopher Olah gives a good description of them
|
||||
at his <a href="http://colah.github.io/posts/2015-08-Understanding-LSTMs/">blog posting</a>. You can build a two-level LSTM by doing</p>
|
||||
<div class="sourceCode" id="cb24"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> lstm2</span></code></pre></div>
|
||||
<p>and train with it with</p>
|
||||
<div class="sourceCode" id="cb25"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./lstm2</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>The LSTM is much easier to train because it explicitly decides how to
|
||||
update its hidden state via “gates”. These gates are called</p>
|
||||
<div class="sourceCode" id="cb25"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./lstm2</span> Shakespeare.txt</span></code></pre></div>
|
||||
<p>The LSTM is much easier to train because it explicitly decides how to update
|
||||
its hidden state via “gates”. These gates are called</p>
|
||||
<ul>
|
||||
<li><em>input gate</em>, which decides what part of the input to pay
|
||||
attention to</li>
|
||||
<li><em>forget gate</em>, which decides what part of the hidden state to
|
||||
forget</li>
|
||||
<li><em>output gate</em>, which decides what part of the hidden state is
|
||||
used to produce the output</li>
|
||||
<li><em>input gate</em>, which decides what part of the input to pay attention to</li>
|
||||
<li><em>forget gate</em>, which decides what part of the hidden state to forget</li>
|
||||
<li><em>output gate</em>, which decides what part of the hidden state is used to
|
||||
produce the output</li>
|
||||
</ul>
|
||||
<p>The basic LSTM equations are</p>
|
||||
<div class="sourceCode" id="cb26"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a>f <span class="op">=</span> sigmoid<span class="op">(</span>Wxf <span class="op">*</span> x <span class="op">+</span> Whf <span class="op">*</span> h<span class="ch">' </span><span class="er">+ Bf)</span></span>
|
||||
@@ -542,95 +473,70 @@ used to produce the output</li>
|
||||
<p>Where</p>
|
||||
<ul>
|
||||
<li><code>x</code> is the input vector</li>
|
||||
<li><code>h</code> is the hidden state (and the output to the next
|
||||
layer)</li>
|
||||
<li><code>c</code> is the <em>cell state</em> which represents the
|
||||
“memory” of the LSTM</li>
|
||||
<li><code>h'</code> and <code>c'</code> are the previous values of
|
||||
<code>h</code> and <code>c</code> respectively</li>
|
||||
<li><code>f</code> is the <em>forget gate</em> that tells the LSTM what
|
||||
portion of the hidden state to forget</li>
|
||||
<li><code>i</code> is the <em>input gate</em> that tells the LSTM what
|
||||
portion of the input vector to pay attention to</li>
|
||||
<li><code>o</code> is the <em>output gate</em> that tells the LSTM what
|
||||
portion of the cell state to use to generate the hidden state</li>
|
||||
<li><code>Wxf</code>, <code>Whf</code>, <code>Wxi</code>,
|
||||
<code>Whi</code>, <code>Wxo</code>, <code>Who</code>, <code>Wxc</code>,
|
||||
and <code>Whc</code> are trainable parameter matrices</li>
|
||||
<li><code>Bf</code>, <code>Bi</code>, <code>Bo</code>, and
|
||||
<code>Bc</code> are trainable bias vectors</li>
|
||||
<li><code>h</code> is the hidden state (and the output to the next layer)</li>
|
||||
<li><code>c</code> is the <em>cell state</em> which represents the “memory” of the LSTM</li>
|
||||
<li><code>h'</code> and <code>c'</code> are the previous values of <code>h</code> and <code>c</code> respectively</li>
|
||||
<li><code>f</code> is the <em>forget gate</em> that tells the LSTM what portion of the hidden
|
||||
state to forget</li>
|
||||
<li><code>i</code> is the <em>input gate</em> that tells the LSTM what portion of the input
|
||||
vector to pay attention to</li>
|
||||
<li><code>o</code> is the <em>output gate</em> that tells the LSTM what portion of the cell
|
||||
state to use to generate the hidden state</li>
|
||||
<li><code>Wxf</code>, <code>Whf</code>, <code>Wxi</code>, <code>Whi</code>, <code>Wxo</code>, <code>Who</code>, <code>Wxc</code>, and <code>Whc</code> are trainable
|
||||
parameter matrices</li>
|
||||
<li><code>Bf</code>, <code>Bi</code>, <code>Bo</code>, and <code>Bc</code> are trainable bias vectors</li>
|
||||
<li><code>tanh(3)</code> is the hyperbolic tangent function</li>
|
||||
<li><code>sigmoid</code> is the <a
|
||||
href="https://en.wikipedia.org/wiki/Logistic_function">logistic
|
||||
function</a></li>
|
||||
<li><code>sigmoid</code> is the <a href="https://en.wikipedia.org/wiki/Logistic_function">logistic function</a></li>
|
||||
</ul>
|
||||
<p>There are several LSTM variants (see <a
|
||||
href="http://colah.github.io/posts/2015-08-Understanding-LSTMs/">C.
|
||||
Olah’s blog post</a> for more examples). One important one is the <a
|
||||
href="https://en.wikipedia.org/wiki/Gated_recurrent_unit">gated
|
||||
recurrent unit</a>. GRUs are simplified versions of an LSTM which
|
||||
combine the gates together, meaning they require fewer learned
|
||||
parameters. This allows them to train faster than a generic LSTM. You
|
||||
can build a two-layer GRU with</p>
|
||||
<div class="sourceCode" id="cb27"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> gru2</span></code></pre></div>
|
||||
<p>There are several LSTM variants (see <a href="http://colah.github.io/posts/2015-08-Understanding-LSTMs/">C. Olah’s blog post</a> for more
|
||||
examples). One important one is the <a href="https://en.wikipedia.org/wiki/Gated_recurrent_unit">gated recurrent unit</a>. GRUs are
|
||||
simplified versions of an LSTM which combine the gates together, meaning they
|
||||
require fewer learned parameters. This allows them to train faster than a
|
||||
generic LSTM. You can build a two-layer GRU with</p>
|
||||
<div class="sourceCode" id="cb27"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> gru2</span></code></pre></div>
|
||||
<h3 id="building-your-own-networks">Building your own networks</h3>
|
||||
<p>The OMLET <code>Makefile</code> comes with one-, two- and three-layer
|
||||
RNNs, LSTMs and GRUs, along with simpler feed-forward networks like
|
||||
multi-layer perceptrons and a linear network. This isn’t the limit of
|
||||
OMLET’s power – you can create your own networks by modifying the
|
||||
<code>Makefile</code>. Networks are passed in on the compiler’s
|
||||
command-line by using <code>-D</code> directives. The network is defined
|
||||
by a <code>-DNW='...'</code> command which consists of a series of
|
||||
comma-separated assignments. For example, the simple one-layer RNN could
|
||||
be defined like</p>
|
||||
<p>The OMLET <code>Makefile</code> comes with one-, two- and three-layer RNNs, LSTMs and
|
||||
GRUs, along with simpler feed-forward networks like multi-layer perceptrons and
|
||||
a linear network. This isn’t the limit of OMLET’s power – you can create your
|
||||
own networks by modifying the <code>Makefile</code>. Networks are passed in on the
|
||||
compiler’s command-line by using <code>-D</code> directives. The network is defined by
|
||||
a <code>-DNW='...'</code> command which consists of a series of comma-separated
|
||||
assignments. For example, the simple one-layer RNN could be defined like</p>
|
||||
<pre class="make"><code>-DNW=' x = I(n), hp = I(128), \
|
||||
h = C(hp, T(A(L(128, x), L(128, hp)))), \
|
||||
y = L(n, h)'</code></pre>
|
||||
<p>The network declares <code>x</code> as an input vector (there must be
|
||||
a declaration for <code>x</code>). It is declared as <code>I(n)</code>,
|
||||
which is an input vector of size <code>n</code>, which is the number of
|
||||
characters of the input alphabet (OMLET computes this from the input
|
||||
file at the start of training). OMLET will arrange to present the input
|
||||
character as a <a
|
||||
href="https://en.wikipedia.org/wiki/One-hot">one-hot</a> vector based on
|
||||
the current input character.</p>
|
||||
<p>The second declaration, <code>hp</code>, declares the previous hidden
|
||||
state vector (what we called <code>h'</code> above). We declare this to
|
||||
be of size 128 – an arbitrary choice. A larger state vector can
|
||||
(theoretically) carry more state, but at a cost of larger parameter
|
||||
matrices and longer training time. You can experiment with increasing
|
||||
the hidden vector size and see.</p>
|
||||
<p>The third line is the core of the RNN. It sets <code>h</code>, the
|
||||
hidden vector output to be the sum of two linear elements specified by
|
||||
<code>L</code>. The <code>L</code> function takes two parameters – the
|
||||
output vector size (which must match the size of <code>h</code>) and the
|
||||
input vector. <code>L</code> will compute <code>y = W * x + B</code>
|
||||
where each <code>L</code> has its own <code>W</code> (weight) and
|
||||
<code>B</code> (bias) training parameters. Both <code>x</code> and
|
||||
<code>hp</code> are sent through <code>L</code> and the result passed
|
||||
through the <code>A</code> function, which does vector addition. That
|
||||
result is passed through <code>T</code> which does element-wise
|
||||
<code>tanh(3)</code> activation.</p>
|
||||
<p>Next, we wrap the whole thing with the <code>C</code> function.
|
||||
<code>C</code> connects <code>hp</code> with <code>h</code>, causing the
|
||||
new value of <code>h</code> to be passed to the <code>hp</code> vector
|
||||
on the next iteration of the algorithm (allowing the RNN to retain state
|
||||
in <code>h</code>).</p>
|
||||
<p>Finally, the whole result is passed through another instance of
|
||||
<code>L</code>, this time producing a vector of size <code>n</code>,
|
||||
which will have the negative log <a
|
||||
href="https://en.wikipedia.org/wiki/Likelihood_function">likelihood</a>
|
||||
function. This is assigned to <code>y</code>, which is the output of the
|
||||
network (and hence must also be declared).</p>
|
||||
<p>OMLET will take the <code>y</code> result and pass it through the <a
|
||||
href="https://en.wikipedia.org/wiki/Softmax_function">softmax</a>
|
||||
function, which converts the log probabilities into a probability
|
||||
distribution. In inference mode, this is used to select the next
|
||||
character to emit. In training mode, this is used to generate the loss
|
||||
which is backpropagated.</p>
|
||||
<p>As an example of a more complicated network, we can look at a
|
||||
two-layer GRU network:</p>
|
||||
<p>The network declares <code>x</code> as an input vector (there must be a declaration for
|
||||
<code>x</code>). It is declared as <code>I(n)</code>, which is an input vector of size <code>n</code>, which
|
||||
is the number of characters of the input alphabet (OMLET computes this from
|
||||
the input file at the start of training). OMLET will arrange to present the
|
||||
input character as a <a href="https://en.wikipedia.org/wiki/One-hot">one-hot</a> vector based on the current input
|
||||
character.</p>
|
||||
<p>The second declaration, <code>hp</code>, declares the previous hidden state vector (what
|
||||
we called <code>h'</code> above). We declare this to be of size 128 – an arbitrary
|
||||
choice. A larger state vector can (theoretically) carry more state, but at
|
||||
a cost of larger parameter matrices and longer training time. You can
|
||||
experiment with increasing the hidden vector size and see.</p>
|
||||
<p>The third line is the core of the RNN. It sets <code>h</code>, the hidden vector output
|
||||
to be the sum of two linear elements specified by <code>L</code>. The <code>L</code> function
|
||||
takes two parameters – the output vector size (which must match the size of
|
||||
<code>h</code>) and the input vector. <code>L</code> will compute <code>y = W * x + B</code> where each <code>L</code>
|
||||
has its own <code>W</code> (weight) and <code>B</code> (bias) training parameters. Both <code>x</code> and
|
||||
<code>hp</code> are sent through <code>L</code> and the result passed through the <code>A</code> function,
|
||||
which does vector addition. That result is passed through <code>T</code> which does
|
||||
element-wise <code>tanh(3)</code> activation.</p>
|
||||
<p>Next, we wrap the whole thing with the <code>C</code> function. <code>C</code> connects <code>hp</code>
|
||||
with <code>h</code>, causing the new value of <code>h</code> to be passed to the <code>hp</code> vector on
|
||||
the next iteration of the algorithm (allowing the RNN to retain state in <code>h</code>).</p>
|
||||
<p>Finally, the whole result is passed through another instance of <code>L</code>, this time
|
||||
producing a vector of size <code>n</code>, which will have the negative log
|
||||
<a href="https://en.wikipedia.org/wiki/Likelihood_function">likelihood</a> function. This is assigned to <code>y</code>, which is the output of
|
||||
the network (and hence must also be declared).</p>
|
||||
<p>OMLET will take the <code>y</code> result and pass it through the <a href="https://en.wikipedia.org/wiki/Softmax_function">softmax</a> function,
|
||||
which converts the log probabilities into a probability distribution. In
|
||||
inference mode, this is used to select the next character to emit. In
|
||||
training mode, this is used to generate the loss which is backpropagated.</p>
|
||||
<p>As an example of a more complicated network, we can look at a two-layer
|
||||
GRU network:</p>
|
||||
<pre class="make"><code>-DHS=128, \
|
||||
-DNW=' x = I(n), \
|
||||
y = L(n, MD(MD(x)))' \
|
||||
@@ -641,167 +547,116 @@ two-layer GRU network:</p>
|
||||
zc = OG(1, -1, z), \
|
||||
h = C(hp, A(M(zc, hp), M(z, c))), \
|
||||
y = h'</code></pre>
|
||||
<p>We are using a few new tricks here – first, we are defining
|
||||
<code>HS</code> as the size of the hidden and cell vectors. There’s
|
||||
nothing special about this name, it’s just convenient to specify it so
|
||||
we don’t have a bunch of constants in the code. Second, the network
|
||||
itself is very simple – it declares <code>x</code> and has the matrix
|
||||
that converts the <code>HS</code>-sized hidden vector back to the
|
||||
<code>n</code>-sized alphabet vector… but it now calls <code>MD</code>,
|
||||
which is the user-definable module (here we are using it twice, to have
|
||||
two cascaded GRU blocks). The <code>MD</code> function performs the
|
||||
sub-network defined by the <code>BK</code> compile-time parameter
|
||||
(specified in the <code>-DBK='...'</code> setting). This sub-module
|
||||
again takes an <code>x</code> parameter and produces a <code>y</code>
|
||||
output. Inside it, we declare <code>hp</code> and <code>h</code>, the
|
||||
previous and current state vector, plus equations for the various GRU
|
||||
gates (these use <code>S</code> for the sigmoid activation function).
|
||||
One final new call is <code>OG</code> which does offset and gain,
|
||||
performing <code>y = offset + gain * x</code> where <code>offset</code>
|
||||
(the first parameter) and <code>gain</code> (the second) are constants.
|
||||
We are using this here to compute <code>(1 - z)</code> for the GRU’s
|
||||
linear interpolator.</p>
|
||||
<p>We are using a few new tricks here – first, we are defining <code>HS</code> as the size
|
||||
of the hidden and cell vectors. There’s nothing special about this name, it’s
|
||||
just convenient to specify it so we don’t have a bunch of constants in the
|
||||
code. Second, the network itself is very simple – it declares <code>x</code> and has
|
||||
the matrix that converts the <code>HS</code>-sized hidden vector back to the <code>n</code>-sized
|
||||
alphabet vector… but it now calls <code>MD</code>, which is the user-definable
|
||||
module (here we are using it twice, to have two cascaded GRU blocks). The
|
||||
<code>MD</code> function performs the sub-network defined by the <code>BK</code> compile-time
|
||||
parameter (specified in the <code>-DBK='...'</code> setting). This sub-module again
|
||||
takes an <code>x</code> parameter and produces a <code>y</code> output. Inside it, we declare
|
||||
<code>hp</code> and <code>h</code>, the previous and current state vector, plus equations for the
|
||||
various GRU gates (these use <code>S</code> for the sigmoid activation function).
|
||||
One final new call is <code>OG</code> which does offset and gain, performing
|
||||
<code>y = offset + gain * x</code> where <code>offset</code> (the first parameter) and <code>gain</code> (the
|
||||
second) are constants. We are using this here to compute <code>(1 - z)</code> for the
|
||||
GRU’s linear interpolator.</p>
|
||||
<p>The full set of available function blocks follows:</p>
|
||||
<ul>
|
||||
<li><code>I(s)</code>: declares a vector (input or state) of size
|
||||
<code>s</code></li>
|
||||
<li><code>L(s, x)</code>: learnable linear function
|
||||
<code>y = W * x + B</code> with an output vector size of
|
||||
<code>s</code></li>
|
||||
<li><code>CM(x)</code>: learnable element-wise gain function
|
||||
<code>y = W * x</code></li>
|
||||
<li><code>I(s)</code>: declares a vector (input or state) of size <code>s</code></li>
|
||||
<li><code>L(s, x)</code>: learnable linear function <code>y = W * x + B</code> with an output vector
|
||||
size of <code>s</code></li>
|
||||
<li><code>CM(x)</code>: learnable element-wise gain function <code>y = W * x</code></li>
|
||||
<li><code>A(a, b)</code>: element-wise add: <code>y = a + b</code></li>
|
||||
<li><code>M(a, b)</code>: element-wise multiply:
|
||||
<code>y = a * b</code></li>
|
||||
<li><code>S(x)</code>: sigmoid activation function
|
||||
<code>y = sigmoid(x)</code></li>
|
||||
<li><code>T(x)</code>: hyperbolic tangent activation function
|
||||
<code>y = tanh(x)</code></li>
|
||||
<li><code>C(xp, x)</code>: copy <code>x</code> to <code>xp</code> in the
|
||||
next time step (propagate through time)</li>
|
||||
<li><code>OG(o, g, x)</code>: apply a constant offset and gain:
|
||||
<code>y = o + g * x</code></li>
|
||||
<li><code>MD(x)</code>: apply the sub-network specified by
|
||||
<code>BK</code></li>
|
||||
<li><code>M(a, b)</code>: element-wise multiply: <code>y = a * b</code></li>
|
||||
<li><code>S(x)</code>: sigmoid activation function <code>y = sigmoid(x)</code></li>
|
||||
<li><code>T(x)</code>: hyperbolic tangent activation function <code>y = tanh(x)</code></li>
|
||||
<li><code>C(xp, x)</code>: copy <code>x</code> to <code>xp</code> in the next time step (propagate through
|
||||
time)</li>
|
||||
<li><code>OG(o, g, x)</code>: apply a constant offset and gain: <code>y = o + g * x</code></li>
|
||||
<li><code>MD(x)</code>: apply the sub-network specified by <code>BK</code></li>
|
||||
</ul>
|
||||
<p>Note: even if you don’t use <code>MD</code> in your network, you
|
||||
should still define <code>BK</code> by adding <code>-DBK='y=x'</code> to
|
||||
the command line, otherwise you will get a compile-time error.</p>
|
||||
<p>Note: even if you don’t use <code>MD</code> in your network, you should still define
|
||||
<code>BK</code> by adding <code>-DBK='y=x'</code> to the command line, otherwise you will get a
|
||||
compile-time error.</p>
|
||||
<h3 id="hyperparameters">Hyperparameters</h3>
|
||||
<p>OMLET has a large number of training and inference parameters which
|
||||
can be changed by the user. All of these are set by <code>-D</code> on
|
||||
the compile command line. The list of hyperparameters follows:</p>
|
||||
<p>OMLET has a large number of training and inference parameters which can be
|
||||
changed by the user. All of these are set by <code>-D</code> on the compile command line.
|
||||
The list of hyperparameters follows:</p>
|
||||
<ul>
|
||||
<li><code>TP</code>: Temperature parameter for use in inference mode.
|
||||
This divides the log probabilities before softmax. A low temperature
|
||||
makes the model choose safer but more boring choices. A high temperature
|
||||
takes more risks but makes more mistakes. Default is 1.0, which uses the
|
||||
computed probabilities.</li>
|
||||
<li><code>N</code>: Batch size. This is the number of times the RNN is
|
||||
unrolled, so it controls how far back in the past the RNN can see. The
|
||||
default is 50. Larger batch sizes update the weights less frequently and
|
||||
allow the RNN to see farther back in time, but at a cost of
|
||||
proportionally more memory.</li>
|
||||
<li><code>TR</code>: The percentage of batches in the input data set
|
||||
that will be used for training. The default value of 0.95 sets this as
|
||||
95%.</li>
|
||||
<li><code>LR</code>: The initial learning rate, the default is
|
||||
0.002.</li>
|
||||
<li><code>LE</code>: The epoch where the learning rate will start
|
||||
decaying. Defaults to epoch 10.</li>
|
||||
<li><code>LD</code>: Learning rate decay, per epoch (after
|
||||
<code>LE</code> epochs). The learning rate is scaled by this number.
|
||||
Default is 0.97</li>
|
||||
<li><code>WD</code>: Weight-decay parameter, to promote <a
|
||||
href="https://en.wikipedia.org/wiki/Regularization_(mathematics)">regularization</a>.
|
||||
The default is 0.00008.</li>
|
||||
<li><code>RS</code>: The random scale for weight initialization. Weight
|
||||
parameters will be initialized to be between <code>-RS</code> to
|
||||
<code>+RS</code>. The default is 0.15.</li>
|
||||
<li><code>CL</code>: Clamp value for gradients. Gradients will be
|
||||
limited to the range <code>-CL</code> to <code>+CL</code>. Default is
|
||||
5.</li>
|
||||
<li><code>B1</code>: Momentum mean parameter for Adam optimizer. Set to
|
||||
0.9.</li>
|
||||
<li><code>B2</code>: Momentum variance parameter for Adam optimizer, Set
|
||||
to 0.999.</li>
|
||||
<li><code>EP</code>: Epsilon parameter for Adam, to provide numerical
|
||||
stability. Set to 0.00000001.</li>
|
||||
<li><code>DI</code>: How often to print a training or validation
|
||||
progress message and inference snippet. The default prints every 100
|
||||
training batches.</li>
|
||||
<li><code>SL</code>: The number of characters to print when doing an
|
||||
inference snippet. Default is 200.</li>
|
||||
<li><code>PF</code>: Format string for the checkpoint filename. The
|
||||
default is <code>"cp%02d_%.3f"</code> which includes the epoch and
|
||||
validation loss. You may wish to add a subdirectory to the name to keep
|
||||
checkpoint files out of the current directory.</li>
|
||||
<li><code>TP</code>: Temperature parameter for use in inference mode. This divides the
|
||||
log probabilities before softmax. A low temperature makes the model choose
|
||||
safer but more boring choices. A high temperature takes more risks but
|
||||
makes more mistakes. Default is 1.0, which uses the computed
|
||||
probabilities.</li>
|
||||
<li><code>N</code>: Batch size. This is the number of times the RNN is unrolled, so it
|
||||
controls how far back in the past the RNN can see. The default is 50.
|
||||
Larger batch sizes update the weights less frequently and allow the RNN to
|
||||
see farther back in time, but at a cost of proportionally more memory.</li>
|
||||
<li><code>TR</code>: The percentage of batches in the input data set that will be used
|
||||
for training. The default value of 0.95 sets this as 95%.</li>
|
||||
<li><code>LR</code>: The initial learning rate, the default is 0.002.</li>
|
||||
<li><code>LE</code>: The epoch where the learning rate will start decaying. Defaults to
|
||||
epoch 10.</li>
|
||||
<li><code>LD</code>: Learning rate decay, per epoch (after <code>LE</code> epochs). The learning
|
||||
rate is scaled by this number. Default is 0.97</li>
|
||||
<li><code>WD</code>: Weight-decay parameter, to promote <a href="https://en.wikipedia.org/wiki/Regularization_(mathematics)">regularization</a>. The default
|
||||
is 0.00008.</li>
|
||||
<li><code>RS</code>: The random scale for weight initialization. Weight parameters will
|
||||
be initialized to be between <code>-RS</code> to <code>+RS</code>. The default is 0.15.</li>
|
||||
<li><code>CL</code>: Clamp value for gradients. Gradients will be limited to the range
|
||||
<code>-CL</code> to <code>+CL</code>. Default is 5.</li>
|
||||
<li><code>B1</code>: Momentum mean parameter for Adam optimizer. Set to 0.9.</li>
|
||||
<li><code>B2</code>: Momentum variance parameter for Adam optimizer, Set to 0.999.</li>
|
||||
<li><code>EP</code>: Epsilon parameter for Adam, to provide numerical stability. Set to
|
||||
0.00000001.</li>
|
||||
<li><code>DI</code>: How often to print a training or validation progress message and
|
||||
inference snippet. The default prints every 100 training batches.</li>
|
||||
<li><code>SL</code>: The number of characters to print when doing an inference snippet.
|
||||
Default is 200.</li>
|
||||
<li><code>PF</code>: Format string for the checkpoint filename. The default is
|
||||
<code>"cp%02d_%.3f"</code> which includes the epoch and validation loss. You may
|
||||
wish to add a subdirectory to the name to keep checkpoint files out of
|
||||
the current directory.</li>
|
||||
</ul>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019mills"><a name="inventory"></a>Inventory for
|
||||
2019/mills</h1>
|
||||
<h1 id="inventory-for-2019mills"><a name="inventory"></a>Inventory for 2019/mills</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a href="2019_mills.tar.bz2">2019_mills.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="2019_mills.tar.bz2">2019_mills.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a href="Eugene_Onegin.cp11_1.188">Eugene_Onegin.cp11_1.188</a> -
|
||||
training data from Eugene Onegin poetry</li>
|
||||
<li><a href="Eugene_Onegin.txt.gz">Eugene_Onegin.txt.gz</a> - compressed
|
||||
Eugene Onegin poetry</li>
|
||||
<li><a
|
||||
href="IOCCC-Rules-Guidelines.cp98_0.175">IOCCC-Rules-Guidelines.cp98_0.175</a>
|
||||
- training data from IOCCC 1984-2019 rules guidelines</li>
|
||||
<li><a
|
||||
href="IOCCC-Rules-Guidelines.txt.gz">IOCCC-Rules-Guidelines.txt.gz</a> -
|
||||
compressed IOCCC rules and guidelines 1984-2019</li>
|
||||
<li><a href="IOCCC-hints.cp09_1.809">IOCCC-hints.cp09_1.809</a> -
|
||||
training data from IOCCC hints file text for 1984-2018</li>
|
||||
<li><a href="IOCCC-hints.txt.gz">IOCCC-hints.txt.gz</a> - compressed
|
||||
IOCCC hints for 1984-2018</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="Shakespeare.cp04_1.633">Shakespeare.cp04_1.633</a> -
|
||||
training data from Shakespeare text</li>
|
||||
<li><a href="Shakespeare.txt.gz">Shakespeare.txt.gz</a> - compressed
|
||||
Shakespeare text</li>
|
||||
<li><a href="Eugene_Onegin.cp11_1.188">Eugene_Onegin.cp11_1.188</a> - training data from Eugene Onegin poetry</li>
|
||||
<li><a href="Eugene_Onegin.txt.gz">Eugene_Onegin.txt.gz</a> - compressed Eugene Onegin poetry</li>
|
||||
<li><a href="IOCCC-Rules-Guidelines.cp98_0.175">IOCCC-Rules-Guidelines.cp98_0.175</a> - training data from IOCCC 1984-2019 rules guidelines</li>
|
||||
<li><a href="IOCCC-Rules-Guidelines.txt.gz">IOCCC-Rules-Guidelines.txt.gz</a> - compressed IOCCC rules and guidelines 1984-2019</li>
|
||||
<li><a href="IOCCC-hints.cp09_1.809">IOCCC-hints.cp09_1.809</a> - training data from IOCCC hints file text for 1984-2018</li>
|
||||
<li><a href="IOCCC-hints.txt.gz">IOCCC-hints.txt.gz</a> - compressed IOCCC hints for 1984-2018</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/mills/README.md">README.md</a> - markdown source for index.html</li>
|
||||
<li><a href="Shakespeare.cp04_1.633">Shakespeare.cp04_1.633</a> - training data from Shakespeare text</li>
|
||||
<li><a href="Shakespeare.txt.gz">Shakespeare.txt.gz</a> - compressed Shakespeare text</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+142
-207
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Timo_Poikola">Timo Poikola</a><br>
|
||||
Location: <a href="../../location.html#FI">FI</a> - <em>Republic of
|
||||
Finland </em> (<em>Finland</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#FI">FI</a> - <em>Republic of Finland </em> (<em>Finland</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -141,18 +141,16 @@ Finland </em> (<em>Finland</em>) <br><br></li>
|
||||
|
||||
<h2 id="to-build">To build:</h2>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
|
||||
<p>There is an alternate version of this program which changes the way
|
||||
the output is displayed. See <a href="#alternate-code">Alternate
|
||||
code</a> below.</p>
|
||||
<p>NOTE: we disable the optimiser because the author stated that for GCC
|
||||
optimiser level 0 gave correct output. With clang [0123s] works which
|
||||
suggests that [123s] might or might not work with GCC. Likewise, we do
|
||||
similar for the standard, forcing <code>-std=gnu11</code>.</p>
|
||||
<p>There is an alternate version of this program which changes the way the output
|
||||
is displayed. See <a href="#alternate-code">Alternate code</a> below.</p>
|
||||
<p>NOTE: we disable the optimiser because the author stated that for GCC optimiser
|
||||
level 0 gave correct output. With clang [0123s] works which suggests that [123s]
|
||||
might or might not work with GCC. Likewise, we do similar for the standard,
|
||||
forcing <code>-std=gnu11</code>.</p>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_poikola">2019 poikola bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_poikola">2019 poikola bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> 512 ./prog</span>
|
||||
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
@@ -163,17 +161,15 @@ href="../../bugs.html#2019_poikola">2019 poikola bugs</a>.</p>
|
||||
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> 512 ./prog</span></code></pre></div>
|
||||
<p>If you wish for some documentation:</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> docs</span></code></pre></div>
|
||||
<p>This will create the file <code>poikola.pdf</code> for your
|
||||
enjoyment.</p>
|
||||
<p>This will create the file <code>poikola.pdf</code> for your enjoyment.</p>
|
||||
<h2 id="try">Try:</h2>
|
||||
<p>If you don’t have a few days, try:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<p>As the <a href="../../bugs.html#2019_poikola">2019 poikola bugs</a>
|
||||
says, this program will not validate input so it might get stuck or fail
|
||||
if invoked erroneously.</p>
|
||||
<p>As the <a href="../../bugs.html#2019_poikola">2019 poikola bugs</a> says, this program will not validate
|
||||
input so it might get stuck or fail if invoked erroneously.</p>
|
||||
<h2 id="alternate-code">Alternate code:</h2>
|
||||
<p>This version prints a newline after each number for parsing in other
|
||||
ways than what can be done with the original entry.</p>
|
||||
<p>This version prints a newline after each number for parsing in other ways than
|
||||
what can be done with the original entry.</p>
|
||||
<h3 id="alternate-build">Alternate build:</h3>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> alt</span></code></pre></div>
|
||||
<h3 id="alternate-use">Alternate use:</h3>
|
||||
@@ -181,19 +177,16 @@ ways than what can be done with the original entry.</p>
|
||||
<h3 id="alternate-try">Alternate try:</h3>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.alt.sh</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Do you have the time to see what this program does? Think again, come
|
||||
back and try again.</p>
|
||||
<p>Note that <a href="https://t5k.org/curios/page.php/2.html">2</a> can
|
||||
be said to be the least <a
|
||||
href="https://en.wikipedia.org/wiki/Parity_(mathematics)">odd</a> <a
|
||||
href="https://en.wikipedia.org/wiki/Prime_number">prime</a> because it
|
||||
is the greatest <a
|
||||
href="https://en.wikipedia.org/wiki/Parity_(mathematics)">even</a>
|
||||
prime. Moreover <code>2</code> can be also said to be the greatest odd
|
||||
prime because it is the least even prime.</p>
|
||||
<p>The source code layout and some of the variable names honors the ski
|
||||
jumping accomplishments of <a
|
||||
href="https://en.wikipedia.org/wiki/Matti_Nyk%C3%A4nen">Matti
|
||||
<p>Do you have the time to see what this program does? Think again, come back and
|
||||
try again.</p>
|
||||
<p>Note that <a href="https://t5k.org/curios/page.php/2.html">2</a> can be said to be the
|
||||
least <a href="https://en.wikipedia.org/wiki/Parity_(mathematics)">odd</a>
|
||||
<a href="https://en.wikipedia.org/wiki/Prime_number">prime</a> because it is the greatest
|
||||
<a href="https://en.wikipedia.org/wiki/Parity_(mathematics)">even</a> prime. Moreover <code>2</code>
|
||||
can be also said to be the greatest odd prime because it is the least even
|
||||
prime.</p>
|
||||
<p>The source code layout and some of the variable names honors the ski jumping
|
||||
accomplishments of <a href="https://en.wikipedia.org/wiki/Matti_Nyk%C3%A4nen">Matti
|
||||
Nykänen</a>.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="how-to-build">How to build:</h3>
|
||||
@@ -201,215 +194,157 @@ Nykänen</a>.</p>
|
||||
<p>or</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">clang</span> <span class="at">-O</span><span class="pp">[</span><span class="ss">0123s</span><span class="pp">]</span> <span class="at">-o</span> prog prog.c</span></code></pre></div>
|
||||
<p>e.g.:</p>
|
||||
<div class="sourceCode" id="cb10"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">clang</span> <span class="at">-O1</span> <span class="at">-o</span> prog prog.c</span></code></pre></div>
|
||||
<div class="sourceCode" id="cb10"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">clang</span> <span class="at">-O1</span> <span class="at">-o</span> prog prog.c</span></code></pre></div>
|
||||
<h3 id="poster">Poster:</h3>
|
||||
<p>You can generate an A3 sized poster by <code>make docs</code>. This
|
||||
command creates a pdf file <code>poikola.pdf</code>. This requires the
|
||||
<p>You can generate an A3 sized poster by <code>make docs</code>. This command creates a pdf
|
||||
file <code>poikola.pdf</code>. This requires the
|
||||
<a href="https://en.wikipedia.org/wiki/PdfTeX">pdfTeX</a> tool.</p>
|
||||
<h3 id="what-this-entry-does">What this entry does:</h3>
|
||||
<p>An old wise man mumbled to me: > Implement a program, which can
|
||||
calculate SHA-3 checksum for a file –</p>
|
||||
<p>An old wise man mumbled to me:
|
||||
> Implement a program, which can calculate SHA-3 checksum for a file –</p>
|
||||
<p>I thought it was easy, but the wizard didn’t stop yet:</p>
|
||||
<blockquote>
|
||||
<p>and primes and Fibonacci numbers.</p>
|
||||
</blockquote>
|
||||
<p>Still easy. But the <a
|
||||
href="https://www.glyphweb.com/arda/g/gandalf.html">Gandalf the Grey</a>
|
||||
impersonator was not ready:</p>
|
||||
<p>Still easy. But the <a href="https://www.glyphweb.com/arda/g/gandalf.html">Gandalf the
|
||||
Grey</a> impersonator was not ready:</p>
|
||||
<blockquote>
|
||||
<p>But use only <code>main()</code>, and do not use <code>math.h</code>
|
||||
nor predefined stuff at all. But wait, there are more rules: This work
|
||||
should reflect the extraordinary mind of Matti Nykänen, the all-time
|
||||
best <a href="https://en.wikipedia.org/wiki/Matti_Nyk%C3%A4nen">ski
|
||||
jumper</a> and <a
|
||||
href="http://telefinn.blogspot.com/2011/11/matti-nykanen-quotes.html">amateur
|
||||
philosopher</a>, who passed away on fourth of February 2019.</p>
|
||||
<p>But use only <code>main()</code>, and do not use <code>math.h</code> nor predefined stuff at all.
|
||||
But wait, there are more rules: This work should reflect the extraordinary mind
|
||||
of Matti Nykänen, the all-time best <a href="https://en.wikipedia.org/wiki/Matti_Nyk%C3%A4nen">ski
|
||||
jumper</a> and <a href="http://telefinn.blogspot.com/2011/11/matti-nykanen-quotes.html">amateur
|
||||
philosopher</a>,
|
||||
who passed away on fourth of February 2019.</p>
|
||||
</blockquote>
|
||||
<h3 id="oh-boys">Oh boys:</h3>
|
||||
<p>So, I followed the rules given by <a
|
||||
href="https://www.glyphweb.com/arda/g/gandalf.html">Gandalf the
|
||||
White</a> and the <a href="../../judges.html">Judges of the
|
||||
IOCCC</a>.</p>
|
||||
<p>Output of <code>iocccsize</code>, using the <a
|
||||
href="../../2019/iocccsize.c">2019 version of iocccsize</a>, is
|
||||
carefully selected. For the sake of clarity, I used single letter
|
||||
variables in the code. I also avoided unnecessary use of functions. Like
|
||||
a <a href="https://en.wikipedia.org/wiki/Tripundra">tripundra</a>, this
|
||||
program has three levels. In order to reveal all of them, you have to
|
||||
compile this program on three consecutive days.</p>
|
||||
<p>As this is a contest for obfuscated code, the program does not
|
||||
perform unnecessary checks, but either fails or gets stuck if invoked
|
||||
erroneously. The program is invoked in this way:</p>
|
||||
<div class="sourceCode" id="cb11"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span>integer<span class="op">></span> <span class="op"><</span>file<span class="op">></span></span></code></pre></div>
|
||||
<p>where <code><integer></code> is 224, 256, 384, 512 or even
|
||||
1024. Yes, I know 1024 is not a supported length of output, but as I
|
||||
said, the program does not validate its input in any way. These same
|
||||
parameters should be given in calculating a <a
|
||||
href="https://en.wikipedia.org/wiki/Fibonacci_sequence">Fibonacci
|
||||
sequence</a> or <a
|
||||
href="https://en.wikipedia.org/wiki/Prime_number">prime numbers</a>.
|
||||
<em>Please note that maximum file size is one gigabyte</em>!</p>
|
||||
<p>So, I followed the rules given by <a href="https://www.glyphweb.com/arda/g/gandalf.html">Gandalf the
|
||||
White</a> and the <a href="../../judges.html">Judges of
|
||||
the IOCCC</a>.</p>
|
||||
<p>Output of <code>iocccsize</code>, using the <a href="../../2019/iocccsize.c">2019 version of
|
||||
iocccsize</a>, is carefully selected. For
|
||||
the sake of clarity, I used single letter variables in the code. I also avoided
|
||||
unnecessary use of functions. Like a
|
||||
<a href="https://en.wikipedia.org/wiki/Tripundra">tripundra</a>, this program has three
|
||||
levels. In order to reveal all of them, you have to compile this program on
|
||||
three consecutive days.</p>
|
||||
<p>As this is a contest for obfuscated code, the program does not perform
|
||||
unnecessary checks, but either fails or gets stuck if invoked erroneously. The
|
||||
program is invoked in this way:</p>
|
||||
<div class="sourceCode" id="cb11"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span>integer<span class="op">></span> <span class="op"><</span>file<span class="op">></span></span></code></pre></div>
|
||||
<p>where <code><integer></code> is 224, 256, 384, 512 or even 1024. Yes, I know 1024 is not a
|
||||
supported length of output, but as I said, the program does not validate its
|
||||
input in any way. These same parameters should be given in calculating a
|
||||
<a href="https://en.wikipedia.org/wiki/Fibonacci_sequence">Fibonacci sequence</a> or <a href="https://en.wikipedia.org/wiki/Prime_number">prime
|
||||
numbers</a>. <em>Please note that maximum
|
||||
file size is one gigabyte</em>!</p>
|
||||
<h3 id="obfuscation">Obfuscation:</h3>
|
||||
<p><em>Matti Nykänen</em>: Every time I jump, and I get that feeling of
|
||||
<em>bon voyage</em>, the feeling that I’ve been here before.</p>
|
||||
<p><em>Matti Nykänen</em>: When you are about to jump, you are all alone
|
||||
and have to make your own decisions. Up there, it’s all <em>up
|
||||
yours</em>.</p>
|
||||
<p>This code has some jumping too. I used some <code>goto</code>s
|
||||
instead of <code>longjmp(3)</code>. Some Finnish <a
|
||||
href="https://en.wikipedia.org/wiki/Ski_jumping">ski jumping</a> sites
|
||||
are used as labels, however, there is <code>lahti</code> instead of
|
||||
<tt style="font-family: Monaco,
|
||||
<p><em>Matti Nykänen</em>: Every time I jump, and I get that feeling of <em>bon voyage</em>,
|
||||
the feeling that I’ve been here before.</p>
|
||||
<p><em>Matti Nykänen</em>: When you are about to jump, you are all alone and have to
|
||||
make your own decisions. Up there, it’s all <em>up yours</em>.</p>
|
||||
<p>This code has some jumping too. I used some <code>goto</code>s instead of <code>longjmp(3)</code>. Some
|
||||
Finnish <a href="https://en.wikipedia.org/wiki/Ski_jumping">ski jumping</a> sites are used
|
||||
as labels, however, there is <code>lahti</code> instead of <tt style="font-family: Monaco,
|
||||
Courier New, monospace;font-size: 12px;">salpausselkä</tt>.</p>
|
||||
<h3 id="sha-3-512-compatibility-chart">SHA-3-512 Compatibility
|
||||
chart</h3>
|
||||
<p>Tested against <a
|
||||
href="https://www.di-mgt.com.au/sha_testvectors.html">test
|
||||
vectors</a>.</p>
|
||||
<p>Clang-4.0: For optimization levels [0123s], the program compiles and
|
||||
produces correct output for every tested vector using the C standards
|
||||
c11, c89, c90, c99, gnu11, gnu1x, gnu89, gnu90, gnu99, iso9899:1990,
|
||||
iso9899:199409, iso9899:1999 and iso9899:2011 (argument of
|
||||
<code>-std=</code>).</p>
|
||||
<h3 id="sha-3-512-compatibility-chart">SHA-3-512 Compatibility chart</h3>
|
||||
<p>Tested against <a href="https://www.di-mgt.com.au/sha_testvectors.html">test vectors</a>.</p>
|
||||
<p>Clang-4.0: For optimization levels [0123s], the program compiles and produces
|
||||
correct output for every tested vector using the C standards c11, c89, c90, c99,
|
||||
gnu11, gnu1x, gnu89, gnu90, gnu99, iso9899:1990, iso9899:199409, iso9899:1999
|
||||
and iso9899:2011 (argument of <code>-std=</code>).</p>
|
||||
<p>GCC-6: For optimization level 0, correct output using the C standards
|
||||
c11, c99, gnu11, gnu1x, gnu89, gnu90, gnu99, iso9899:1999 and
|
||||
iso9899:2011.</p>
|
||||
c11, c99, gnu11, gnu1x, gnu89, gnu90, gnu99, iso9899:1999 and iso9899:2011.</p>
|
||||
<h3 id="missing-a-prime">Missing a prime</h3>
|
||||
<p>For obvious reason, the <a
|
||||
href="https://mathworld.wolfram.com/OddPrime.html">oddest prime</a> is
|
||||
missing from output.</p>
|
||||
<p>For obvious reason, the <a href="https://mathworld.wolfram.com/OddPrime.html">oddest
|
||||
prime</a> is missing from output.</p>
|
||||
<h3 id="observations">Observations</h3>
|
||||
<p><code>gcc</code> and <code>clang</code> are very fragile compilers. I
|
||||
spent numerous hours trying to achieve exactly the same output from
|
||||
different optimization levels and compilers. Small change in code can
|
||||
produce really unexpected results, i.e. the compiler can skip a few
|
||||
expressions or statements without obvious reason.</p>
|
||||
<p><code>gcc</code> and <code>clang</code> are very fragile compilers. I spent numerous hours trying to
|
||||
achieve exactly the same output from different optimization levels and
|
||||
compilers. Small change in code can produce really unexpected results, i.e. the
|
||||
compiler can skip a few expressions or statements without obvious reason.</p>
|
||||
<h3 id="major-spoilers">Major spoilers</h3>
|
||||
<p>It is commonly believed that <a
|
||||
href="http://www.cadaeic.net/calendar.htm">Mike Keith’s algorithm</a>
|
||||
published in <em>Journal of Recreational Mathematics</em>, Vol. 22,
|
||||
No. 4, 1990, p. 280, is the shortest way to calculate the day of the
|
||||
week for a given date.</p>
|
||||
<p>It is commonly believed that <a href="http://www.cadaeic.net/calendar.htm">Mike Keith’s
|
||||
algorithm</a> published in <em>Journal of
|
||||
Recreational Mathematics</em>, Vol. 22, No. 4, 1990, p. 280, is the shortest way to
|
||||
calculate the day of the week for a given date.</p>
|
||||
<h4 id="keiths-versus-my-algorithm">Keith’s versus my algorithm</h4>
|
||||
<p>Kieth’s algorithm is
|
||||
<code>(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7</code>. I noticed
|
||||
that <code>(23*m/9+(m<3?y--:y-2)+d+4+y/4-y/100+y/400)%7</code> is one
|
||||
character shorter. In my solution, <code>m<3?y--:y-2</code> is used
|
||||
directly, instead of assigning a value to <code>d</code>.</p>
|
||||
<p><code>Q</code> is pronounced in Finnish exactly like
|
||||
<code>kuu</code>, a word for <a
|
||||
href="https://en.wikipedia.org/wiki/Month">month</a> or the <a
|
||||
href="https://en.wikipedia.org/wiki/Moon">Moon</a>. So,
|
||||
<code>Q = k</code> is intended.</p>
|
||||
<p>Last term of outputted <a
|
||||
href="https://en.wikipedia.org/wiki/Fibonacci_sequence">Fibonacci
|
||||
sequence</a> is the last one smaller than 2<sup>64</sup>. It is a plain
|
||||
but funny coincidence that the value of <code>^</code> is 94 in <a
|
||||
href="https://en.wikipedia.org/wiki/ASCII">ASCII</a>.</p>
|
||||
<p>For <a href="https://en.wikipedia.org/wiki/Prime_number">prime
|
||||
calculations</a>: I recycled code from my high school C-programming
|
||||
course. Originally, I wrote it over 20 years ago. My teacher said that
|
||||
it is (too) complicated to use bits stored in arrays, so I did it.</p>
|
||||
<p>Kieth’s algorithm is <code>(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7</code>. I noticed
|
||||
that <code>(23*m/9+(m<3?y--:y-2)+d+4+y/4-y/100+y/400)%7</code> is one character shorter. In
|
||||
my solution, <code>m<3?y--:y-2</code> is used directly, instead of assigning a value to
|
||||
<code>d</code>.</p>
|
||||
<p><code>Q</code> is pronounced in Finnish exactly like <code>kuu</code>, a word for
|
||||
<a href="https://en.wikipedia.org/wiki/Month">month</a> or the
|
||||
<a href="https://en.wikipedia.org/wiki/Moon">Moon</a>. So, <code>Q = k</code> is intended.</p>
|
||||
<p>Last term of outputted <a href="https://en.wikipedia.org/wiki/Fibonacci_sequence">Fibonacci
|
||||
sequence</a> is the last one
|
||||
smaller than 2<sup>64</sup>. It is a plain but funny coincidence
|
||||
that the value of <code>^</code> is 94 in <a href="https://en.wikipedia.org/wiki/ASCII">ASCII</a>.</p>
|
||||
<p>For <a href="https://en.wikipedia.org/wiki/Prime_number">prime calculations</a>: I recycled
|
||||
code from my high school C-programming course. Originally, I wrote it over 20
|
||||
years ago. My teacher said that it is (too) complicated to use bits stored in
|
||||
arrays, so I did it.</p>
|
||||
<h3 id="other-stuff">Other stuff</h3>
|
||||
<p><a href="../../authors.html#Cody_Boone_Ferguson">Cody Boone
|
||||
Ferguson</a>: I really like that you enjoyed my previous entry. I hope
|
||||
that you will like this entry too. Because I did not want to give too
|
||||
many clues to <a href="../../judges.html">the Judges</a>, I tried to
|
||||
write this entry in a different way than <a
|
||||
href="../../2018/poikola/index.html">Most Stellar</a>, but in this code
|
||||
there is at least one recycled thing from it. By the way, the answers to
|
||||
the questions I posed: (1) 255. (2) Try to compare binary
|
||||
representations of those <code>float</code>s and binary representation
|
||||
of the string “<code>25th IOCCC!</code>”. (3) I don’t know. I used
|
||||
standard <a
|
||||
href="https://en.wikipedia.org/wiki/Trigonometric_functions">trigonometric
|
||||
functions</a> from <a
|
||||
href="https://en.wikipedia.org/wiki/C_mathematical_functions#Overview_of_functions">math.h</a>
|
||||
for rotating the <a href="https://en.wikipedia.org/wiki/Big_Dipper">Big
|
||||
Dipper</a> and later replaced those functions with my own
|
||||
implementations. But there was a bug in my code and the effect was more
|
||||
beautiful than intended. I did not even debug this bug and now it works
|
||||
as a feature. (4) It is not possible. If you change a single bit, the <a
|
||||
href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Fletcher-16">Fletcher’s
|
||||
16 checksum</a> does not match anymore and <code>goto</code> jumps to
|
||||
the end of the code.</p>
|
||||
<p>I see that one of the <a
|
||||
href="../../authors.html#Volker_Diels-Grabsch">Volker
|
||||
Diels-Grabsch</a>’s winning entries is awarded the category <a
|
||||
href="../../2019/diels-grabsch2/prog.c">Most self-aware</a>. In last
|
||||
year, my entry incorporates the <a
|
||||
href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Fletcher-16">Fletcher’s
|
||||
16 algorithm</a> to ensure integrity of code. One of my first ideas for
|
||||
this year was to do the same thing, but with <a
|
||||
href="https://en.wikipedia.org/wiki/SHA-3">SHA-3</a>. Using Fletcher 16,
|
||||
calculating a <a
|
||||
href="https://en.wikipedia.org/wiki/Checksum">checksum</a> which matches
|
||||
with <code>sleeping time factor</code> took about one minute. I realized
|
||||
that SHA-3 even with 224-<a
|
||||
href="https://en.wikipedia.org/wiki/Bit">bit</a> output could take too
|
||||
much <a
|
||||
href="https://en.wikipedia.org/wiki/Central_processing_unit">CPU</a>
|
||||
time.</p>
|
||||
<p>I would like to say <em>thanks</em> to PSP, because there were not
|
||||
too many interruptions during the coding phase.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<p><a href="../../authors.html#Cody_Boone_Ferguson">Cody Boone Ferguson</a>: I really like that you enjoyed my
|
||||
previous entry. I hope that you will like this entry too. Because I did not
|
||||
want to give too many clues to <a href="../../judges.html">the Judges</a>, I tried to write this
|
||||
entry in a different way than <a href="../../2018/poikola/index.html">Most Stellar</a>, but in this
|
||||
code there is at least one recycled thing from it. By the way, the answers to
|
||||
the questions I posed: (1) 255. (2) Try to compare binary representations of
|
||||
those <code>float</code>s and binary representation of the string “<code>25th IOCCC!</code>”. (3) I
|
||||
don’t know. I used standard <a href="https://en.wikipedia.org/wiki/Trigonometric_functions">trigonometric
|
||||
functions</a> from
|
||||
<a href="https://en.wikipedia.org/wiki/C_mathematical_functions#Overview_of_functions">math.h</a>
|
||||
for rotating the <a href="https://en.wikipedia.org/wiki/Big_Dipper">Big Dipper</a> and
|
||||
later replaced those functions with my own implementations. But there was a bug
|
||||
in my code and the effect was more beautiful than intended. I did not even
|
||||
debug this bug and now it works as a feature. (4) It is not possible. If you
|
||||
change a single bit, the <a href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Fletcher-16">Fletcher’s 16
|
||||
checksum</a> does
|
||||
not match anymore and <code>goto</code> jumps to the end of the code.</p>
|
||||
<p>I see that one of the <a href="../../authors.html#Volker_Diels-Grabsch">Volker
|
||||
Diels-Grabsch</a>’s winning entries is
|
||||
awarded the category <a href="../../2019/diels-grabsch2/prog.c">Most self-aware</a>. In last
|
||||
year, my entry incorporates the <a href="https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Fletcher-16">Fletcher’s 16
|
||||
algorithm</a> to
|
||||
ensure integrity of code. One of my first ideas for this year was to do the same
|
||||
thing, but with <a href="https://en.wikipedia.org/wiki/SHA-3">SHA-3</a>. Using Fletcher 16,
|
||||
calculating a <a href="https://en.wikipedia.org/wiki/Checksum">checksum</a> which matches
|
||||
with <code>sleeping time factor</code> took about one minute. I realized that SHA-3 even
|
||||
with 224-<a href="https://en.wikipedia.org/wiki/Bit">bit</a> output could take too much
|
||||
<a href="https://en.wikipedia.org/wiki/Central_processing_unit">CPU</a> time.</p>
|
||||
<p>I would like to say <em>thanks</em> to PSP, because there were not too many
|
||||
interruptions during the coding phase.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019poikola"><a name="inventory"></a>Inventory for
|
||||
2019/poikola</h1>
|
||||
<h1 id="inventory-for-2019poikola"><a name="inventory"></a>Inventory for 2019/poikola</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/prog.alt.c">prog.alt.c</a>
|
||||
- alternative source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/poikola.tex">poikola.tex</a>
|
||||
- supplied documentation</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/try.alt.sh">try.alt.sh</a>
|
||||
- how to run alternative code</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a href="2019_poikola.tar.bz2">2019_poikola.tar.bz2</a> - download
|
||||
entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/prog.alt.c">prog.alt.c</a> - alternative source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/poikola.tex">poikola.tex</a> - supplied documentation</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/try.alt.sh">try.alt.sh</a> - how to run alternative code</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="2019_poikola.tar.bz2">2019_poikola.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/poikola/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
+76
-115
@@ -130,8 +130,8 @@
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Don_Yang">Don Yang</a><br>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of
|
||||
America</em> (<em>United States</em>) <br><br></li>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -144,8 +144,7 @@ America</em> (<em>United States</em>) <br><br></li>
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2019_yang">2019 yang bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2019_yang">2019 yang bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> sample_input.txt a b c d</span>
|
||||
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
@@ -161,8 +160,8 @@ href="../../bugs.html#2019_yang">2019 yang bugs</a>.</p>
|
||||
<h2 id="try">Try:</h2>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>Do you understand how this program works? You may have to go over and
|
||||
over the output again.</p>
|
||||
<p>Do you understand how this program works? You may have to go over and over the
|
||||
output again.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<h3 id="summary">Summary:</h3>
|
||||
<p>Scramble/unscramble to single file:</p>
|
||||
@@ -181,85 +180,74 @@ over the output again.</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="kw">|</span> <span class="ex">ruby</span> prog.c</span></code></pre></div>
|
||||
<p>Input must be in UTF-8 encoding.</p>
|
||||
<h3 id="details">Details:</h3>
|
||||
<p>This is a text scrambling utility. To scramble text, specify input
|
||||
file name as the first argument:</p>
|
||||
<p>This is a text scrambling utility. To scramble text, specify input file name as
|
||||
the first argument:</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="op">></span> output.txt</span></code></pre></div>
|
||||
<p>If original input file was small enough to fit in your terminal, you
|
||||
can simply use <code>cat</code> to unscramble the output text.</p>
|
||||
<div class="sourceCode" id="cb10"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cat</span> output.txt</span></code></pre></div>
|
||||
<p>It might seem like nothing was scrambled, but you can try passing the
|
||||
output through <code>strings(1)</code> and see that most of the original
|
||||
strings are gone. What happened is that the original text has been
|
||||
shuffled with ANSI cursor positioning codes inserted in such a way that
|
||||
characters are printed in random order. This effect is more visible if
|
||||
there is a delay after each character is printed. For convenience, a
|
||||
utility is included in the source to output characters slowly:</p>
|
||||
<div class="sourceCode" id="cb11"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="kw">|</span> <span class="ex">ruby</span> prog.c</span></code></pre></div>
|
||||
<p>Scrambling order is deterministic, but you can reshuffle the output
|
||||
by piping it through the same utility again, by specifying
|
||||
<code>-</code> as the first argument:</p>
|
||||
<div class="sourceCode" id="cb12"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="kw">|</span> <span class="ex">./prog</span> <span class="at">-</span> <span class="kw">|</span> <span class="ex">./prog</span> <span class="at">-</span> <span class="kw">|</span> <span class="ex">...</span></span></code></pre></div>
|
||||
<div class="sourceCode" id="cb10"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cat</span> output.txt</span></code></pre></div>
|
||||
<p>It might seem like nothing was scrambled, but you can try passing the output
|
||||
through <code>strings(1)</code> and see that most of the original strings are gone. What
|
||||
happened is that the original text has been shuffled with ANSI cursor
|
||||
positioning codes inserted in such a way that characters are printed in random
|
||||
order. This effect is more visible if there is a delay after each character is
|
||||
printed. For convenience, a utility is included in the source to output
|
||||
characters slowly:</p>
|
||||
<div class="sourceCode" id="cb11"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="kw">|</span> <span class="ex">ruby</span> prog.c</span></code></pre></div>
|
||||
<p>Scrambling order is deterministic, but you can reshuffle the output by
|
||||
piping it through the same utility again, by specifying <code>-</code> as the
|
||||
first argument:</p>
|
||||
<div class="sourceCode" id="cb12"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="kw">|</span> <span class="ex">./prog</span> <span class="at">-</span> <span class="kw">|</span> <span class="ex">./prog</span> <span class="at">-</span> <span class="kw">|</span> <span class="ex">...</span></span></code></pre></div>
|
||||
<p>You can also split the input to multiple files, each getting a subset
|
||||
of the original input characters:</p>
|
||||
<div class="sourceCode" id="cb13"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt output1.txt output2.txt ...</span>
|
||||
<div class="sourceCode" id="cb13"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt output1.txt output2.txt ...</span>
|
||||
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="fu">cat</span> output1.txt output2.txt ... <span class="op">></span> unscrambled.txt</span></code></pre></div>
|
||||
<p>You can only unscramble files with <code>cat</code> if the input fits
|
||||
in a single terminal screen. If you don’t know what will be the terminal
|
||||
size of the recipient, note that <code>prog.c</code> will fit in a 80x25
|
||||
terminal, so a good guideline is to pick files that have fewer rows and
|
||||
columns than <code>prog.c</code>.</p>
|
||||
<p>For files that are larger than your terminal window, <code>cat</code>
|
||||
will not be sufficient for unscrambling because any scrolling causes the
|
||||
character positions to be misaligned. But fear not, this utility also
|
||||
includes unscrambling functionality. If no argument is specified, input
|
||||
will be read through <code>stdin</code> and unscrambled to
|
||||
<code>stdout</code>:</p>
|
||||
<div class="sourceCode" id="cb14"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> scrambled.txt <span class="op">></span> unscrambled.txt</span></code></pre></div>
|
||||
<p>You can only unscramble files with <code>cat</code> if the input fits in a single
|
||||
terminal screen. If you don’t know what will be the terminal size of
|
||||
the recipient, note that <code>prog.c</code> will fit in a 80x25 terminal, so a
|
||||
good guideline is to pick files that have fewer rows and columns than
|
||||
<code>prog.c</code>.</p>
|
||||
<p>For files that are larger than your terminal window, <code>cat</code> will not be
|
||||
sufficient for unscrambling because any scrolling causes the character
|
||||
positions to be misaligned. But fear not, this utility also includes
|
||||
unscrambling functionality. If no argument is specified, input will
|
||||
be read through <code>stdin</code> and unscrambled to <code>stdout</code>:</p>
|
||||
<div class="sourceCode" id="cb14"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> scrambled.txt <span class="op">></span> unscrambled.txt</span></code></pre></div>
|
||||
<p>Where this is useful is that if you scramble the input to multiple
|
||||
files and unscramble each output file individually, those output files
|
||||
can be printed on transparencies and distributed separately.</p>
|
||||
<div class="sourceCode" id="cb15"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt output1.txt output2.txt output3.txt</span>
|
||||
files and unscramble each output file individually, those output
|
||||
files can be printed on transparencies and distributed separately.</p>
|
||||
<div class="sourceCode" id="cb15"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt output1.txt output2.txt output3.txt</span>
|
||||
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> output1.txt <span class="op">></span> layer1.txt</span>
|
||||
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> output2.txt <span class="op">></span> layer2.txt</span>
|
||||
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> <span class="op"><</span> output3.txt <span class="op">></span> layer3.txt</span></code></pre></div>
|
||||
<p>In other words, this is a utility for facilitating <a
|
||||
href="https://en.wikipedia.org/wiki/Visual_cryptography">visual
|
||||
cryptography</a>.</p>
|
||||
<p>In other words, this is a utility for facilitating
|
||||
<a href="https://en.wikipedia.org/wiki/Visual_cryptography">visual cryptography</a>.</p>
|
||||
<p>This utility can also be used just for removing trailing whitespaces
|
||||
and expanding tabs to 8 spaces.</p>
|
||||
<div class="sourceCode" id="cb16"><pre
|
||||
class="sourceCode sh"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="kw">|</span> <span class="ex">./prog</span></span></code></pre></div>
|
||||
<div class="sourceCode" id="cb16"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span> input.txt <span class="kw">|</span> <span class="ex">./prog</span></span></code></pre></div>
|
||||
<h3 id="features">Features:</h3>
|
||||
<h4 id="utf-8-support">UTF-8 support:</h4>
|
||||
<p>A simple text scrambling utility might not have required a screenful
|
||||
of code, but this particular one natively supports UTF-8. Specifically:
|
||||
individual UTF-8 byte sequences will not be split into broken ones, and
|
||||
the utility is aware of full-width versus half-width differences such
|
||||
that the cursor is positioned correctly for most CJK input. <a
|
||||
href="sample_input.txt">sample_input.txt</a> demonstrates this feature
|
||||
with a mix of Basic Latin and Japanese characters.</p>
|
||||
of code, but this particular one natively supports UTF-8.
|
||||
Specifically: individual UTF-8 byte sequences will not be split into
|
||||
broken ones, and the utility is aware of full-width versus half-width
|
||||
differences such that the cursor is positioned correctly for most CJK
|
||||
input. <a href="sample_input.txt">sample_input.txt</a> demonstrates this feature with a mix of
|
||||
Basic Latin and Japanese characters.</p>
|
||||
<p>Output cursor positions will most definitely be wrong for inputs
|
||||
containing combining characters and right-to-left text, but it should be
|
||||
possible to unscramble those text back to the original using this same
|
||||
utility, since the utility is self-consistent in how cursor positions
|
||||
are handled.</p>
|
||||
containing combining characters and right-to-left text, but it should
|
||||
be possible to unscramble those text back to the original using this
|
||||
same utility, since the utility is self-consistent in how cursor
|
||||
positions are handled.</p>
|
||||
<h3 id="error-handling">Error handling</h3>
|
||||
<p>If any file can not be opened for reading or writing, an error is
|
||||
printed to <code>stderr</code>, and the utility will exit with nonzero
|
||||
status.</p>
|
||||
printed to <code>stderr</code>, and the utility will exit with nonzero status.</p>
|
||||
<p>If there isn’t enough memory, the utility will likely crash.</p>
|
||||
<p>If input contains CR-LF end of line sequences, those <code>CR</code>s
|
||||
are silently dropped. In fact, most control codes are silently ignored
|
||||
except line feeds (preserved) and tabs (expanded to 8 spaces).</p>
|
||||
<p>If input contains CR-LF end of line sequences, those <code>CR</code>s are silently
|
||||
dropped. In fact, most control codes are silently ignored except line
|
||||
feeds (preserved) and tabs (expanded to 8 spaces).</p>
|
||||
<h3 id="compatibility">Compatibility</h3>
|
||||
<p>Verified to work and compiles without warnings on these
|
||||
environments:</p>
|
||||
<p>Verified to work and compiles without warnings on these environments:</p>
|
||||
<ul>
|
||||
<li>gcc 7.3.0 on Linux</li>
|
||||
<li>gcc 7.4.0 on Cygwin</li>
|
||||
@@ -268,72 +256,45 @@ environments:</p>
|
||||
<li>gcc 4.8.4 on Linux</li>
|
||||
</ul>
|
||||
<h3 id="full-version">Full version</h3>
|
||||
<p>I tried really hard to make <code>prog.c</code> fit in a 80x25
|
||||
terminal without wrapping. If I were not constrained by space, I would
|
||||
have made an ASCII art out of it. <a href="violet.c">violet.c</a> is
|
||||
that program, and also comes with the minor benefit of supporting lines
|
||||
longer than a million columns depending on <code>sizeof(int)</code>.</p>
|
||||
<p>Violet is named after <a
|
||||
href="https://en.wikipedia.org/wiki/Violet_Evergarden">Violet
|
||||
Evergarden</a> in the story with the same name, the character who is
|
||||
highly skilled in writing letters.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<p>I tried really hard to make <code>prog.c</code> fit in a 80x25 terminal without wrapping.
|
||||
If I were not constrained by space, I would have made an ASCII art out of it.
|
||||
<a href="violet.c">violet.c</a> is that program, and also comes with the minor benefit of
|
||||
supporting lines longer than a million columns depending on <code>sizeof(int)</code>.</p>
|
||||
<p>Violet is named after <a href="https://en.wikipedia.org/wiki/Violet_Evergarden">Violet
|
||||
Evergarden</a> in the story with
|
||||
the same name, the character who is highly skilled in writing letters.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2019yang"><a name="inventory"></a>Inventory for
|
||||
2019/yang</h1>
|
||||
<h1 id="inventory-for-2019yang"><a name="inventory"></a>Inventory for 2019/yang</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/ioccc.txt">ioccc.txt</a>
|
||||
- sample input</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/sample_input.txt">sample_input.txt</a>
|
||||
- sample input</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/violet.c">violet.c</a>
|
||||
- source formatter as ASCII Violet Evergarden</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/ioccc.txt">ioccc.txt</a> - sample input</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/sample_input.txt">sample_input.txt</a> - sample input</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/violet.c">violet.c</a> - source formatter as ASCII Violet Evergarden</li>
|
||||
<li><a href="spoiler.html">spoiler.html</a> - SPOILER WARNING</li>
|
||||
<li><a href="2019_yang.tar.bz2">2019_yang.tar.bz2</a> - download entry
|
||||
source</li>
|
||||
<li><a href="2019_yang.tar.bz2">2019_yang.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2019/yang/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
Reference in new issue
Block a user