Files
ioccc/2024/endoh1/index.html
T
Cody Boone Ferguson 09ff59ee85 Various typos in 2024/
The following files (not all of these files were checked yet) were
modified (when mentioning README.md I also rebuilt the index.html file):

    2024/burton/README.md
    2024/endoh1/README.md
    2024/endoh1/try.sh
2025-08-08 02:57:17 -07:00

923 lines
37 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- START: two lines up starts content from: inc/top.default.html -->
<!-- END: this line ends content from: inc/top.default.html -->
<!-- START: this line starts content from: inc/head.default.html -->
<head>
<link rel="stylesheet" href="../../ioccc.css">
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>2024/endoh1 - Prize in patient pointillism</title>
<link rel="icon" type="image/x-icon" href="../../favicon.ico">
<meta name="description" content="2024 IOCCC entry endoh1 - Prize in patient pointillism">
<meta name="keywords" content="IOCCC, 2024, IOCCC 2024, IOCCC entry, endoh1, Prize in patient pointillism">
</head>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- END: this line ends content from: inc/head.default.html -->
<!-- -->
<!-- This web page was formed via the tool: bin/readme2index.sh -->
<!-- The content of main section of this web page came from: 2024/endoh1/README.md -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2024/endoh1/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2024/endoh1/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2024/endoh1/README.md !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- Markdown content was converted into HTML via the tool: bin/md2html.sh -->
<!-- START: this line starts content from: inc/body.default.html -->
<body>
<!-- END: this line ends content from: inc/body.default.html -->
<!-- START: this line starts content from: inc/topbar.default.html -->
<div class="theader">
<nav class="topbar">
<div class="container">
<div class="logo">
<a href="../../index.html" class="logo-link">
IOCCC
</a>
</div>
<div class="topbar-items">
<div class="item">
<span class="item-header">
Entries
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../years.html" class="sub-item-link">
Winning entries
</a>
</div>
<div class="outfit-font">
<a href="../../authors.html" class="sub-item-link">
Winning authors
</a>
</div>
<div class="outfit-font">
<a href="../../location.html" class="sub-item-link">
Location of authors
</a>
</div>
<div class="outfit-font">
<a href="../../bugs.html" class="sub-item-link">
Bugs and (mis)features
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_an_entry" class="sub-item-link">
Fixing entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_author" class="sub-item-link">
Updating author info
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
Status
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../news.html" class="sub-item-link">
News
</a>
</div>
<div class="outfit-font">
<a href="../../status.html" class="sub-item-link">
Contest status
</a>
</div>
<div class="outfit-font">
<a href="../../next/rules.html" class="sub-item-link">
IOCCC rules
</a>
</div>
<div class="outfit-font">
<a href="../../next/guidelines.html" class="sub-item-link">
IOCCC guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../markdown.html" class="sub-item-link">
Markdown guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../SECURITY.html" class="sub-item-link">
Security policy
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
FAQ
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../faq.html" class="sub-item-link">
Frequently asked questions
</a>
</div>
<div class="outfit-font">
<a href="../../quick-start.html#enter" class="sub-item-link">
Enter the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#compiling" class="sub-item-link">
Compiling entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#running_entries" class="sub-item-link">
Running entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#help" class="sub-item-link">
How to help
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
About
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../index.html" class="sub-item-link">
Home page
</a>
</div>
<div class="outfit-font">
<a href="../../social.html" class="sub-item-link">
IOCCC social media
</a>
</div>
<div class="outfit-font">
<a href="../../about.html" class="sub-item-link">
About the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../judges.html" class="sub-item-link">
The judges
</a>
</div>
<div class="outfit-font">
<a href="../../thanks-for-help.html" class="sub-item-link">
Thanks for the help
</a>
</div>
<div class="outfit-font">
<a href="../../contact.html" class="sub-item-link">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</nav>
<div class="header-mobile-menu">
<noscript>
<a href="../../nojs-menu.html" class="topbar-js-label">
Please Enable JavaScript
</a>
</noscript>
<button id="header-open-menu-button" class="topbar-mobile-menu">
<img
src="../../png/hamburger-icon-open.png"
alt="hamburger style menu icon - open state"
width=48
height=48>
</button>
<button id="header-close-menu-button" class="hide-content">
<img
src="../../png/hamburger-icon-closed.png"
alt="hamburger style menu icon - closed state"
width=48
height=48>
</button>
<div id="mobile-menu-panel" class="hide-content">
<div class="mobile-menu-container">
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Entries
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../years.html">
Winning entries
</a>
<a class="mobile-submenu-item" href="../../authors.html">
Winning authors
</a>
<a class="mobile-submenu-item" href="../../location.html">
Location of authors
</a>
<a class="mobile-submenu-item" href="../../bugs.html">
Bugs and (mis)features
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_an_entry">
Fixing entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_author">
Updating author info
</a>
<a class="mobile-submenu-item" href="../../thanks-for-help.html">
Thanks for the help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Status
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../news.html">
News
</a>
<a class="mobile-submenu-item" href="../../status.html">
Contest status
</a>
<a class="mobile-submenu-item" href="../../next/rules.html">
IOCCC rules
</a>
<a class="mobile-submenu-item" href="../../next/guidelines.html">
IOCCC guidelines
</a>
<a class="mobile-submenu-item" href="../../markdown.html">
Markdown guidelines
</a>
<a class="mobile-submenu-item" href="../../SECURITY.html">
Security policy
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
FAQ
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../faq.html">
Frequently asked questions
</a>
<a class="mobile-submenu-item" href="../../quick-start.html#enter">
Enter the IOCCC
</a>
<a class="mobile-submenu-item" href="../../faq.html#compiling">
Compiling entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#running_entries">
Running entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#help">
How to help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
About
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../index.html">
Home page
</a>
<a class="mobile-submenu-item" href="../../social.html">
IOCCC social media
</a>
<a class="mobile-submenu-item" href="../../about.html">
About the IOCCC
</a>
<a class="mobile-submenu-item" href="../../judges.html">
The judges
</a>
<a class="mobile-submenu-item" href="../../contact.html">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var headerOpenMenuButton = document.getElementById("header-open-menu-button");
var headerCloseMenuButton = document.getElementById("header-close-menu-button");
var mobileMenuPanel = document.getElementById("mobile-menu-panel");
headerOpenMenuButton.addEventListener("click", () => {
headerOpenMenuButton.classList.remove("topbar-mobile-menu");
headerOpenMenuButton.classList.add("hide-content");
headerCloseMenuButton.classList.remove("hide-content");
headerCloseMenuButton.classList.add("topbar-mobile-menu");
mobileMenuPanel.classList.remove("hide-content");
mobileMenuPanel.classList.add("topbar-mobile-panel");
});
headerCloseMenuButton.addEventListener("click", () => {
headerCloseMenuButton.classList.remove("topbar-mobile-menu");
headerCloseMenuButton.classList.add("hide-content");
mobileMenuPanel.classList.add("hide-content");
mobileMenuPanel.classList.remove("topbar-mobile-panel");
headerOpenMenuButton.classList.add("topbar-mobile-menu");
headerOpenMenuButton.classList.remove("hide-content");
});
</script>
<!-- END: this line ends content from: inc/topbar.default.html -->
<!-- START: this line starts content from: inc/header.default.html -->
<div class="header">
<a href="../../2011/zucker/index.html">
<img src="../../png/ioccc.png"
alt="IOCCC image by Matt Zucker"
width=300
height=110>
</a>
<h1>The International Obfuscated C Code Contest</h1>
<h2>2024/endoh1 - Prize in patient pointillism</h2>
<h3>slow ray tracer in CPP</h3>
</div>
<!-- END: this line ends content from: inc/header.default.html -->
<!-- START: this line starts content from: inc/navbar.mid.html -->
<div class="navbar">
<a class="Left" href="../codemeow/index.html">&larr; 2024/codemeow</a>
<a class="Left" href="../index.html">&uarr; 2024 &uarr;</a>
<a class="Left" href="../endoh2/index.html">2024/endoh2 &rarr;</a>
<a class="Right" href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/prog.c">C code</a>
<a class="Right" href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/Makefile">Makefile</a>
<a class="Right" href="#inventory">Inventory</a>
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2024%2Fendoh1%2Findex.html">&#x2713;</a>
</div>
<!-- END: this line ends content from: inc/navbar.mid.html -->
<!-- START: this line starts content from: inc/before-content.default.html -->
<div class="content" id="content">
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-author.sh -->
<h2 id="author">Author:</h2>
<ul>
<li>Name: <a href="../../authors.html#Yusuke_Endoh">Yusuke Endoh</a><br>
Location: <a href="../../location.html#JP">JP</a> - <em>Japan</em></li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
<!-- END: this line ends content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- BEFORE: 1st line of markdown file: 2024/endoh1/README.md -->
<h2 id="award-presentation">Award presentation:</h2>
<p>Watch the <a href="https://www.youtube.com/@OurFavoriteUniverse">Our Favorite Universe</a>
YouTube show for this entry:</p>
<blockquote>
<p><a href="https://www.youtube.com/watch?v=-BORKHexSPM">IOCCC28 - 2024/endoh1 - Prize in patient pointillism</a></p>
</blockquote>
<h2 id="to-build">To build:</h2>
<pre><code> make all</code></pre>
<h2 id="try">Try:</h2>
<pre><code> ./try.sh</code></pre>
<p><strong>HINT</strong>: You have to be <strong>VERY</strong> patient while the above script runs to completion.</p>
<h2 id="judges-remarks">Judges’ remarks:</h2>
<p>When you <code>make all</code> you see what looks like a C program, <code>rt.c</code>.
However if you try to compile <code>rt.c</code>, you will fail: even if you try to
define the symbols <code>X</code>, <code>Y</code>, <code>W</code>, and <code>H</code>.</p>
<p>Well, the purpose of the C program, <code>rt.c</code> is to generate the red, green, and blue colors of
a single pixel, in the C Preprocessor!!!</p>
<p>For the patient, an image may be rendered a slow pixel at a time.
Think of this as digital <a href="https://en.wikipedia.org/wiki/Pointillism">Pointillism</a>. :-)</p>
<p>For the truly impatient who wishes to get right to the point without trying to dot around
waiting for the <a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/try.sh">try.sh</a> to finish, you may view these images:</p>
<ul>
<li><a href="ref.8.png">tiny 8x8 image</a></li>
<li><a href="ref.32.png">small 32x32 image</a></li>
<li><a href="ref.128.png">medium 128x128 image</a></li>
<li><a href="ref.512.png">large 512x512 image</a></li>
</ul>
<p><strong>FUN FACT</strong>: We were able to determine on an “<em>x86-64 processor</em>” running
“<em>RHEL 9.6</em>” using “<em>gcc version 11.5.0</em>”, one could theoretically render
a <strong>2147483647 x 2147483647</strong> pixel image. At the rate it took to render
the <strong>512 x 512</strong> pixel image, and without using any parallelism, such an
image would take about <strong>169 billion years</strong> to fully render on a single
CPU core! Fully rendering such large images is <strong>NOT</strong> recommended. :-)</p>
<h3 id="parallel-make">Parallel make</h3>
<p><strong>SUGGESTION</strong>: The <a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/Makefile">2024/endoh1/Makefile</a>,
by default, uses a single CPU core, can make use of parallel operations.
If you have access to a “<em>parallel make</em>”, can achieve the above in a shorter
around of time. If you have “<em>n</em>” CPU cores available, consider running
a parallel make with “<em>n-1</em>” jobs that run simultaneously. For example:</p>
<pre><code> RESERVE=&quot;-2&quot;
NPROC=$(nproc)
((JOBS=NPROC-RESERVE))
SIZE=512
make clobber all
nohup time make -j &quot;$JOBS&quot; out.ppm H=&quot;$SIZE&quot; W=&quot;$SIZE&quot; &gt; make.out 2&gt;&amp;1 &lt; /dev/null &amp;</code></pre>
<p>Where <code>SIZE</code> is the size of the image to generate.</p>
<p>Where <code>RESERVE</code> is the number of CPU cores to reserve for other things
such as the operating system, daemons, terminal window, etc. You can even
“<em>oversubscribe</em>” by setting RESERVE to a negative number (e.g., <code>RESERVE="-2"</code>).</p>
<p><strong>NOTE</strong>: The <a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/try.sh">try.sh</a> script follows the above
example for <code>SIZE</code> values of 8, 32, 128, and then 512.</p>
<p>The optimal <code>RESERVE</code> will depend on your hardware, operating system,
a C compiler. Making <code>RESERVE</code> too small (i.e., too negative) may slow
down the result. We recommend that experiment various values of <code>RESERVE</code>
with moderate <code>SIZE</code> of <strong>32</strong> in order to try to find an optimal <code>JOBS</code>
value before attempting to try a larger size such as <strong>512</strong> and beyond.</p>
<div id="larger">
<h3 id="be-first-to-build-images-larger-than-512x512">Be first to build images larger than 512x512</h3>
</div>
<p><strong>QUESTION</strong>: Do you have the patience to build an even larger than a 512x512 image?
If you do, <strong>using the program as it is written of course</strong>, please <a href="../../judges.html">send the IOCCC</a>
the following:</p>
<ul>
<li>Image Height x Width in pixels</li>
<li>URL of the fully rendered image (in PPM form or better yet converted to PNG)</li>
<li>How long it took (perhaps using the time(1) command or using the <code>time</code> shell builtin)</li>
<li>The starting and ending dates (using <code>date -u</code>) of your rendering</li>
<li>Number of CPU cores, Operating system, Compiler, Compiler version, and make version</li>
<li>The number of jobs you ran in parallel</li>
<li>Anything else you may have done to optimize</li>
<li>Your name, (GitHub handle (optional)), (Mastodon handle (optional)), (home page URL (optional)), Country (or XX to be anonymous)</li>
</ul>
<p><strong>PLEASE</strong> do not attempt to optimize the general algorithm used by this entry to build PPM images.
Please remain “<em>faithful to the spirit</em>” of this wonderful entry when attempting to build larger PPM images.</p>
<p>The first people to render a new record sized image <strong>using the general algorithm used by this entry</strong>,
will be given credit in the <a href="../../thanks-for-help.html">thanks for the help</a> web page.</p>
<h2 id="authors-remarks">Author’s remarks:</h2>
<h3 id="a-ray-tracer-in-the-c-preprocessor">A Ray Tracer in the C Preprocessor</h3>
<p>Ever since the iconic 1988 IOCCC winning entry <a href="../../1988/applin/index.html">1988/applin</a>,
bending the C preprocessor to one’s will has been a time-honored tradition in the IOCCC.
This entry sets out to be the culmination of that legacy: a ray tracer implemented entirely with C macros!</p>
<h4 id="how-to-run">How to Run</h4>
<p>The initial program, <code>./prog</code> (compiled from <code>prog.c</code>), outputs the main code, <code>rt.c</code>.
To get started, compile and execute it:</p>
<pre><code> make all</code></pre>
<p>Note: <code>rt.c</code> is not a valid C program – it’s written for C preprocessor.</p>
<p>To get the color of a single pixel at position (16, 16) in a 32 x 32 image, run:</p>
<pre><code> cc -E -P -DX=16 -DY=16 -DW=32 -DH=32 rt.c</code></pre>
<p>This will produce:</p>
<pre><code> 129
62
129</code></pre>
<p>These three values represent the red, green, and blue components respectively.</p>
<ul>
<li>Red = 129 (0x81)</li>
<li>Green = 62 (0x3e)</li>
<li>Blue = 129 (0x81)</li>
</ul>
<p>In other words, this indicates that the pixel at position (16, 16) has the color #813e81.</p>
<h4 id="how-to-generate-the-full-image">How to Generate the Full Image</h4>
<p>To generate the entire image, you need to run the preprocessor for every pixel.
For example, to form a 32x32 image:</p>
<pre><code> mkdir -p pixel
cc -E -P -DX=0 -DY=0 -DW=32 -DH=32 rt.c &gt; pixel/pixel-00-00.txt
cc -E -P -DX=1 -DY=0 -DW=32 -DH=32 rt.c &gt; pixel/pixel-00-01.txt
cc -E -P -DX=2 -DY=0 -DW=32 -DH=32 rt.c &gt; pixel/pixel-00-02.txt
...
cc -E -P -DX=30 -DY=0 -DW=32 -DH=32 rt.c &gt; pixel/pixel-00-30.txt
cc -E -P -DX=31 -DY=0 -DW=32 -DH=32 rt.c &gt; pixel/pixel-00-31.txt
cc -E -P -DX=0 -DY=1 -DW=32 -DH=32 rt.c &gt; pixel/pixel-01-00.txt
cc -E -P -DX=1 -DY=1 -DW=32 -DH=32 rt.c &gt; pixel/pixel-01-01.txt
cc -E -P -DX=2 -DY=1 -DW=32 -DH=32 rt.c &gt; pixel/pixel-01-02.txt
...
cc -E -P -DX=30 -DY=31 -DW=32 -DH=32 rt.c &gt; pixel/pixel-31-30.txt
cc -E -P -DX=31 -DY=31 -DW=32 -DH=32 rt.c &gt; pixel/pixel-31-31.txt</code></pre>
<p>Then, concatenate the results with a PPM header to create the image:</p>
<pre><code> echo P3 32 32 &gt; out.ppm
echo 255 &gt;&gt; out.ppm
find pixel -type f -print | LANG=C sort | xargs cat &gt;&gt; out.ppm</code></pre>
<p>Now open <code>out.ppm</code> with any image viewer that supports the PPM format.</p>
<h4 id="automating-with-makefile">Automating with Makefile</h4>
<p>To form a 32x32 image:</p>
<pre><code> make clean targets out.ppm H=32 W=32</code></pre>
<p>Now open <code>out.ppm</code> with any image viewer that supports the PPM format.</p>
<h4 id="generating-a-larger-image">Generating a Larger Image</h4>
<p>To form a 256x256 image:</p>
<pre><code> make clean targets out.ppm H=256 W=256</code></pre>
<p>Now open <code>out.ppm</code> with any image viewer that supports the PPM format.</p>
<p>For reference, the 512x512 image took about 10 hours to render.</p>
<h4 id="technical-challenges">Technical Challenges</h4>
<p>Below is a technical explanation of the implementation.</p>
<h5 id="copying-a-macro-definition">Copying a Macro Definition</h5>
<p>One core challenges was how to “copy” the value of a macro.</p>
<p>For example, in C macros:</p>
<pre><code> #define X 10
#define Y X
#undef X
#define X 20
Y // expands to &quot;20&quot;, not &quot;10&quot;</code></pre>
<p>The C preprocessor uses lazy evaluation, meaning macro values are always resolved at the time of use.
With this observation, some people claim it’s impossible to copy a macro’s value.</p>
<p>One known workaround is encoding one bit by whether or not a macro is defined (as seen in <code>applin.c</code> from IOCCC 1988 and <code>vik2.c</code> from IOCCC 2004).
However, this approach is too inefficient for our purposes – ray tracing requires operations like multiplication, and even square root.</p>
<p>Instead, we discovered an efficient way to “copy” a macro’s value.
The key observation is that <code>#if</code> eagerly evaluates the definition of a macro at that point in preprocessing.
For example:</p>
<pre><code> #if X % 2
# define X_b0 1 // The LSB of X is 1
#else
# define X_b0 0 // The LSB of X is 0
#endif</code></pre>
<p>This technique copies the least significant bit of <code>X</code>.
By applying this for each bit, we can reconstruct the full value:</p>
<pre><code> #define X 10
#if X % 2
# define X_b0 1
#else
# define X_b0 0
#endif
#if X / 2 % 2
# define X_b1 2
#else
# define X_b1 0
#endif
#if X / 4 % 2
# define X_b2 4
#else
# define X_b2 0
#endif
...
#define Y (X_b0 + X_b1 + X_b2 + ...)
#undef X
#define X 20
Y // replaced with &quot;0 + 2 + 0 + 8 + ...&quot; = 10</code></pre>
<p>Even if <code>X</code> is later redefined, <code>Y</code> remains unchanged.</p>
<p>This technique resembles <a href="https://en.wikipedia.org/wiki/Information_flow_(information_theory)">“information flow”</a> in the information security.
To our best knowledge, there has been no literature that mentions this technique in terms of the C preprocessor programming.</p>
<h5 id="macro-expansion-explosion">Macro Expansion Explosion</h5>
<p>Using macros for complex expressions often causes memory issues.</p>
<p>For instance, consider this Newton’s method implementation for square roots:</p>
<pre><code> #define sqrt0(x, guess) (guess ? (x/guess+guess)/2 : 0)
#define sqrt(x) sqrt0(x,sqrt0(x,sqrt0(x,sqrt0(x,sqrt0(x,10000)))))</code></pre>
<p>The subroutine <code>sqrt0</code> is one step of Newton’s method, and <code>sqrt</code> applies it five times.
There are three occurences of the argument <code>guess</code> in the body of <code>sqrt0</code>.
Thus, applying <code>sqrt</code> repeats its argument expression at least 5^3 = 243 times.
This easily leads to the explosion of macro expansion.</p>
<p>We avoid this issue by using the earlier “copy” trick – reducing the size of macro expansions by materializing their values.</p>
<h5 id="encoding-vectors">Encoding Vectors</h5>
<p>In theory, it is trivial to encode a 3D vector in the C preprocessor: you can just define three macros for x, y, and z components.
However, it creates bloated code – unsuitable for IOCCC size limits.</p>
<p>Instead, we encode vectors as simple tuples:</p>
<pre><code> #define vec 1,2,3</code></pre>
<p>The vector projection can be implemented as follows.</p>
<pre><code> #define fst(x,y,z) x
#define snd(x,y,z) y
#define thd(x,y,z) z
#define call(f,a) f(a)</code></pre>
<p>Example usage:</p>
<pre><code> call(fst, vec) // expands to 1
call(snd, vec) // expands to 2
call(thd, vec) // expands to 3</code></pre>
<p>The auxiliary macro <code>call</code> is required.
This is a hassle of the C preprocessor, but, <code>call(fst, vec)</code> is expanded to <code>fst(1,2,3)</code>, which results in <code>1</code>.</p>
<p>We can define a vector addition by using the projections.</p>
<pre><code> #define vec3_add(a,b) fst(a)+fst(b),snd(a)+snd(b),thd(a)+thd(b)</code></pre>
<p>Now, we can simply write <code>vec3_add(v1, v2)</code> to add two vectors.
One identifier represents one vector.
It is also elegantly possible to nest expressions like <code>vec3_add(v1, vec3_add(v1, v2))</code>.</p>
<pre><code> #define v1 0,1,2
#define v2 2,1,0
int main() {
printf(&quot;(%d %d %d)\n&quot;, vec3_add(v1, v2)); // prints &quot;(2 2 2)&quot;
printf(&quot;(%d %d %d)\n&quot;, vec3_add(v1, vec3_add(v1, v2))); // prints &quot;(2 3 4)&quot;
}</code></pre>
<h5 id="ray-tracing-via-self-inclusion">Ray Tracing via Self-Inclusion</h5>
<p>Ray tracing involves recursive calls for reflection.
In <code>rt.c</code>, this is done via:</p>
<pre><code> #include __FILE__</code></pre>
<p>In the implementation, only spheres reflect rays, and only one sphere exists.
Thus, the recursion depth is limited to one.</p>
<p>Theoretically, it is possible to support multiple reflections, but this would require implementing a “stack” to keep “local variables” in a stack frame.</p>
<h5 id="outputting-a-pixel">Outputting a Pixel</h5>
<p>The preprocessed result of <code>rt.c</code> contains some preprocessor directives (starting with <code>#</code>) and three integers (red, green, and blue).</p>
<pre><code> cc -E -DX=16 -DY=16 -DW=32 -DH=32 rt.c</code></pre>
<p>This will produce:</p>
<pre><code> # 0 &quot;rt.c&quot;
# 0 &quot;&lt;built-in&gt;&quot;
# 0 &quot;&lt;command-line&gt;&quot;
# 1 &quot;/usr/include/stdc-predef.h&quot; 1 3 4
# 0 &quot;&lt;command-line&gt;&quot; 2
# 1 &quot;rt.c&quot;
# 3481 &quot;rt.c&quot;
# 1 &quot;rt.c&quot; 1
# 2090 &quot;rt.c&quot;
# 1 &quot;rt.c&quot; 1
# 2091 &quot;rt.c&quot; 2
# 3482 &quot;rt.c&quot; 2
# 3582 &quot;rt.c&quot;
129
# 3684 &quot;rt.c&quot;
62
# 3786 &quot;rt.c&quot;
129</code></pre>
<p>Interestingly, these are valid in the PPM format (lines starting with <code>#</code> are commments in PPM).
Thus, just concatenating the results for all pixels (and prefixing a small header) will work to create a PPM image file.</p>
<p>When render a large image, we recommend use the <code>-E -P</code> flags as in:</p>
<pre><code> cc -E -P -DX=16 -DY=16 -DW=32 -DH=32 rt.c</code></pre>
<p>This will only produce:</p>
<pre><code> 129
62
129</code></pre>
<p>Note that values appear as expressions like <code>(0 + 2 + 0 + 8 + ...)</code> because we use the “copy” trick.
To print them as to ordinary decimal values, we use macro logic like:</p>
<pre><code> // assume red is (0 + 2 + 0 + 8)
#if red / 100 % 10 == 0
# define digit0(digits) 0##digits
#elif red / 100 % 10 == 1
# define digit0(digits) 1##digits
#else
# define digit0(digits) 2##digits
#endif
#if red / 10 % 10 == 0
# define digit1(digits) digits0(0##digits)
#elif red / 10 % 10 == 1
# define digit1(digits) digits0(1##digits)
#elif ...
...
#endif
#if red % 10 == 0
# define digits digit1(0)
#elif red % 10 == 1
# define digits digit1(1)
#elif ...
...
#endif
digits // outputs &quot;10&quot;</code></pre>
<h4 id="customizing-the-scene">Customizing the Scene</h4>
<p>You can modify the scene by editing the top of <code>rt.c</code>.</p>
<h5 id="example-defaults">Example Defaults</h5>
<pre><code> #define p 0,500,4000 // sphere center position
#define q 2000 // sphere radius
#define r 300,300,300 // sphere color (default: light gray)
#define s(x) 900,200+K*7100,900 // plane color (default: checkered colors of white for K=1 and purple for K=0)
#define t -2000,4000,1000 // light position
#define u 50000,50000,50000 // light color (default: white)
#define v(x) 500-x,500-x,500 // background color (default: gradation from blue to white)</code></pre>
<h5 id="variant-example">Variant Example</h5>
<pre><code> #define p 0,0,8000
#define q 2000
#define r 300,300,900
#define s(x) 200,500-x*300,200+x*800
#define t 2000,4000,3000
#define u 30000,40000,30000
#define v(x) 500,x,10</code></pre>
<p>Features:</p>
<ul>
<li>Grounded blue sphere</li>
<li>Blue and green checkered floor</li>
<li>Sunset-style lighting</li>
</ul>
<p>See <code>ref.512-variant.png</code> for the rendered result.</p>
<h4 id="limitations">Limitations</h4>
<p>Currently, this program supports:</p>
<ul>
<li>One sphere</li>
<li>One floor</li>
<li>One light</li>
</ul>
<p>Adding more lights is relatively simple.
Adding multiple spheres would require stack support for recursive ray tracing (see “Ray Tracing by Self-Inclusion” section).</p>
<p>Note: we recommend GCC for performance; Clang is slower for C preprocessor-heavy tasks like this one.</p>
<!--
Copyright © 1984-2025 by Landon Curt Noll and Leonid A. Broukhis. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<!-- AFTER: last line of markdown file: 2024/endoh1/README.md -->
<!-- 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 -->
<div id="inventory">
<h1 id="inventory-for-2024endoh1">Inventory for 2024/endoh1</h1>
</div>
<h2 id="primary-files">Primary files</h2>
<ul>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/prog.c">prog.c</a> - entry source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/Makefile">Makefile</a> - entry Makefile</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/prog.orig.c">prog.orig.c</a> - original source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/ref.8.png">ref.8.png</a> - 8x8 image in PNG form</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/try.sh">try.sh</a> - script to try entry</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/ref.32.png">ref.32.png</a> - 32x32 image in PNG form</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/ref.128.png">ref.128.png</a> - 128x128 image in PNG form</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/ref.512.png">ref.512.png</a> - 512x512 image in PNG form</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/ref.512-variant.png">ref.512-variant.png</a> - variant of 512x512 image in PNG form</li>
</ul>
<h2 id="secondary-files">Secondary files</h2>
<ul>
<li><a href="2024_endoh1.tar.bz2">2024_endoh1.tar.bz2</a> - download entry tarball</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/README.md">README.md</a> - markdown source for this web page</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/.entry.json">.entry.json</a> - entry summary and manifest in JSON</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/endoh1/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
<li><a href=".path">.path</a> - directory path from top level directory</li>
<li><a href="index.html">index.html</a> - this web page</li>
</ul>
<hr style="width:10%;text-align:left;margin-left:0">
<h4>
Jump to: <a href="#">top</a>
</h4>
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
<!-- END: this line ends content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
</div>
<!-- END: this line ends content from: inc/after-content.default.html -->
<!-- START: this line starts content from: inc/footer.inventory.html -->
<!--
Copyright © 1984-2025 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<div class="footer">
<div id="copyright"><h3>Copyright &copy; 1984-2025 by Landon Curt Noll:
<a href="https://creativecommons.org/faq/#what-does-some-rights-reserved-mean"
target="_blank"
rel="license noopener noreferrer">Some Rights Reserved</a></h3>
<p>
This work is <b>licensed by Landon Curt Noll</b> under
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1"
target="_blank"
rel="license noopener noreferrer"
style="display:inline-block;">CC BY-SA 4.0</a></b>.
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/cc.png"
alt="cc inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/by.png"
alt="person inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/sa.png"
alt="arrow looping back on itself inside circle symbol"><br>
You should <b>carefully review</b> the
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode.en"
target="_blank"
rel="license noopener noreferrer">CC BY-SA 4.0 LEGAL CODE</a></b>
before using the licensed material.<br>
You may wish to review the
<b><a href="../../license.html"
target="_blank"
rel="license noopener noreferrer">highlights of some of the key features and terms</a></b>
of <b>CC BY-SA 4.0</b>.<br>
</p>
</div>
<div id="coda"><h3>Coda</h3>
<p>
<a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2024%2Fendoh1%2Findex.html" rel="nofollow">Nu HTML check this web page</a><br>
<a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a><br>
</p>
</div>
</div>
<!-- END: this line ends content from: inc/footer.inventory.html -->
<!-- START: this line starts content from: inc/bottom.default.html -->
</body>
</html>
<!-- END: this line ends content from: inc/bottom.default.html -->