<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2025-12-01T08:32:00+01:00</updated><id>http://localhost:4000/feed.xml</id><title type="html">code&lt;metas&gt;
&lt;/metas&gt;</title><author><name>Hannah Lenk</name></author><entry><title type="html">Advent of Code 2020</title><link href="http://localhost:4000/2021/04/19/Advent-of-Code-2020.html" rel="alternate" type="text/html" title="Advent of Code 2020" /><published>2021-04-19T02:59:26+02:00</published><updated>2021-04-19T02:59:26+02:00</updated><id>http://localhost:4000/2021/04/19/Advent%20of%20Code%202020</id><content type="html" xml:base="http://localhost:4000/2021/04/19/Advent-of-Code-2020.html"><![CDATA[<p><em>My most valued readers! So glad you could drop by again! You are just in time to catch me singing the praises - almost as belated as they are deserved - for an annual coding competition that can be classified as the highlight of many a programmer each year. In addition, I also show and explain all my solutions for it.</em></p>

<p>In recent years, I have found myself increasingly looking forward to December. Not because of Christmas, not because of my birthday<sup id="fnref:celebrate" role="doc-noteref"><a href="#fn:celebrate" class="footnote" rel="footnote">1</a></sup>, not even because the best thing in each successive one seems to be it finally coming to a close - but because of <a href="https://adventofcode.com/">Advent of Code</a>.</p>

<p>In line with my more general resolution of being more open and public about everything I do<sup id="fnref:why" role="doc-noteref"><a href="#fn:why" class="footnote" rel="footnote">2</a></sup>, I decided I should note down my thoughts, document my experiences and publish my solutions this time around.</p>

<p>Keeping in line with my general tendencies, however, I am - of course - incredibly late to the party.<sup id="fnref:party" role="doc-noteref"><a href="#fn:party" class="footnote" rel="footnote">3</a></sup> Advent ended far more than 4 month ago and I only managed to complete this writeup now, not even in time to ruin the easter bunnys day<sup id="fnref:easter" role="doc-noteref"><a href="#fn:easter" class="footnote" rel="footnote">4</a></sup>.</p>

<p>Nonetheless, despite their seasonal framing, the problems posed are timeless, highly educational and results can be submitted even years after the original “end”. As such, I am hopeful my musings on this particular incarnation - though late - might still prove helpful, interesting and enjoyable to some of my dear readers.</p>

<p>One last word of warning before we get to it:<br />
I am aware, I do tend to say that <a href="/2020/06/22/klobigb_overview.html">Every.</a> <a href="/2020/07/15/A-plea-for-order.html">Single.</a> <a href="/2020/11/22/The-Royal-Game.html">Time.</a>, but this article really is structurally very different from all that came before it. Even if you enjoyed those, it might not come as a surprise if you don’t enjoy this one<sup id="fnref:excuse" role="doc-noteref"><a href="#fn:excuse" class="footnote" rel="footnote">5</a></sup>. 
I wrote a small introduction and a tiny conclusion tying it all together, but really, everything else was written rather independently. Therefore, this should maybe be viewed more like a collection of very small articles or commentaries - one for each day - instead of one grand, cohesive whole. You can freely jump around, look at only the explanations for a single day or even skip all code completely and just peruse my thoughts and opinions at the beginning and end.</p>

<div class="post_toc">
  <h4>Contents</h4>
  <blockquote>
<ul id="markdown-toc">
  <li><a href="#what-is-this-and-why-should-i-care" id="markdown-toc-what-is-this-and-why-should-i-care">What is this and why should I care?</a>    <ul>
      <li><a href="#community" id="markdown-toc-community">Community</a></li>
    </ul>
  </li>
  <li><a href="#solutions" id="markdown-toc-solutions">Solutions</a>    <ul>
      <li><a href="#setup-and-tooling" id="markdown-toc-setup-and-tooling">Setup and tooling</a></li>
      <li><a href="#disclaimer" id="markdown-toc-disclaimer">Disclaimer</a></li>
      <li><a href="#day-1" id="markdown-toc-day-1">Day 1</a></li>
      <li><a href="#day-2" id="markdown-toc-day-2">Day 2</a></li>
      <li><a href="#day-3" id="markdown-toc-day-3">Day 3</a></li>
      <li><a href="#day-4" id="markdown-toc-day-4">Day 4</a></li>
      <li><a href="#day-5" id="markdown-toc-day-5">Day 5</a></li>
      <li><a href="#day-6" id="markdown-toc-day-6">Day 6</a></li>
      <li><a href="#day-7" id="markdown-toc-day-7">Day 7</a></li>
      <li><a href="#day-8" id="markdown-toc-day-8">Day 8</a></li>
      <li><a href="#day-9" id="markdown-toc-day-9">Day 9</a></li>
      <li><a href="#day-10" id="markdown-toc-day-10">Day 10</a></li>
      <li><a href="#day-11" id="markdown-toc-day-11">Day 11</a></li>
      <li><a href="#day-12" id="markdown-toc-day-12">Day 12</a></li>
      <li><a href="#day-13" id="markdown-toc-day-13">Day 13</a></li>
      <li><a href="#day-14" id="markdown-toc-day-14">Day 14</a></li>
      <li><a href="#day-15" id="markdown-toc-day-15">Day 15</a></li>
      <li><a href="#day-16" id="markdown-toc-day-16">Day 16</a></li>
      <li><a href="#day-17" id="markdown-toc-day-17">Day 17</a></li>
      <li><a href="#day-18" id="markdown-toc-day-18">Day 18</a></li>
      <li><a href="#day-19" id="markdown-toc-day-19">Day 19</a></li>
      <li><a href="#day-20" id="markdown-toc-day-20">Day 20</a></li>
      <li><a href="#day-21" id="markdown-toc-day-21">Day 21</a></li>
      <li><a href="#day-22" id="markdown-toc-day-22">Day 22</a></li>
      <li><a href="#day-23" id="markdown-toc-day-23">Day 23</a></li>
      <li><a href="#day-24" id="markdown-toc-day-24">Day 24</a></li>
      <li><a href="#day-25" id="markdown-toc-day-25">Day 25</a></li>
    </ul>
  </li>
  <li><a href="#conclusion" id="markdown-toc-conclusion">Conclusion</a>    <ul>
      <li><a href="#closing-thoughts-on-this-edition" id="markdown-toc-closing-thoughts-on-this-edition">Closing thoughts on this edition</a></li>
      <li><a href="#what-now" id="markdown-toc-what-now">What now?</a></li>
    </ul>
  </li>
</ul>

  </blockquote>
</div>

<h1 id="what-is-this-and-why-should-i-care">What is this and why should I care?</h1>

<p>I really don’t think I can put it better than the creator himself, so allow me to first point out that Eric Wastl has presented many times on the topic and watching at least <a href="https://youtu.be/CFWuwNDOnIo">one of those presentations</a> is probably a more valuable investment of your time and attention.</p>

<p>If, however, you intend to stay with me for now and want the shortened, succinct version - also ripped directly from his talks - Advent of Code is what you get if you combine this<sup id="fnref:advent_credit" role="doc-noteref"><a href="#fn:advent_credit" class="footnote" rel="footnote">6</a></sup>:</p>

<p><img src="/images/advent_calendar.jpg" alt="Advent Calendar" title="An Advent Calendar" class="centered-image" width="40%" /></p>

<p>with something like these:</p>

<p><img src="/images/competitive_prog_sites.png" alt="A number of competitive programming sites" title="Not an exhaustive list and not an endorsement of any one of those sites!" class="centered-image" width="60%" /></p>

<p>Beginning on the first of December, each day leading up to Christmas you get another door to open and peer behind. Instead of discovering a piece of chocolate - as is usual in more common variations of an <a href="https://en.wikipedia.org/wiki/Advent_calendar">advent calendar</a> - each door reveals a brand new programming puzzle to solve, all of them flimsily tied together with a whimsical and endearing cover story.</p>

<p>Whilst this description alone might, to the uninitiated, sound nice but not particularly exciting, it being the only thing during the last 5 to 10 years that managed to motivate me to consistently wake up and be available at a specific time of day - let alone really early - should tell you there is something very special about it.</p>

<p>And indeed, there is much that differentiates it from other events and makes participating in Advent of Code a rewarding and unique experience:</p>

<ul>
  <li>
    <p>It is not tied to any specific tool, language or environment. In fact, special care is taken to keep the problems language agnostic and not give any one - compiled or otherwise - a significant edge over others<sup id="fnref:speed" role="doc-noteref"><a href="#fn:speed" class="footnote" rel="footnote">7</a></sup>. As you have to submit a solution, not the code which computes it, anything goes and you are free to chose whichever path you fancy. You can preprocess input, combine multiple tools, solve some puzzles with pen and paper, <a href="https://www.reddit.com/r/adventofcode/comments/kfnt2s/2020_day_18_part_1_outsourcing_the_solution_they/">crowdsource</a> or use whatever other crazy ideas you might come up with. Anything short of hacking the site is welcome and kind of the point. It really teaches you to solve the specific problem in front of you, just as you should do in this strange “real world” I have been hearing so much of.</p>
  </li>
  <li>
    <p>Its one of a kind two part structure not only increases accessibility but lends itself particularly well as a teaching tool. You see, you do not really get one puzzle each day, you get two, the second of which is unlocked after you successfully solved the first one! Most of the time it is a more complicated variation or an extension of the first part. The effect of this structure, as I see it, is twofold: On the one hand, even complete beginners do get at least one task each day they can realistically hope to solve. 
On the other hand, what you have learned in part 1 can and must immediately be applied in part 2, consolidating new knowledge and fostering true understanding. You have to rethink and optimize your approach, consider asymptotic complexity and benefit from keeping your code clean and extensible.</p>
  </li>
  <li>
    <p>The occasional interdependence of many tasks, as seen with the <a href="https://adventofcode.com/2019/day/2">notorious intcode problems</a> in 2019, serves as a wonderful incentive to not only keep code extensible from the start, but even regularly go back to maintain and clean it up. You never quite know if and when you might have to build on something written on a previous day and not considering that might come back to bite you. Again, reminiscent of and not entirely unlike this “real world” thing.</p>
  </li>
</ul>

<p>That list is not exhaustive and deeply personal, which is why I will stop now. There is, however, one aspect so important to deserve its own section in this introduction: What really sets Advent of Code apart - more than anything - from all other coding competitions I know of, is its amazing community.</p>

<h2 id="community">Community</h2>

<p>With more than <a href="https://adventofcode.com/2020/stats">150000 participants</a> vying for one of the coveted spots on <a href="https://adventofcode.com/2020/leaderboard">a global leaderboard</a> consisting of a very meager 100 places, one could expect a certain degree of hostility.</p>

<p>What is actually happening is, however, the very opposite. Seldom have I witnessed such incredible supportiveness in so competitive an environment. Everyone helps and encourages everyone else, providing tips and assistance when needed, comparing solutions, sharing thoughts and ideas and just in general being awesome to each other.</p>

<p>To name just one example, I invite you to scroll through this <a href="https://www.reddit.com/r/adventofcode/comments/k4ejjz/2020_day_1_unlock_crash_postmortem/">lovely reddit thread</a>, started by the creator himself after, on the very first day of this most recent edition, the servers collapsed under the unpredictably huge load on puzzle unlock. Who got onto the leaderboard on that day was more of a function of who got to the servers first upon their restart than who solved the problem most quickly. As such, no leaderboard points were given at all. Instead of disgruntled voices protesting the decision or complaints about the crash, you’ll find only words of encouragement and understanding.</p>

<p>That incident was not just a fluke either. Solving the puzzles simultaneously with thousands of others around the world, all with different backgrounds, preferences and varying levels of experience and skill provides ample opportunity to learn from and inspire each other. There are even <a href="https://www.reddit.com/r/adventofcode/comments/kjtmw0/introducing_your_aoc_2020_gettin_crafty_with_it/">special rewards for exceptionally creative solutions, visualizations and other ideas</a>. And memes. A lot of memes.</p>

<p>The community is, of course, not restricted to reddit exclusively. Many participants - all across the leaderboard - stream their solving live on platforms like twitch and youtube, searching github for “adventofcode” reveals more than 30000 repositories and various sub-communities maintain their own leaderboards.</p>

<p>Related blog posts also exist in abundance. Even if I most definitely won the race for most delayed wrap-up post, it is by far less of an excessive margin <a href="https://www.reddit.com/r/adventofcode/comments/mcgzox/2020_rust_is_it_too_late_for_advent_of_code/">than you might think</a>. In no particular order of timing and preference, as I love them all, here <a href="https://danvdk.medium.com/advent-of-code-2020-this-time-in-rust-7904559e24bc">is</a> <a href="https://timvisee.com/blog/solving-aoc-2020-in-under-a-second/">a small</a> <a href="https://cestlaz.github.io/post/advent-2020-final-thoughts/">selection</a> <a href="https://explog.in/notes/aoc.html">of</a> <a href="https://dannyvankooten.com/solving-advent-of-code-2020-under-1-second/">wrap-up posts</a>. There are many more and I encourage you to search for them.</p>

<p>Regardless, I promised to keep this short. Enough preamble, let’s leave the gushing for another day and move on to finally discuss solutions.</p>

<h1 id="solutions">Solutions</h1>

<h2 id="setup-and-tooling"><a href="https://github.com/philipplenk/adventofcode20/tree/main/tools">Setup and tooling</a></h2>

<p>If you read my remarks above attentively, you will know that choosing which set of languages and tools to employ is a pivotal decision. Allow me to briefly explain my sophisticated thought process on that matter:</p>

<p><em>If all you have is a hammer, everything looks like a nail. If your favorite tool is a very efficient hammer, you can beat everything into submission until it wishes it were one.</em></p>

<p>Naturally, I exclusively used C++.</p>

<p>I am a lot of things, and one of them is ambitious in all the wrong ways. Last year, I made it onto the global leaderboard just once and I intended to improve on that.<sup id="fnref:failure" role="doc-noteref"><a href="#fn:failure" class="footnote" rel="footnote">8</a></sup> To improve my chances of doing so, I did the bare minimum of preparation and composed a few simple scripts automating repetitive, time consuming site interactions. Nothing fancy, just one <a href="https://github.com/philipplenk/adventofcode20/blob/main/tools/submit_result.sh">for submission</a>, one for <a href="https://github.com/philipplenk/adventofcode20/blob/main/tools/fetch_input.sh">fetching the input</a>, <a href="https://github.com/philipplenk/adventofcode20/blob/main/tools/init.sh">copying and opening a boilerplate ready base file</a> for each day and a very <a href="https://github.com/philipplenk/adventofcode20/blob/main/base/Makefile">simplistic Makefile</a> tying them together.</p>

<h2 id="disclaimer">Disclaimer</h2>

<p>All explanations that follow are also reproduced in a <a href="https://github.com/philipplenk/adventofcode20">github repository</a>, next to the code they pertain to. So if you are only interested in a solution for one specific day, it might be better to just head over there and browse to the corresponding folder.</p>

<p>They also - obviously - spoil the fun of solving the problems on your own. So, if you happen to know me personally and your name starts with H, J, K, M, R or S or if you simply wish to - as opposed to being forced to - do the puzzles on your own first, <a href="#conclusion">skip</a> what is written below and return to compare once you are ready ;-) You may consider me sorely disappointed if you look at the solutions before your own attempts.</p>

<p>WHAT FOLLOWS DOES CERTAINLY NOT CONTAIN THE BEST CODE I HAVE EVER WRITTEN. I solved all of them at the time they appeared, which was 6 am in the morning where I live, between 8 - 12 hours ahead of my normal waking time xD</p>

<h2 id="day-1"><a href="https://github.com/philipplenk/adventofcode20/tree/main/01">Day 1</a></h2>

<h3 id="part-1">Part 1</h3>

<p>The first puzzle was simply finding two elements in a list of numbers which sum to another number(in our case the then current year, 2020).</p>

<p>This can, of course, be solved trivially in quadratic time, as can be seen in <a href="https://github.com/philipplenk/adventofcode20/tree/main/01/01_nested_loop.cpp">01_nested_loop.cpp</a>:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">vals</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">+</span><span class="n">vals</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">==</span><span class="mi">2020</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="c1">//found it!</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>If we want to <a href="https://github.com/philipplenk/adventofcode20/tree/main/01/01_binary_search.cpp">get fancy</a>, we can sort our input in O(n log n) time, iterate over it and find the potentially corresponding number in O(log n) time, yielding a total running time of O(n log n) again:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">vals</span><span class="p">));</span>
		
<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">v</span><span class="o">:</span><span class="n">vals</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">binary_search</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="mi">2020</span><span class="o">-</span><span class="n">v</span><span class="p">))</span>
	<span class="p">{</span>
		<span class="c1">//found it!</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>Yes, <a href="https://en.cppreference.com/w/cpp/algorithm/binary_search">binary_search in the standard library returns a boolean</a>. This is one of the rare occasions where that is actually exactly what we want. For all the others, there is <a href="https://en.cppreference.com/w/cpp/algorithm/lower_bound">lower_bound</a> and <a href="https://en.cppreference.com/w/cpp/algorithm/upper_bound">upper_bound</a>.</p>

<p>That is rather nice, but if we are willing to sacrifice just a tiny little bit of additional memory(O(m) with m being the searched for sum) and assume all numbers are non-negative we could <a href="https://github.com/philipplenk/adventofcode20/tree/main/01/01.cpp">even go linear</a>:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">bitset</span><span class="o">&lt;</span><span class="mi">2021</span><span class="o">&gt;</span> <span class="n">seen</span><span class="p">{};</span>
		
<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">v</span><span class="o">:</span> <span class="n">vals</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">v</span><span class="o">&gt;</span><span class="mi">2020</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
	
	<span class="n">seen</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="n">v</span><span class="p">);</span>
	<span class="k">if</span><span class="p">(</span><span class="n">seen</span><span class="p">.</span><span class="n">test</span><span class="p">(</span><span class="mi">2020</span><span class="o">-</span><span class="n">v</span><span class="p">))</span>
	<span class="p">{</span>
		<span class="c1">//found it!</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>Without the assumption of non-negativity - which held for my input, but might not for everyones -  we can still do a variation of this, but would have to use significantly more memory and/or rely on some sort of hashset.</p>

<h3 id="part-2">Part 2</h3>

<p>For a tiny bit more difficulty (and were the numbers bigger also a significant spike in runtime for the trivial solutions), the second part asks us to find three numbers that sum to 2020. Luckily for us, the list is reasonably short and even the <a href="https://github.com/philipplenk/adventofcode20/tree/main/01/02_nested_loop.cpp">now cubic nested for loops</a> produce the correct result in a very short time(a very small fraction of a second on even my old machine):</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">k</span><span class="o">=</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="n">k</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">k</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">if</span><span class="p">(</span><span class="n">vals</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">+</span><span class="n">vals</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">+</span><span class="n">vals</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">==</span><span class="mi">2020</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="c1">//found it!</span>
			<span class="p">}</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>Both of our slightly more sophisticated methods for part 1 can relatively easily be adapted to this new constraint. For the one applying sorting, simply add yet another for loop, yielding a O(n^2 log(n)) runtime. <a href="https://github.com/philipplenk/adventofcode20/tree/main/01/02_binary_search.cpp">Nothing to write home about</a>, but a step up from cubic…</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">vals</span><span class="p">));</span>
	
<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">target</span> <span class="o">=</span> <span class="mi">2020</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
		<span class="k">if</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">binary_search</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">target</span><span class="p">))</span>
		<span class="p">{</span>
			<span class="c1">//found it!</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>Again, we can get rid of that tiny annoying log(n) factor, given the same assumptions and using the same technique as above. Adding another for loop results in <a href="https://github.com/philipplenk/adventofcode20/tree/main/02/02.cpp">the following code</a>, for “only” quadratic time.</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">bitset</span><span class="o">&lt;</span><span class="mi">2021</span><span class="o">&gt;</span> <span class="n">seen</span><span class="p">{};</span>
		
<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">vals</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&gt;</span><span class="mi">2020</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
	<span class="n">seen</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="n">vals</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
	
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">vals</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">&gt;</span><span class="mi">2020</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
		<span class="n">seen</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="n">vals</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span>
		
		<span class="k">const</span> <span class="k">auto</span> <span class="n">target</span> <span class="o">=</span> <span class="mi">2020</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
		
		<span class="k">if</span><span class="p">(</span><span class="n">target</span><span class="o">&lt;</span><span class="mi">2021</span> <span class="o">&amp;&amp;</span> <span class="n">target</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">seen</span><span class="p">.</span><span class="n">test</span><span class="p">(</span><span class="n">target</span><span class="p">))</span>
		<span class="p">{</span>
			<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">vals</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">*</span><span class="n">vals</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">*</span><span class="n">target</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span>
			<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>More than sufficient for the small input set, yet I really did not like stopping here.</p>

<p>Whilst it remains an open research problem whether or not the general <a href="https://en.wikipedia.org/wiki/3SUM">3SUM problem</a> is solvable in subquadratic time, we do have some additional constraints. Our input consists of only non-negative integers smaller or equal to our target value. Wikipedia claims that for integers in range -n to n there exists a solution in O(n log n) utilizing a Fast Fourier Transform on the input set represented as a bit vector, but unfortunately I failed to understand how exactly such a solution could be constructed.</p>

<p>So I tried to find a different, better solution, gave it a tiny bit more thought and my contemplations yielded <a href="https://github.com/philipplenk/adventofcode20/tree/main/01/02_wrong.cpp">the following code</a>:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">vals</span><span class="p">));</span>	
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">lower</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">higher</span> <span class="o">=</span> <span class="n">vals</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span>

<span class="k">while</span><span class="p">(</span><span class="n">lower</span><span class="o">&lt;</span><span class="n">higher</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">target</span> <span class="o">=</span> <span class="mi">2020</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">lower</span><span class="p">]</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">higher</span><span class="p">];</span>
	<span class="k">if</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">binary_search</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">vals</span><span class="p">),</span><span class="n">target</span><span class="p">))</span>
	<span class="p">{</span>
		<span class="c1">//found it!</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">vals</span><span class="p">[</span><span class="n">lower</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">lower</span><span class="p">]</span><span class="o">&lt;</span><span class="n">vals</span><span class="p">[</span><span class="n">higher</span><span class="p">]</span><span class="o">-</span><span class="n">vals</span><span class="p">[</span><span class="n">higher</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
		<span class="o">++</span><span class="n">lower</span><span class="p">;</span>
	<span class="k">else</span>
		<span class="o">--</span><span class="n">higher</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>The runtime is bounded fairly simple: lower and higher start n values apart from each other and in each iteration either one is moved towards the other or a solution is found. As such, the while loop runs at most n times. The most expensive operation within is the binary search, running in log n time. As such, the overall complexity is O(n<em>log(n)) (for sorting) + O(n</em>log(n)) (for the loop), yielding a glorious O(n*log(n)) in total!</p>

<p>That is all fine and dandy, it even worked for my input and the few others I could find and try it on at the time, but that alone is far from sufficient to prove it could work for any input. As such, I tried to sketch a proof and in so doing quickly had to come to a shattering realization: <strong>this is completely wrong and ridiculously stupid!</strong></p>

<p>For instance, it fails with the following simple input:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1 9 1009 1010 2000
</code></pre></div></div>

<p>Nonetheless, I considered this failure educational and working out why it works for some inputs and how exactly it fails so spectacularly on many others can be quite instructive, which is why I still showcase it here.</p>

<h2 id="day-2"><a href="https://github.com/philipplenk/adventofcode20/tree/main/02">Day 2</a></h2>

<h3 id="part-1-1">Part 1</h3>

<p>The second day was algorithmically far easier(and imho less interesting) than the first one, as the only difficulty here was avoiding typos and parsing the input. You got a list of words and <em>policies</em>, which described how to determine if a given word was valid:</p>

<p>1-3 p: word</p>

<p>Count the occurrences of the given letter(p) in the given word(word) and check it is present between the lower(1) and higher(3) bound times. We then had to count the number of valid words, i.e. words that satisfied their own policy.</p>

<p>Really, this was mostly just a typing speed challenge, with standard algorithms doing the bulk of the work. I simply defined a struct describing one such rule/word pair:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">policy_word</span>
<span class="p">{</span>
	<span class="kt">char</span> <span class="n">letter</span><span class="p">;</span>
	<span class="kt">int</span> <span class="n">min</span><span class="p">,</span> <span class="n">max</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">str</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>Followed by overloading operator«(lazily, without any error handling), so I could extract properly typed input from stdin:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">in</span><span class="p">,</span> <span class="n">policy_word</span><span class="o">&amp;</span> <span class="n">p</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">char</span> <span class="n">dummy</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">p</span><span class="p">.</span><span class="n">min</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">dummy</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">p</span><span class="p">.</span><span class="n">max</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">p</span><span class="p">.</span><span class="n">letter</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">dummy</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">p</span><span class="p">.</span><span class="n">str</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">in</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>That allowed me to conveniently combine istream_iterator and std::count_if to solve the actual problem:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">count_if</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">policy_word</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{},[](</span><span class="k">auto</span> <span class="n">pw</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">cnt</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">count</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">pw</span><span class="p">.</span><span class="n">str</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">pw</span><span class="p">.</span><span class="n">str</span><span class="p">),</span><span class="n">pw</span><span class="p">.</span><span class="n">letter</span><span class="p">);</span>
	<span class="k">return</span> <span class="n">cnt</span><span class="o">&gt;=</span><span class="n">pw</span><span class="p">.</span><span class="n">min</span> <span class="o">&amp;&amp;</span> <span class="n">cnt</span><span class="o">&lt;=</span><span class="n">pw</span><span class="p">.</span><span class="n">max</span><span class="p">;</span>
<span class="p">})</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<h3 id="part-2-1">Part 2</h3>

<p>Part 2 was even more trivial, as the interpretation of the policies was changed. Now a valid word has to have the given letter at exactly one of the given positions. Simply change the validity checking lambda and you get the following code:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">count_if</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">policy_word</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{},[](</span><span class="k">auto</span> <span class="n">pw</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">return</span> <span class="n">pw</span><span class="p">.</span><span class="n">str</span><span class="p">[</span><span class="n">pw</span><span class="p">.</span><span class="n">min</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">!=</span><span class="n">pw</span><span class="p">.</span><span class="n">str</span><span class="p">[</span><span class="n">pw</span><span class="p">.</span><span class="n">max</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">pw</span><span class="p">.</span><span class="n">str</span><span class="p">[</span><span class="n">pw</span><span class="p">.</span><span class="n">min</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">==</span><span class="n">pw</span><span class="p">.</span><span class="n">letter</span> <span class="o">||</span> <span class="n">pw</span><span class="p">.</span><span class="n">str</span><span class="p">[</span><span class="n">pw</span><span class="p">.</span><span class="n">max</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">==</span><span class="n">pw</span><span class="p">.</span><span class="n">letter</span><span class="p">);</span>
<span class="p">})</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<p>The only potential issue, and obviously one I stumbled upon and which cost me one minute because of an incorrect answer is that position - of course - starts at 1, not 0 here.</p>

<h2 id="day-3"><a href="https://github.com/philipplenk/adventofcode20/tree/main/03">Day 3</a></h2>

<h3 id="part-1-2">Part 1</h3>

<p>Yeahy, may the ascii art begin! This was the first of a classical kind of 2d grid based puzzles this year! It was also the first problem this year where what little preparation I had done came in handy, having predefined point and vector types.</p>

<p>Given a map consisting of open spaces (represented as ‘.’) and trees(represented as ‘#’), all we had to do was check how often one would hit a tree when going down a certain slope. Beginning in {0,0}, just adding the vector {3,1} until you hit the bottom, count the elements with value #. To ensure you always reach the bottom, the grid extends infinitely to the right, simply looping around in classic pacman fashion - which implemented via a simple % on the x value:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">vec2d</span> <span class="n">direction</span><span class="p">{</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">};</span>
<span class="n">point2d</span> <span class="n">pos</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">};</span>

<span class="kt">int</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">y</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">grid</span><span class="p">.</span><span class="n">size</span><span class="p">()))</span>
<span class="p">{</span>
	<span class="n">pos</span><span class="p">.</span><span class="n">x</span><span class="o">%=</span><span class="n">grid</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">();</span>
	<span class="k">if</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">pos</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'#'</span><span class="p">)</span>
		<span class="o">++</span><span class="n">count</span><span class="p">;</span>
	
	<span class="n">pos</span><span class="o">+=</span><span class="n">direction</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<h3 id="part-2-2">Part 2</h3>

<p>Part 2 was simply doing the same thing with multiple slopes and multiplying the results. Nothing fancy, just moving the counting to a lambda and a small range-for does the trick:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">d</span><span class="o">:</span> <span class="p">{</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">5</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">7</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">}})</span>
	<span class="n">result</span><span class="o">*=</span><span class="n">count_trees</span><span class="p">(</span><span class="n">d</span><span class="p">);</span></code></pre>
</figure>

<h2 id="day-4"><a href="https://github.com/philipplenk/adventofcode20/tree/main/04">Day 4</a></h2>

<h3 id="part-1-3">Part 1</h3>

<p>Given a list of key:value pairs, separated by empty lines, we were first asked to simply check for the presence of various fields. Quite similar to the first day, this was mostly an exercise in getting parsing somewhat right, which, frankly, annoyed me a little at the time. As on that day, I first simply defined a type for the data:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">password_data</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">data</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>followed by an overloaded operator»:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">in</span><span class="p">,</span> <span class="n">password_data</span><span class="o">&amp;</span> <span class="n">pwd</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">pwd</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
	
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">line</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="n">stringstream</span> <span class="n">strm</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">getline</span><span class="p">(</span><span class="n">in</span><span class="p">,</span><span class="n">line</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">line</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
	<span class="p">{</span>
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">c</span><span class="o">:</span> <span class="n">line</span><span class="p">)</span>
			<span class="n">strm</span><span class="o">&lt;&lt;</span><span class="p">(</span><span class="n">c</span><span class="o">==</span><span class="sc">':'</span><span class="o">?</span><span class="sc">' '</span><span class="o">:</span><span class="n">c</span><span class="p">);</span>
		<span class="n">strm</span><span class="o">&lt;&lt;</span><span class="sc">' '</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span><span class="p">,</span> <span class="n">data</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">strm</span><span class="o">&gt;&gt;</span><span class="n">name</span><span class="o">&gt;&gt;</span><span class="n">data</span><span class="p">)</span>
		<span class="n">pwd</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">=</span><span class="n">data</span><span class="p">;</span>
		
	<span class="k">if</span><span class="p">(</span><span class="n">pwd</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
		<span class="n">in</span><span class="p">.</span><span class="n">setstate</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ios</span><span class="o">::</span><span class="n">failbit</span><span class="p">);</span>
	<span class="k">else</span>
		<span class="n">in</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
	
	<span class="k">return</span> <span class="n">in</span><span class="p">;</span>
<span class="p">}</span>	</code></pre>
</figure>

<p>We then define what it means to be valid:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">bool</span> <span class="nf">is_valid</span><span class="p">(</span><span class="k">const</span> <span class="n">password_data</span><span class="o">&amp;</span> <span class="n">pwd</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span><span class="mi">7</span><span class="o">&gt;</span> <span class="n">required</span><span class="p">{</span><span class="s">"byr"</span><span class="p">,</span><span class="s">"iyr"</span><span class="p">,</span><span class="s">"eyr"</span><span class="p">,</span><span class="s">"hgt"</span><span class="p">,</span><span class="s">"hcl"</span><span class="p">,</span><span class="s">"ecl"</span><span class="p">,</span><span class="s">"pid"</span><span class="p">};</span>
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">part</span><span class="o">:</span> <span class="n">required</span><span class="p">)</span>
		<span class="k">if</span><span class="p">(</span><span class="n">pwd</span><span class="p">.</span><span class="n">data</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">part</span><span class="p">)</span><span class="o">==</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">pwd</span><span class="p">.</span><span class="n">data</span><span class="p">))</span>
			<span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
	<span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>and let count_if do all the work:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">count_if</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">password_data</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{},</span><span class="n">is_valid</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<p>The different maps were separated by an empty line in between them, which made it rather tedious (and likely a bad idea) to parse as I did by overloading operator» on std::istream. I also - as usual - committed another ridiculously stupid mistake that cost me a good 5 minutes:</p>

<p>Note how I read lines until either std::getline fails or returns an empty line. That is because there are actually two ways a collection of related key-value pairs is terminated: With an empty line OR with the end of input. The problem occurs in the latter case. If std::getline fails, it sets, appropriately, the std::ios::failbit on the underlying stream. If I do not clear it, however, this indicates to the istream_iterator that extraction failed and the last entry will not be accepted.</p>

<h3 id="part-2-3">Part 2</h3>

<p>Now, in addition to merely checking for their presence, we were tasked with checking each fields validity based on certain criteria. Again, not too difficult, just quite tedious and easy to get wrong, yielding somewhat unsightly code by necessity. Originally, I had a gigantic if-else block and repeated code, just to get it done as quickly as possible(faaar too slow for the leaderboard, of course), but looking at that code was the sort of torture I could not possibly subject my dear readers to, so I went kind of overboard and constructed a bunch of composable function objects that allowed me to define the criteria in an almost declarative style:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string_view</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">function</span><span class="o">&lt;</span><span class="kt">bool</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string_view</span><span class="p">)</span><span class="o">&gt;&gt;&gt;</span> <span class="n">field_validator</span>
<span class="p">{</span>
	<span class="p">{</span><span class="s">"byr"</span><span class="p">,</span> <span class="n">all</span><span class="p">(</span><span class="n">is_length</span><span class="p">(</span><span class="mi">4</span><span class="p">),</span><span class="n">is_number</span><span class="p">,</span><span class="n">chain</span><span class="p">(</span><span class="n">as_number</span><span class="p">,</span><span class="n">is_between</span><span class="p">(</span><span class="mi">1920</span><span class="p">,</span><span class="mi">2002</span><span class="p">)))},</span>
		
	<span class="p">{</span><span class="s">"iyr"</span><span class="p">,</span> <span class="n">all</span><span class="p">(</span><span class="n">is_length</span><span class="p">(</span><span class="mi">4</span><span class="p">),</span><span class="n">is_number</span><span class="p">,</span><span class="n">chain</span><span class="p">(</span><span class="n">as_number</span><span class="p">,</span><span class="n">is_between</span><span class="p">(</span><span class="mi">2010</span><span class="p">,</span><span class="mi">2020</span><span class="p">)))},</span>
		
	<span class="p">{</span><span class="s">"eyr"</span><span class="p">,</span> <span class="n">all</span><span class="p">(</span><span class="n">is_length</span><span class="p">(</span><span class="mi">4</span><span class="p">),</span><span class="n">is_number</span><span class="p">,</span><span class="n">chain</span><span class="p">(</span><span class="n">as_number</span><span class="p">,</span><span class="n">is_between</span><span class="p">(</span><span class="mi">2020</span><span class="p">,</span><span class="mi">2030</span><span class="p">)))},</span>
		
	<span class="p">{</span><span class="s">"hgt"</span><span class="p">,</span> <span class="n">one_of</span>
		<span class="p">(</span>
		<span class="n">all</span><span class="p">(</span><span class="n">ends_with</span><span class="p">(</span><span class="s">"cm"</span><span class="p">),</span><span class="n">chain</span><span class="p">(</span><span class="n">remove_suffix</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span><span class="n">is_number</span><span class="p">),</span><span class="n">chain</span><span class="p">(</span><span class="n">remove_suffix</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span><span class="n">as_number</span><span class="p">,</span><span class="n">is_between</span><span class="p">(</span><span class="mi">150</span><span class="p">,</span><span class="mi">193</span><span class="p">))),</span>
			<span class="n">all</span><span class="p">(</span><span class="n">ends_with</span><span class="p">(</span><span class="s">"in"</span><span class="p">),</span><span class="n">chain</span><span class="p">(</span><span class="n">remove_suffix</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span><span class="n">is_number</span><span class="p">),</span><span class="n">chain</span><span class="p">(</span><span class="n">remove_suffix</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span><span class="n">as_number</span><span class="p">,</span><span class="n">is_between</span><span class="p">(</span><span class="mi">59</span><span class="p">,</span><span class="mi">76</span><span class="p">)))</span>
		<span class="p">)</span>
	<span class="p">},</span>
		
	<span class="p">{</span><span class="s">"ecl"</span><span class="p">,</span> <span class="n">is_one_of</span><span class="p">(</span><span class="s">"amb"</span><span class="p">,</span><span class="s">"blu"</span><span class="p">,</span><span class="s">"brn"</span><span class="p">,</span><span class="s">"gry"</span><span class="p">,</span><span class="s">"grn"</span><span class="p">,</span><span class="s">"hzl"</span><span class="p">,</span><span class="s">"oth"</span><span class="p">)},</span>
	
	<span class="p">{</span><span class="s">"pid"</span><span class="p">,</span> <span class="n">all</span><span class="p">(</span><span class="n">is_length</span><span class="p">(</span><span class="mi">9</span><span class="p">),</span><span class="n">is_number</span><span class="p">)},</span>
	
	<span class="p">{</span><span class="s">"hcl"</span><span class="p">,</span> <span class="n">all</span><span class="p">(</span><span class="n">starts_with</span><span class="p">(</span><span class="s">"#"</span><span class="p">),</span> <span class="n">chain</span><span class="p">(</span><span class="n">remove_prefix</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span><span class="n">is_hexnumber</span><span class="p">))},</span>
<span class="p">};</span></code></pre>
</figure>

<p>The business logic ones are rather trivial and uninteresting. The ones used for composition can, however, prove educational:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">constexpr</span> <span class="k">auto</span> <span class="n">all</span> <span class="o">=</span> <span class="p">[](</span><span class="k">auto</span><span class="p">...</span> <span class="n">checkers</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">[</span><span class="o">=</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">str</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="n">checkers</span><span class="p">(</span><span class="n">str</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="p">...);</span> <span class="p">};</span> <span class="p">};</span>
	
<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">one_of</span> <span class="o">=</span> <span class="p">[](</span><span class="k">auto</span><span class="p">...</span> <span class="n">checkers</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">[</span><span class="o">=</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">str</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="n">checkers</span><span class="p">(</span><span class="n">str</span><span class="p">)</span> <span class="o">||</span> <span class="p">...);</span> <span class="p">};</span> <span class="p">};</span>
	
<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">chain</span> <span class="o">=</span> <span class="p">[](</span><span class="k">auto</span> <span class="n">fun</span><span class="p">,</span> <span class="k">auto</span><span class="p">...</span> <span class="n">funs</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">chain_impl</span> <span class="o">=</span> <span class="p">[](</span><span class="k">auto</span> <span class="n">recurse</span><span class="p">,</span> <span class="k">auto</span> <span class="n">fun</span><span class="p">,</span> <span class="k">auto</span><span class="p">...</span> <span class="n">funs</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span> <span class="k">constexpr</span><span class="p">(</span><span class="k">sizeof</span><span class="p">...(</span><span class="n">funs</span><span class="p">)</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span>
			<span class="k">return</span> <span class="n">fun</span><span class="p">;</span>
		<span class="k">else</span>
			<span class="k">return</span> <span class="p">[</span><span class="o">=</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">arg</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">recurse</span><span class="p">(</span><span class="n">recurse</span><span class="p">,</span> <span class="n">funs</span><span class="p">...)(</span><span class="n">fun</span><span class="p">(</span><span class="n">arg</span><span class="p">));</span> <span class="p">};</span>
	<span class="p">};</span>
	
	<span class="k">return</span> <span class="nf">chain_impl</span><span class="p">(</span><span class="n">chain_impl</span><span class="p">,</span><span class="n">fun</span><span class="p">,</span><span class="n">funs</span><span class="p">...);</span>
<span class="p">};</span></code></pre>
</figure>

<p><em>all</em> simply takes a bunch of callables and returns a new callable that utilizes <a href="https://en.cppreference.com/w/cpp/language/fold">C++17’s fold expressions</a> to call each one of the given checkers in a chain connected via &amp;&amp;, i.e. returning true exactly if all of the given checkers would return true.</p>

<p><em>one_of</em> does pretty much the same thing, just with ||, i.e. or, instead of and.</p>

<p><em>chain</em>, as the other two, takes a collection of callables and returns another callable. This one, however, is constructed in a little more complicated fashion. First, we call a helper <em>chain_impl</em>. This is necessary to get recursion, which is otherwise not easily available in lambda expressions. The helper does one of two things:</p>
<ul>
  <li>If there is only one callable left, it is returned.</li>
  <li>Otherwise, we construct a new callable that calls the first one and passes the result on to whatever the recursion will construct for all other functions.</li>
</ul>

<p>Effectively, given functions a, b, c and d, this will construct an expression equivalent to d(c(b(a(input)))), i.e. it chains the calls, using the result of the first as input to the second and so on(similar to the use of <a href="https://en.wikipedia.org/wiki/Pipeline_(Unix)">pipes</a> in Unix, a | b | c | d).</p>

<h2 id="day-5"><a href="https://github.com/philipplenk/adventofcode20/tree/main/05">Day 5</a></h2>

<h3 id="part-1-4">Part 1</h3>

<p>This one was a bit more interesting and certainly educational. We were given a lovely description of how a certain airliner numbers their seats by repeatedly subdividing a range, throwing away either the lower or the upper half with each incoming letter. Whilst reminiscent of binary search, it is basically even simpler. The description mirrors exactly the classical definition of what a bit actually is: something that halves your prior uncertainty. As such, the strings proved to be nothing more than a fancy encoding for a 10-digit binary number, MSB first. With this realization, completing the task - that of finding the highest id - was trivial:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp">	<span class="k">const</span> <span class="k">auto</span> <span class="n">seat_id</span><span class="o">=</span><span class="p">[](</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">str</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">c</span><span class="o">:</span> <span class="n">str</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">id</span><span class="o">&lt;&lt;=</span><span class="mi">1</span><span class="p">;</span>
			<span class="k">if</span><span class="p">(</span><span class="n">c</span><span class="o">==</span><span class="sc">'B'</span> <span class="o">||</span> <span class="n">c</span><span class="o">==</span><span class="sc">'R'</span><span class="p">)</span>
				<span class="n">id</span><span class="o">|=</span><span class="mi">1</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="k">return</span> <span class="n">id</span><span class="p">;</span>
	<span class="p">};</span>
	
	<span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">max_id</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&gt;::</span><span class="n">min</span><span class="p">();</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">str</span><span class="p">;</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="o">&gt;&gt;</span><span class="n">str</span><span class="p">;)</span>
	<span class="p">{</span>
		<span class="n">max_id</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">max_id</span><span class="p">,</span><span class="n">seat_id</span><span class="p">(</span><span class="n">str</span><span class="p">));</span>
	<span class="p">}</span></code></pre>
</figure>

<p>Note how we cannot use <a href="https://en.cppreference.com/w/cpp/algorithm/max_element">max_element</a>, as that sadly requires a <a href="https://en.cppreference.com/w/cpp/named_req/ForwardIterator">forward iterator</a>.</p>

<h3 id="part-2-4">Part 2</h3>

<p>Given the same list, we were now tasked with finding the one and only missing element. The list does not necessarily start or end at the lowest and highest possible id, but our missing element was declared to be somewhere in between.
This could - again - be solved in more than one way, with up and downsides of runtime, memory usage or readability. First, the <a href="https://github.com/philipplenk/adventofcode20/tree/main/05/02_adjacent_find.cpp">more readable solution</a>, at an additional O(n) memory (for storing all ids) and O(n log n) runtime (for sorting them):</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&gt;</span> <span class="n">ids</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">transform</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{},</span><span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">ids</span><span class="p">),</span><span class="n">seat_id</span><span class="p">);</span>
	
<span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">ids</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">ids</span><span class="p">));</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="p">(</span><span class="o">*</span><span class="n">std</span><span class="o">::</span><span class="n">adjacent_find</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">ids</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">ids</span><span class="p">),[](</span><span class="k">auto</span> <span class="n">lhs</span><span class="p">,</span> <span class="k">auto</span> <span class="n">rhs</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">rhs</span><span class="o">-</span><span class="n">lhs</span><span class="o">&gt;</span><span class="mi">1</span><span class="p">;</span> <span class="p">})</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<p>Already pretty decent, but we can do better by knowing and abusing a tiny bit of bit magic, specifically the following lovely properties of the XOR operation:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A ^ A == 0
</code></pre></div></div>

<p>I.e. a number xor’ed with itself disappears. Further:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A^B == B^A
</code></pre></div></div>

<p>That is, the operation is commutative, the order in which it is performed does not matter. And finally:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A^0 == A 
</code></pre></div></div>

<p>A number xor’ed with 0 does not change.</p>

<p>All of this can be combined to imply this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(A^B^C^E...) ^ (A^B^C^D^E...)
</code></pre></div></div>

<p>will be equivalent to</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(A^A) ^ (B^B) ^ (C^C) ^ (E^E) ... ^ D
</code></pre></div></div>

<p>meaning the only one left over that is not zeroed will be our missing element! This yields <a href="https://github.com/philipplenk/adventofcode20/tree/main/05/02_xor.cpp">this beautifully efficient solution</a> that no one without knowledge of the trick has any realistic hope to grasp:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">min</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&gt;::</span><span class="n">max</span><span class="p">(),</span> <span class="n">max</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&gt;::</span><span class="n">min</span><span class="p">();</span>
<span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">xored</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">all</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">for_each</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{},[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">str</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">id</span> <span class="o">=</span> <span class="n">seat_id</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>
	<span class="n">min</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">min</span><span class="p">(</span><span class="n">min</span><span class="p">,</span><span class="n">id</span><span class="p">);</span>
	<span class="n">max</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">max</span><span class="p">,</span><span class="n">id</span><span class="p">);</span>
	<span class="n">xored</span><span class="o">^=</span><span class="n">id</span><span class="p">;</span>
<span class="p">});</span>
	
<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">i</span><span class="o">=</span><span class="n">min</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;=</span><span class="n">max</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="n">all</span><span class="o">^=</span><span class="n">i</span><span class="p">;</span>

<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="p">(</span><span class="n">xored</span><span class="o">^</span><span class="n">all</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<p>Knowing the trick, it does seem rather straightforward so and has only constant memory footprint and linear runtime, which is just fabulous ;-)</p>

<p>Accessibility can, however, be somewhat regained whilst not only keeping but even improving ever so slightly on this runtime by recognizing there is a simpler pair of operations with very similar properties: + and -.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A+0 = A

A-A = 0

A+B = B+A
</code></pre></div></div>

<p>Meaning, of course,</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(A+B+C+D+E...) - (A+B+C+E...) = (A-A) + (B-B) + (C-C) + D + (E-E)... = D
</code></pre></div></div>

<p>Simply summing all elements and subtracting that sum from what it would be if none were missing yields exactly the one missing element! Knowing <a href="https://www.youtube.com/watch?v=Dd81F6-Ar_0">a bit of history</a> and Gauss’s famous formula for computing the sum of all integers up to a given bound((n*n+n)/2), we can skip the second loop and directly compute the desired sum in closed form:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">min</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&gt;::</span><span class="n">max</span><span class="p">(),</span> <span class="n">max</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&gt;::</span><span class="n">min</span><span class="p">();</span>
<span class="kt">int</span> <span class="n">sum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">for_each</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{},[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">str</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">id</span> <span class="o">=</span> <span class="n">seat_id</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>
	<span class="n">min</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">min</span><span class="p">(</span><span class="n">min</span><span class="p">,</span><span class="n">id</span><span class="p">);</span>
	<span class="n">max</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">max</span><span class="p">,</span><span class="n">id</span><span class="p">);</span>
	<span class="n">sum</span><span class="o">+=</span><span class="n">id</span><span class="p">;</span>
<span class="p">});</span>
	
<span class="o">--</span><span class="n">min</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="p">((</span><span class="n">max</span><span class="o">*</span><span class="n">max</span><span class="o">+</span><span class="n">max</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="o">-</span><span class="p">(</span><span class="n">min</span><span class="o">*</span><span class="n">min</span><span class="o">+</span><span class="n">min</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="o">-</span><span class="n">sum</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<h2 id="day-6"><a href="https://github.com/philipplenk/adventofcode20/tree/main/06">Day 6</a></h2>

<h3 id="part-1-5">Part 1</h3>

<p>Given a number of “yes-or-no-questions” - each identified by a single character - we were provided with a list of “answers”, i.e. lines containing a character if the corresponding question was answered in the affirmative and not containing it otherwise.</p>

<p>Those answers were separated into groups by empty lines and our first task was to count in how many groups each “question”(i.e. character) was present. We then should return the sum of those counts.</p>

<p>Again - as seems to be a theme in those early days - the most difficult or rather time consuming part here is parsing question and input correctly, with the actual task being simple counting. Here is how I did it:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">,</span><span class="mi">256</span><span class="o">&gt;</span> <span class="n">counts</span><span class="p">{};</span>
<span class="k">const</span> <span class="k">auto</span> <span class="n">begin</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">counts</span><span class="p">[</span><span class="sc">'a'</span><span class="p">],</span> <span class="n">end</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">counts</span><span class="p">[</span><span class="sc">'z'</span><span class="o">+</span><span class="mi">1</span><span class="p">];</span>
	
<span class="k">const</span> <span class="k">auto</span> <span class="n">finish_group</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">]()</span>
<span class="p">{</span>		
	<span class="n">total</span><span class="o">+=</span><span class="n">std</span><span class="o">::</span><span class="n">count_if</span><span class="p">(</span><span class="n">begin</span><span class="p">,</span><span class="n">end</span><span class="p">,[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">v</span><span class="p">){</span> <span class="k">return</span> <span class="n">v</span><span class="o">!=</span><span class="mi">0</span><span class="p">;</span> <span class="p">});</span>
	<span class="n">std</span><span class="o">::</span><span class="n">fill</span><span class="p">(</span><span class="n">begin</span><span class="p">,</span><span class="n">end</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
<span class="p">};</span>
	
<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">getline</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">,</span><span class="n">line</span><span class="p">))</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">line</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
		<span class="n">finish_group</span><span class="p">();</span>
	<span class="k">else</span>
	<span class="p">{</span>
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">c</span><span class="o">:</span> <span class="n">line</span><span class="p">)</span>
			<span class="o">++</span><span class="n">counts</span><span class="p">[</span><span class="n">c</span><span class="p">];</span>
	<span class="p">}</span>
<span class="p">}</span>
<span class="n">finish_group</span><span class="p">();</span></code></pre>
</figure>

<p>Nothing much to explain here. I simply read the input, line by line, and count the frequency of all characters in an array indexed by the characters value - just like one would do when implementing <a href="https://en.wikipedia.org/wiki/Counting_sort">counting sort</a>. After an empty line, I finalize the group by counting how many entries were not 0 - that means they appeared at least once - and reset the counts.</p>

<p>Using an array to count is, of course, a bit of a waste of space, but I deemed it acceptable as the resulting code is succinct, readable and efficient. It also turned out to be useful for part 2.</p>

<h3 id="part-2-5">Part 2</h3>

<p>The second part did not, in fact, significantly ramp up the difficulty. Instead of counting how often each answer was given in total, we should only count those answers in a group which were given by everyone in it. As I already counted the frequency, all that was left was determining the group size:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp">	<span class="o">++</span><span class="n">group_size</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">c</span><span class="o">:</span> <span class="n">line</span><span class="p">)</span>
		<span class="o">++</span><span class="n">counts</span><span class="p">[</span><span class="n">c</span><span class="p">];</span></code></pre>
</figure>

<p>Followed by simply changing a “!=0” to a “==group_size”:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">finish_group</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">]()</span>
<span class="p">{</span>		
	<span class="n">total</span><span class="o">+=</span><span class="n">std</span><span class="o">::</span><span class="n">count</span><span class="p">(</span><span class="n">begin</span><span class="p">,</span><span class="n">end</span><span class="p">,</span><span class="n">group_size</span><span class="p">);</span>
	<span class="n">group_size</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="n">fill</span><span class="p">(</span><span class="n">begin</span><span class="p">,</span><span class="n">end</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
<span class="p">};</span></code></pre>
</figure>

<p>It might have broken if anyone had enthusiastically answered yes more than once on the same question, which, to my great relief, was not the case.</p>

<h2 id="day-7"><a href="https://github.com/philipplenk/adventofcode20/tree/main/07">Day 7</a></h2>

<h3 id="part-1-6">Part 1</h3>

<p>Finally a graph problem! Given a number of bags, all of which containing a number of different bags, first count all that will, in one of those interior ones, contain a “shiny gold” one. Before tackling the more interesting part here, we unfortunately do have to get some annoying parsing out of the way, which - as so frequently - took the bulk of my required time.</p>

<p>Which bags contain how many of which other bags was given as a string of this form:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
</code></pre></div></div>

<p>Or sometimes:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>faded blue bags contain no other bags.
</code></pre></div></div>

<p>It ought to be trivial, but I am embarrassed to say that this years problems really drove home the point that my skills in the parsing area are severely lacking and I have some serious brushing up to do. Some higher proficiency with regular expressions, for instance, might have tremendously simplified the following abomination I came up with at the time:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">in</span><span class="p">,</span> <span class="n">rule</span><span class="o">&amp;</span> <span class="n">r</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">r</span><span class="p">.</span><span class="n">own_name</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
	<span class="n">r</span><span class="p">.</span><span class="n">can_contain_n</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
	
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">str</span><span class="p">,</span> <span class="n">last</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">str</span> <span class="o">&amp;&amp;</span> <span class="n">str</span><span class="o">!=</span><span class="s">"contain"</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">r</span><span class="p">.</span><span class="n">own_name</span><span class="o">+=</span><span class="n">last</span><span class="p">;</span>
		<span class="n">last</span> <span class="o">=</span> <span class="n">str</span><span class="o">+</span><span class="s">" "</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="n">r</span><span class="p">.</span><span class="n">own_name</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
	
	<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">in</span><span class="p">)</span>
		<span class="k">return</span> <span class="n">in</span><span class="p">;</span>
	
	<span class="k">do</span>
	<span class="p">{</span>
		<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">n</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">n_str</span><span class="p">;</span>
		<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">n_str</span><span class="p">;</span>
		<span class="k">if</span><span class="p">(</span><span class="n">n_str</span><span class="o">==</span><span class="s">"no"</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">str</span><span class="o">&gt;&gt;</span><span class="n">str</span><span class="o">&gt;&gt;</span><span class="n">str</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
		
		<span class="n">n</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">stoi</span><span class="p">(</span><span class="n">n_str</span><span class="p">);</span>
		<span class="k">while</span><span class="p">(</span><span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">str</span> <span class="o">&amp;&amp;</span> <span class="n">str</span><span class="p">.</span><span class="n">back</span><span class="p">()</span><span class="o">!=</span><span class="sc">','</span> <span class="o">&amp;&amp;</span> <span class="n">str</span><span class="p">.</span><span class="n">back</span><span class="p">()</span><span class="o">!=</span><span class="sc">'.'</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">name</span><span class="o">+=</span><span class="n">str</span><span class="o">+</span><span class="s">" "</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="n">name</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
		<span class="n">r</span><span class="p">.</span><span class="n">can_contain_n</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">=</span><span class="n">n</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">while</span><span class="p">(</span><span class="n">str</span><span class="p">.</span><span class="n">back</span><span class="p">()</span><span class="o">!=</span><span class="sc">'.'</span><span class="p">);</span>
	
	<span class="k">return</span> <span class="n">in</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Don’t look at it too closely. Great! Now that we have this, let’s return to the root of our problem. Or rather the reverse. Interpreting the “contains” relation as edges in a graph, we can have one node for each bag type and an edge to all other bags in which it might be contained:</p>

<p>For instance, this description:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>green bags contain 2 red bags, 2 black bags.
red bags contain 1 blue bag.
blue bags contain 1 shiny gold bag, 3 black bags.
black bags contain no other bags.
shiny gold bags contain 7 gold bags.
</code></pre></div></div>

<p>would yield the following:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"red" &lt;--------- "blue" &lt;----- "shiny gold" &lt;----- "gold"
  |                ^ 
  v                |
"green"&lt;--"black"__|
</code></pre></div></div>

<p>Thanks to the eldritch horror above, such a reversed graph can be constructed easily, representing it as a map from <em>node-name</em> to <em>list-of-children-names</em>:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;&gt;</span> <span class="n">reverse_graph</span><span class="p">;</span>
<span class="n">rule</span> <span class="n">r</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="o">&gt;&gt;</span><span class="n">r</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">name</span><span class="p">,</span><span class="n">n</span><span class="p">]</span><span class="o">:</span><span class="n">r</span><span class="p">.</span><span class="n">can_contain_n</span><span class="p">)</span>
	<span class="n">reverse_graph</span><span class="p">[</span><span class="n">name</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">own_name</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</figure>

<p>Given that, all we need to do is walk each possible path away from our starting node (“shiny gold”) and count the total number of nodes we pass by(remembering which we have already seen and counted on the way):</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">left</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">unordered_set</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">seen</span><span class="p">;</span>
<span class="n">left</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="s">"shiny gold"</span><span class="p">);</span>

<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">left</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">next</span> <span class="o">=</span> <span class="n">left</span><span class="p">.</span><span class="n">back</span><span class="p">();</span>
	
	<span class="n">left</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span> 
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">target</span><span class="o">:</span> <span class="n">reverse_graph</span><span class="p">[</span><span class="n">next</span><span class="p">])</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">seen</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">target</span><span class="p">)</span><span class="o">==</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">seen</span><span class="p">))</span>
		<span class="p">{</span>
			<span class="n">seen</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">target</span><span class="p">);</span>
			<span class="n">left</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">target</span><span class="p">);</span>
			<span class="o">++</span><span class="n">count</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<h3 id="part-2-6">Part 2</h3>

<p>Wonderful! Now for part 2 we were tasked with doing basically the reverse. Instead of counting how many different kinds of bags can contain a shiny gold one, we are asked how many bags are contained within. This requires us to consider one more piece of information given in our data, the number telling us how often each kind of bag is contained within. Reversing the edges from part 1 and labeling them with a “cost” representing their quantity yields a graph like this one:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"red" ----1----&gt; "blue" --1--&gt; "shiny gold" ---7--&gt; "gold"
  ^                  | 
  2                  3
  |                  |
"green"-2-&gt;"black"&lt;__|
</code></pre></div></div>

<p>Which we will, once again, simply walk recursively from our starting location, multiplying the results by the given quantities:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">edge</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">target</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">weight</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">number_of_interior_bags</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">outer_name</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">edge</span><span class="o">&gt;&gt;&amp;</span> <span class="n">graph</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	<span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">graph</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">outer_name</span><span class="p">);</span>
	<span class="k">if</span><span class="p">(</span><span class="n">it</span><span class="o">==</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">graph</span><span class="p">))</span>
		<span class="k">return</span> <span class="n">count</span><span class="p">;</span>
		
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">name</span><span class="p">,</span><span class="n">n</span><span class="p">]</span><span class="o">:</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">)</span>
		<span class="n">count</span><span class="o">+=</span><span class="n">n</span><span class="o">*</span><span class="n">number_of_interior_bags</span><span class="p">(</span><span class="n">name</span><span class="p">,</span><span class="n">graph</span><span class="p">);</span>
	
	<span class="k">return</span> <span class="n">count</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<h2 id="day-8"><a href="https://github.com/philipplenk/adventofcode20/tree/main/08">Day 8</a></h2>

<h3 id="part-1-7">Part 1</h3>

<p>The interesting emulation problems have finally started! I really loved all the intcode problems in 2019, so this was getting my hopes up!</p>

<p>We started out slowly so and should just fix a simple program which executes one of only three types of instructions:</p>

<ul>
  <li>acc, adding to the accumulator</li>
  <li>jmp, a relative jump</li>
  <li>nop, my favorite thing, doing nothing</li>
</ul>

<p>As given, the program contained an infinite loop and we were tasked with determining its state once we enter the loop, i.e. once we execute an instruction for the second time. Without further ado, lets jump right into the code.</p>

<p>First, we define structs for our state and instructions:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">state</span>
<span class="p">{</span>
	<span class="kt">int</span> <span class="n">accumulator</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="kt">int</span> <span class="n">pc</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">enum</span> <span class="k">class</span> <span class="nc">opcode</span>
<span class="p">{</span>
	<span class="n">acc</span><span class="p">,</span>
	<span class="n">jmp</span><span class="p">,</span>
	<span class="n">nop</span>
<span class="p">};</span>

<span class="k">struct</span> <span class="nc">instruction</span>
<span class="p">{</span>
	<span class="n">opcode</span> <span class="n">op</span><span class="p">;</span>
	<span class="kt">int</span> <span class="n">arg</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>Parsing them is thankfully easy:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">in</span><span class="p">,</span> <span class="n">instruction</span><span class="o">&amp;</span> <span class="n">ins</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">name</span><span class="p">;</span>
	<span class="k">if</span><span class="p">(</span><span class="n">name</span><span class="o">==</span><span class="s">"acc"</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">=</span><span class="n">opcode</span><span class="o">::</span><span class="n">acc</span><span class="p">;</span>
		<span class="k">return</span> <span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">ins</span><span class="p">.</span><span class="n">arg</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="nf">if</span><span class="p">(</span><span class="n">name</span><span class="o">==</span><span class="s">"jmp"</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">=</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="p">;</span>
		<span class="k">return</span> <span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">ins</span><span class="p">.</span><span class="n">arg</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="nf">if</span><span class="p">(</span><span class="n">name</span><span class="o">==</span><span class="s">"nop"</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">=</span><span class="n">opcode</span><span class="o">::</span><span class="n">nop</span><span class="p">;</span>
		<span class="k">return</span> <span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">ins</span><span class="p">.</span><span class="n">arg</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">return</span> <span class="n">in</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>As is executing them, either adding to the accumulator or adding to the program counter or alternatively doing nothing at all:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">void</span> <span class="nf">execute</span><span class="p">(</span><span class="k">const</span> <span class="n">instruction</span><span class="o">&amp;</span> <span class="n">ins</span><span class="p">,</span> <span class="n">state</span><span class="o">&amp;</span> <span class="n">s</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">switch</span><span class="p">(</span><span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">case</span> <span class="n">opcode</span><span class="o">::</span><span class="n">acc</span><span class="p">:</span> <span class="n">s</span><span class="p">.</span><span class="n">accumulator</span><span class="o">+=</span><span class="n">ins</span><span class="p">.</span><span class="n">arg</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="p">:</span> <span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">+=</span><span class="n">ins</span><span class="p">.</span><span class="n">arg</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="n">opcode</span><span class="o">::</span><span class="n">nop</span><span class="p">:</span> <span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>To solve our problem, we first read all instructions into a vector, setup a pristine state with accumulator = pc = 0 and begin executing. 
After each instruction we increment the program counter to determine the next one, whilst keeping track - in a simple hashset - of all positions we have encountered so far. Upon reaching one that was previously seen, we declare the cycle detected and break our loop:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">instruction</span><span class="o">&gt;</span> <span class="n">instructions</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">instruction</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{});</span>

<span class="n">state</span> <span class="n">s</span><span class="p">{};</span>
<span class="n">std</span><span class="o">::</span><span class="n">unordered_set</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">seen</span><span class="p">;</span>

<span class="k">while</span><span class="p">(</span><span class="n">seen</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">)</span><span class="o">==</span><span class="n">seen</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
<span class="p">{</span>
	<span class="n">seen</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">);</span>
	<span class="n">execute</span><span class="p">(</span><span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">],</span><span class="n">s</span><span class="p">);</span>
	<span class="o">++</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">s</span><span class="p">.</span><span class="n">accumulator</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<p>Lovely, lets move on to…</p>

<h3 id="part-2-7">Part 2</h3>

<p>Now that we are able to emulate our loop, we are supposed to break it. There is one single nop or jmp instruction that if flipped to the opposite will cause our program to terminate by causing the program counter to reach the end of memory.</p>

<p>The most trivial and perfectly sufficient idea is to simply brute force it. Iterate over every instruction and if it is a jmp or nop, toggle it and try running our program from part 1. If a loop was detected, we try the next one. If not, we have found the instruction to change:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">ins</span><span class="o">:</span> <span class="n">instructions</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">!=</span><span class="n">opcode</span><span class="o">::</span><span class="n">acc</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">=</span><span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">==</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="o">?</span><span class="n">opcode</span><span class="o">::</span><span class="n">nop</span><span class="o">:</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="p">;</span>
		<span class="k">auto</span> <span class="p">[</span><span class="n">loop_detected</span><span class="p">,</span> <span class="n">result</span><span class="p">]</span> <span class="o">=</span> <span class="n">detect_loop</span><span class="p">(</span><span class="n">instructions</span><span class="p">);</span>
		<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">loop_detected</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">result</span><span class="p">.</span><span class="n">accumulator</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">=</span><span class="n">ins</span><span class="p">.</span><span class="n">op</span><span class="o">==</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="o">?</span><span class="n">opcode</span><span class="o">::</span><span class="n">nop</span><span class="o">:</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>To keep it readable, I outsourced loop detection and gave it a nice, expressive return type:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">execution_result</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">loop_detected</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
	<span class="n">state</span> <span class="n">final_state</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">execution_result</span> <span class="nf">detect_loop</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">instruction</span><span class="o">&gt;&amp;</span> <span class="n">instructions</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">state</span> <span class="n">s</span><span class="p">{};</span>
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">seen</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span><span class="nb">false</span><span class="p">);</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">seen</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">])</span>
	<span class="p">{</span>
		<span class="n">seen</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
		<span class="n">execute</span><span class="p">(</span><span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">],</span><span class="n">s</span><span class="p">);</span>
		<span class="o">++</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="k">return</span> <span class="p">{</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">()),</span> <span class="n">s</span><span class="p">};</span>
<span class="p">}</span></code></pre>
</figure>

<p>Whilst this is perfectly sufficient in our case and terminates within a small fraction of a second even on my old machines, it is not exactly ideal. Worst case, its asymptotic complexity seems quadratic. Consider this example:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nop 1
nop 1
nop 1
....
jmp -program_size
</code></pre></div></div>

<p>It would run over each nop, run the complete program to the very end, detect the loop and try the next one. That is, each attempt before the last executes n-1 nop and 2 jmp instructions and we need to do that n-1 times. Quite terrifying. So lets do better:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">auto</span> <span class="n">reaches_end</span> <span class="o">=</span> <span class="n">compute_end_reachability</span><span class="p">(</span><span class="n">instructions</span><span class="p">);</span>

<span class="n">state</span> <span class="n">s</span><span class="p">{};</span>
<span class="kt">bool</span> <span class="n">changed_one</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>

<span class="k">while</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">()))</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">changed_one</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">target_pc</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">+</span><span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">].</span><span class="n">arg</span><span class="p">;</span>
		<span class="k">if</span><span class="p">(</span><span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">].</span><span class="n">op</span><span class="o">==</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">reaches_end</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">reaches_end</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="o">+</span><span class="mi">1</span><span class="p">])</span>
		<span class="p">{</span>
			<span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">].</span><span class="n">op</span><span class="o">=</span><span class="n">opcode</span><span class="o">::</span><span class="n">nop</span><span class="p">;</span>
			<span class="n">changed_one</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="k">else</span> <span class="nf">if</span><span class="p">(</span><span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">].</span><span class="n">op</span><span class="o">==</span><span class="n">opcode</span><span class="o">::</span><span class="n">nop</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">reaches_end</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">reaches_end</span><span class="p">[</span><span class="n">target_pc</span><span class="p">])</span>
		<span class="p">{</span>
			<span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">].</span><span class="n">op</span><span class="o">=</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="p">;</span>
			<span class="n">changed_one</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
	<span class="n">execute</span><span class="p">(</span><span class="n">instructions</span><span class="p">[</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">],</span><span class="n">s</span><span class="p">);</span>
	<span class="o">++</span><span class="n">s</span><span class="p">.</span><span class="n">pc</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">s</span><span class="p">.</span><span class="n">accumulator</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<p>Looks a bit more complex than our previous attempt, but the running time turns out to be linear. Allow me to first explain my reasoning:</p>

<p>Assuming we knew for each instruction if beginning execution from it will reach the end, we could execute our code once and simply change the first instruction we encounter that could not reach the end but could if toggled. Doing such a thing would run in linear time, as no loops are entered and each instruction is executed at most once. That is exactly what you see happening in the code above.</p>

<p>This, however, delegates the hard problem to figuring out which instructions can and cannot reach the end:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">compute_jump_sources</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">instruction</span><span class="o">&gt;&amp;</span> <span class="n">instructions</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">jump_sources</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">());</span>
	<span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">pc</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">pc</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">());</span><span class="o">++</span><span class="n">pc</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">target_pc</span> <span class="o">=</span> <span class="n">pc</span><span class="o">+</span><span class="n">instructions</span><span class="p">[</span><span class="n">pc</span><span class="p">].</span><span class="n">arg</span><span class="p">;</span>
		<span class="k">if</span><span class="p">(</span><span class="n">instructions</span><span class="p">[</span><span class="n">pc</span><span class="p">].</span><span class="n">op</span><span class="o">==</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span> <span class="o">&amp;&amp;</span> <span class="n">target_pc</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">target_pc</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">()))</span>
			<span class="n">jump_sources</span><span class="p">[</span><span class="n">target_pc</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">pc</span><span class="p">);</span>
	<span class="p">}</span>
	
	<span class="k">return</span> <span class="n">jump_sources</span><span class="p">;</span>
<span class="p">}</span>
	
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">compute_end_reachability</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">instruction</span><span class="o">&gt;&amp;</span> <span class="n">instructions</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">reaches_end</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span><span class="nb">false</span><span class="p">);</span>
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">seen</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span><span class="nb">false</span><span class="p">);</span>
	
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">jump_sources</span> <span class="o">=</span> <span class="n">compute_jump_sources</span><span class="p">(</span><span class="n">instructions</span><span class="p">);</span>
	
	<span class="k">const</span> <span class="k">auto</span> <span class="n">mark_upward</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">int</span> <span class="n">start_pc</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">value</span><span class="p">,</span> <span class="k">auto</span> <span class="n">recurse</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">void</span>
	<span class="p">{</span>		
		<span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">pc</span> <span class="o">=</span> <span class="n">start_pc</span><span class="p">;</span> <span class="n">pc</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">seen</span><span class="p">[</span><span class="n">pc</span><span class="p">];</span> <span class="o">--</span><span class="n">pc</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">const</span> <span class="k">auto</span> <span class="n">target_pc</span> <span class="o">=</span> <span class="n">pc</span><span class="o">+</span><span class="n">instructions</span><span class="p">[</span><span class="n">pc</span><span class="p">].</span><span class="n">arg</span><span class="p">;</span>
			<span class="k">if</span><span class="p">(</span><span class="n">instructions</span><span class="p">[</span><span class="n">pc</span><span class="p">].</span><span class="n">op</span><span class="o">==</span><span class="n">opcode</span><span class="o">::</span><span class="n">jmp</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="k">if</span><span class="p">(</span><span class="n">target_pc</span><span class="o">&lt;</span><span class="mi">0</span> <span class="o">||</span> <span class="n">target_pc</span><span class="o">&gt;=</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">()))</span>
					<span class="n">value</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
				<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">seen</span><span class="p">[</span><span class="n">target_pc</span><span class="p">])</span>
					<span class="n">value</span> <span class="o">=</span> <span class="n">reaches_end</span><span class="p">[</span><span class="n">target_pc</span><span class="p">];</span>
				<span class="k">else</span>
					<span class="k">break</span><span class="p">;</span>
			<span class="p">}</span>
			<span class="n">seen</span><span class="p">[</span><span class="n">pc</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
			<span class="n">reaches_end</span><span class="p">[</span><span class="n">pc</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="p">;</span>
			
			<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">source</span><span class="o">:</span> <span class="n">jump_sources</span><span class="p">[</span><span class="n">pc</span><span class="p">])</span>
				<span class="n">recurse</span><span class="p">(</span><span class="n">source</span><span class="p">,</span><span class="n">value</span><span class="p">,</span><span class="n">recurse</span><span class="p">);</span>
		<span class="p">}</span>
	<span class="p">};</span>
	
	<span class="n">mark_upward</span><span class="p">(</span><span class="n">instructions</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="nb">true</span><span class="p">,</span><span class="n">mark_upward</span><span class="p">);</span>
	
	<span class="k">return</span> <span class="n">reaches_end</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>I am iterating over all instructions once to determine from where each instruction can be reached(compute_jump_sources). Then I iterate again and mark which instructions can reach the end. Turns out that is not quite so hard either. We have to realize the following simple facts:</p>

<ul>
  <li>A non-jmp instruction can reach the end if it is at the end or if the one following it could reach the end</li>
  <li>A jmp instruction can reach the end if its target is the end or can reach the end</li>
</ul>

<p>As such, we start with the only one we know about - the end - and work our way upwards. If its not a jump, we simply mark it with the previous result. If its a jump and we know about its destination, we continue with the destinations value. If its a jump and we don’t know about its destination, we can’t proceed and break. Furthermore, if the current instruction can be reached by a jump, we recurse and work our way upward from its source, too.</p>

<p>Runtime analysis of this might seem like a mess, but our seen-vector rushes in to save the day: 
There are at most n jump sources in total (as there are at most n jmp instructions), as such recurse can be called at most n times in total), so we have at most n loops.
Each iteration of the loop either breaks or sets a value in the seen vector to true which was not set previously. As each loop can of course only break once, the total number the first can happen is n.
As seen has exactly n elements and we only enter an iteration and set a value if it was not set, the total number the second can happen - over all loops - is also n.</p>

<p>Just lovely, isn’t it?</p>

<h2 id="day-9"><a href="https://github.com/philipplenk/adventofcode20/tree/main/09">Day 9</a></h2>

<h3 id="part-1-8">Part 1</h3>

<p>Surprisingly easy given the previous two assignments, our quest on this day was simply adding up numbers. We were given a list of them and should find the first one that cannot be represented as a sum of two of the 25 preceding ones. The more perceptive of my readers probably realized by now, that in the grand tradition of instructional <a href="https://en.wikipedia.org/wiki/Spiral_approach">spiraling</a>, this is but a slightly more complicated variation of what we did on day 1!</p>

<p>As such, a trivial - yet horrific in time complexity - <a href="https://github.com/philipplenk/adventofcode20/tree/main/09/01_trivial.cpp">solution</a> is to brute force our way through the problem with 3 ugly nested loops:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="n">n</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">data</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">-</span><span class="n">n</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">i</span><span class="p">;</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">k</span><span class="o">=</span><span class="n">j</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="n">k</span><span class="o">&lt;</span><span class="n">i</span><span class="p">;</span><span class="o">++</span><span class="n">k</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">if</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">+</span><span class="n">data</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="o">==</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
			<span class="p">{</span>
				<span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="p">}</span>
		<span class="p">}</span>
		<span class="k">if</span><span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">found</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>Funnily enough, that is still fast enough and if we analyzed its complexity at university level, we would call it O(n), as 25 is a constant and so is 25^2. 375 * n is still O(n), so we are golden xD. Well, as you might have guessed from my somewhat snappy tone here, I don’t really like that much. We also keep all of our range in memory right now, which could be avoided.</p>

<p>We only need the last 25 numbers, so lets start with that:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">N</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">trivial_fixed_ring</span>
<span class="p">{</span>
	<span class="nl">public:</span>
	<span class="k">using</span> <span class="n">value_type</span> <span class="o">=</span> <span class="n">T</span><span class="p">;</span>
	
	<span class="kt">void</span> <span class="n">push_back</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">value</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">data_</span><span class="p">[</span><span class="n">start_</span><span class="o">++</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="p">;</span>
		<span class="n">start_</span><span class="o">%=</span><span class="n">N</span><span class="p">;</span>
		
	<span class="p">}</span>
	
	<span class="k">auto</span><span class="o">&amp;</span> <span class="k">operator</span><span class="p">[](</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">idx</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">return</span> <span class="n">data_</span><span class="p">[(</span><span class="n">start_</span><span class="o">+</span><span class="n">idx</span><span class="p">)</span><span class="o">%</span><span class="n">N</span><span class="p">];</span>
	<span class="p">}</span>
	
	<span class="k">auto</span><span class="o">&amp;</span> <span class="k">operator</span><span class="p">[](</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">idx</span><span class="p">)</span> <span class="k">const</span>
	<span class="p">{</span>
		<span class="k">return</span> <span class="n">data_</span><span class="p">[(</span><span class="n">start_</span><span class="o">+</span><span class="n">idx</span><span class="p">)</span><span class="o">%</span><span class="n">N</span><span class="p">];</span>
	<span class="p">}</span>
	
	<span class="k">auto</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">N</span><span class="p">;</span> <span class="p">}</span>
	
	<span class="k">private</span><span class="o">:</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="n">N</span><span class="o">&gt;</span> <span class="n">data_</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">start_</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>Yeah, as there is none in the standard library<sup id="fnref:ring" role="doc-noteref"><a href="#fn:ring" class="footnote" rel="footnote">9</a></sup>, implementing a small, bad and severely broken ring buffer might be ever so slight overkill, considering the input list is a mere 1000 numbers and the approach above runs in the fraction of a fraction of a fraction of a second, but who am I if not one to always entertain the notion of severely overengineering the most trivial of tasks?</p>

<p>Utilizing this data structure, our solution changes to look like this:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">constexpr</span> <span class="k">auto</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">25</span><span class="p">;</span>
<span class="n">trivial_fixed_ring</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="n">n</span><span class="o">&gt;</span> <span class="n">data</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">copy_n</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},</span><span class="n">n</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">data</span><span class="p">));</span>

<span class="kt">int</span> <span class="n">next</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="o">&gt;&gt;</span><span class="n">next</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">data</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">data</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">if</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">+</span><span class="n">data</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="o">==</span><span class="n">next</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="n">found</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="p">}</span>
		<span class="p">}</span>
		<span class="k">if</span><span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
	
	<span class="n">data</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">next</span><span class="p">);</span>
<span class="p">}</span>

<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">next</span><span class="p">;</span></code></pre>
</figure>

<p>Our theoretical runtime can be reduced by using the exact same methods employed on day 1: either via sorting or via wasting a potentially huge amount of memory.</p>

<p>Let’s do <a href="https://github.com/philipplenk/adventofcode20/tree/main/09/01_sort.cpp">sorting first</a>. We can’t sort in place, as the original order dictates which elements will be replaced in succeeding steps, which is why we have to copy them into an additional buffer first:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="n">n</span><span class="o">&gt;</span> <span class="n">buffer</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">partial_sort_copy</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">data</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">data</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">buffer</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">buffer</span><span class="p">));</span></code></pre>
</figure>

<p>We then walk this buffer once, binary-searching for the missing element:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">v</span><span class="o">:</span> <span class="n">buffer</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">found</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">binary_search</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">buffer</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">buffer</span><span class="p">),</span><span class="n">next</span><span class="o">-</span><span class="n">v</span><span class="p">);</span>
	<span class="k">if</span><span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span></code></pre>
</figure>

<p>Lovely, isn’t it? We reduced our complexity down to O(n) * O(25 log 25), which is, asymptotically speaking, completely irrelevant. If the constant were ever increased, however, it could prove useful to reduce it even further.</p>

<p>Last time, we had a convenient constraint on how big our numbers could get, which was completely thrown out for this task. Numbers here can - and apparently do - get arbitrarily big, so its kind of impossible to allocate a big enough array in advance. Whilst we could determine this number in linear time(by simply scanning the input once and saving max and min values), a simple bitset won’t do, as our sliding window might contain more than one copy of the same value and we have to keep track of when all of those fall out of the window, i.e. we have to count. Considering my solution was &gt;20 million, keeping one integer for each <em>possible</em> one in the input constitutes unfathomable abuse of memory even for the likes of me, so I bailed out and decided on using a hashmap instead, which will - at least on average - still provide me with O(1)-ish access time:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">seen</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">v</span><span class="o">:</span> <span class="n">data</span><span class="p">)</span> <span class="o">++</span><span class="n">seen</span><span class="p">[</span><span class="n">v</span><span class="p">];</span>

<span class="kt">int</span> <span class="n">next</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="o">&gt;&gt;</span><span class="n">next</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">found</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">v</span><span class="o">:</span> <span class="n">data</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">found</span> <span class="o">=</span> <span class="n">seen</span><span class="p">[</span><span class="n">next</span><span class="o">-</span><span class="n">v</span><span class="p">]</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">;</span>
		<span class="k">if</span><span class="p">(</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">found</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
	
	<span class="o">--</span><span class="n">seen</span><span class="p">[</span><span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]];</span>
	<span class="o">++</span><span class="n">seen</span><span class="p">[</span><span class="n">next</span><span class="p">];</span>
	<span class="n">data</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">next</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</figure>

<h3 id="part-2-8">Part 2</h3>

<p>Surprisingly even easier than part 1 this time. Take the number we just obtained and find a contiguous set of size&gt;2 in our data that sums to it. We can do this easily by keeping a running set, always adding the next number and - if we ever run over our target - erase from the start until we are &lt;= to it again:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">data</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{});</span>
<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">min</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">data</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">sum</span><span class="o">+=</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
	<span class="k">while</span><span class="p">(</span><span class="n">sum</span><span class="o">&gt;</span><span class="n">target</span> <span class="o">&amp;&amp;</span> <span class="n">min</span><span class="o">&lt;</span><span class="n">i</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">sum</span><span class="o">-=</span><span class="n">data</span><span class="p">[</span><span class="n">min</span><span class="p">];</span>
		<span class="o">++</span><span class="n">min</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">if</span><span class="p">(</span><span class="n">sum</span><span class="o">==</span><span class="n">target</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">auto</span> <span class="p">[</span><span class="n">min_it</span><span class="p">,</span><span class="n">max_it</span><span class="p">]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">minmax_element</span><span class="p">(</span><span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="n">min</span><span class="p">],</span><span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
		<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;*</span><span class="n">min_it</span><span class="o">+*</span><span class="n">max_it</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<h2 id="day-10"><a href="https://github.com/philipplenk/adventofcode20/tree/main/10">Day 10</a></h2>

<h3 id="part-1-9">Part 1</h3>

<p>Travel power adapters, oh my. The cover story is a cute one, but the actual problem is rather straightforward. Given a number of “joltage” adapters output values, connectable if they are between 1 and 3 apart and the second is higher than the first, figure out how often they are apart by 1 and how often they are apart by 3 if all were connected together. Since we never can connect a higher to a lower adapter, we simply sort and count the difference between every two elements:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">jolts</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">{});</span>
<span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">jolts</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">jolts</span><span class="p">));</span>

<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">diff1</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">diff3</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">last</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">jolts</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">jolts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-</span><span class="n">last</span><span class="p">;</span>
	<span class="k">if</span><span class="p">(</span><span class="n">diff</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
		<span class="o">++</span><span class="n">diff1</span><span class="p">;</span>
	<span class="k">if</span><span class="p">(</span><span class="n">diff</span><span class="o">==</span><span class="mi">3</span><span class="p">)</span>
		<span class="o">++</span><span class="n">diff3</span><span class="p">;</span>
	<span class="n">last</span> <span class="o">=</span> <span class="n">jolts</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="p">(</span><span class="n">diff1</span><span class="o">*</span><span class="p">(</span><span class="n">diff3</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<h3 id="part-2-9">Part 2</h3>

<p>That was ever so slightly more difficult. My first hunch was a simple recursive solution, counting the options:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">count_options</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">long</span><span class="o">&gt;&amp;</span> <span class="n">jolts</span><span class="p">,</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">last_jolt</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">next_idx</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">begin_jolt</span> <span class="o">=</span> <span class="n">last_jolt</span><span class="p">;</span>
	
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">result</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="n">next_idx</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">jolts</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">jolts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-</span><span class="n">last_jolt</span><span class="p">;</span>
		
		<span class="k">if</span><span class="p">(</span><span class="n">diff</span><span class="o">&gt;</span><span class="mi">3</span><span class="p">)</span>
			<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
			
		<span class="k">if</span><span class="p">(</span><span class="n">diff</span><span class="o">&lt;</span><span class="mi">3</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">jolts</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
			<span class="n">result</span><span class="o">+=</span><span class="n">count_options</span><span class="p">(</span><span class="n">jolts</span><span class="p">,</span><span class="n">last_jolt</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="n">cache</span><span class="p">);</span>
		
		<span class="n">last_jolt</span> <span class="o">=</span> <span class="n">jolts</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
	<span class="p">}</span>
	
	<span class="k">return</span> <span class="n">result</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Turns out that is not ideal for a number of reasons, most obvious among them is runtime and repeated work. If, for instance, we skip the first adapter and take the second and third on one path, whilst we take the first, skip the second and take the third, the total may be different, but what follows afterwards is exactly the same. Nonetheless, the code above will compute this twice. Every subpath can be reached in a multitude of ways and I recompute it every. single. time. Let’s fix that:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">count_options</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">long</span><span class="o">&gt;&amp;</span> <span class="n">jolts</span><span class="p">,</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">last_jolt</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">next_idx</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">long</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;&amp;</span> <span class="n">cache</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="k">auto</span> <span class="n">it</span><span class="o">=</span><span class="n">cache</span><span class="p">.</span><span class="n">find</span><span class="p">({</span><span class="n">last_jolt</span><span class="p">,</span><span class="n">next_idx</span><span class="p">});</span><span class="n">it</span><span class="o">!=</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">cache</span><span class="p">))</span>
		<span class="k">return</span> <span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">;</span>
		
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">begin_jolt</span> <span class="o">=</span> <span class="n">last_jolt</span><span class="p">;</span>
	
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">result</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="n">next_idx</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">jolts</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">jolts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-</span><span class="n">last_jolt</span><span class="p">;</span>
		
		<span class="k">if</span><span class="p">(</span><span class="n">diff</span><span class="o">&gt;</span><span class="mi">3</span><span class="p">)</span>
			<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
			
		<span class="k">if</span><span class="p">(</span><span class="n">diff</span><span class="o">&lt;</span><span class="mi">3</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">jolts</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
			<span class="n">result</span><span class="o">+=</span><span class="n">count_options</span><span class="p">(</span><span class="n">jolts</span><span class="p">,</span><span class="n">last_jolt</span><span class="p">,</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="n">cache</span><span class="p">);</span>
		
		<span class="n">last_jolt</span> <span class="o">=</span> <span class="n">jolts</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
	<span class="p">}</span>
	
	<span class="k">return</span> <span class="n">cache</span><span class="p">[{</span><span class="n">begin_jolt</span><span class="p">,</span><span class="n">next_idx</span><span class="p">}]</span> <span class="o">=</span> <span class="n">result</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>I employed the time honored tradition of slapping a cache onto my recursion to avoid duplicating work. This turns out to be more than fast enough for our problem and a result is available within the fraction of a second again. Nonetheless, we could have done even better, even if I failed to figure that one out myself in the heat of the moment. It was pointed out to me on the <a href="https://www.includecpp.org/discord/">#include discord</a> and is visible in <a href="https://gitlab.com/stephanroslen/aoc2020/-/blob/master/day10/main.cpp">this solution</a>. Instead of going forward and counting what could follow, we can - true to the spirit of <a href="https://en.wikipedia.org/wiki/Dynamic_programming">dynamic programming</a> - go backward and count the pathes we have already seen. Basically the same idea, but we can save the hashmap and know ahead of time how many entries we will need.</p>

<p>Wonderful, but checking <a href="https://www.reddit.com/r/adventofcode/comments/kabi91/2020_day_10_closedform_mathematical_solution/">the lovely reddit</a>, you will figure out there is an even better, if far more mathy<sup id="fnref:mathy" role="doc-noteref"><a href="#fn:mathy" class="footnote" rel="footnote">10</a></sup> and slightly less intuitive way running in what is apparently linear time. Turns out there is a connection to the <a href="https://en.wikipedia.org/wiki/Generalizations_of_Fibonacci_numbers#Tribonacci_numbers">tribonacci sequence</a>.</p>

<p>That was fun and I almost got near the global leaderboard for once, rank 508, my best so far this year.)</p>

<h2 id="day-11"><a href="https://github.com/philipplenk/adventofcode20/tree/main/11">Day 11</a></h2>

<h3 id="part-1-10">Part 1</h3>

<p><a href="https://en.wikipedia.org/wiki/Cellular_automaton">Cellular automata</a>! Quite fitting, to honor <a href="https://en.wikipedia.org/wiki/John_Horton_Conway">John Conway’s</a> legacy - in the sad year of his passing - with another one of those. The cover story here is about seats and people admirably practicing social distancing. If they have too many neighbors, they move away. Given an initial state and a simple set of rules, we had to simulate the seating constellations until they reach a stable, unchanging state.
Rather straightforward, so edges, corners and the fact that all cells update simultaneously always complicates issues slightly. Here is one update step:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">constexpr</span> <span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">vec2d</span><span class="p">,</span><span class="mi">8</span><span class="o">&gt;</span> <span class="n">directions</span><span class="p">{{{</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">},{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">},{</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">},{</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">},{</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">},{</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">},{</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">},{</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">}}};</span>
		
<span class="k">auto</span> <span class="n">next</span> <span class="o">=</span> <span class="n">grid</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">changed</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">foreach_in_square</span><span class="p">({</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">},{</span><span class="n">grid_width</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="n">grid_height</span><span class="o">-</span><span class="mi">1</span><span class="p">},[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">p</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">p</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">p</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'.'</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
	
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">adjacent_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">d</span><span class="o">:</span> <span class="n">directions</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">target</span> <span class="o">=</span> <span class="n">p</span><span class="o">+</span><span class="n">d</span><span class="p">;</span>
		<span class="k">if</span><span class="p">(</span><span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="o">&lt;</span><span class="n">grid_width</span> <span class="o">&amp;&amp;</span> <span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="o">&lt;</span><span class="n">grid_height</span><span class="p">)</span>
			<span class="n">adjacent_count</span><span class="o">+=</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'#'</span><span class="p">);</span>
	<span class="p">}</span>
		
	<span class="k">if</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">p</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">p</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'L'</span> <span class="o">&amp;&amp;</span> <span class="n">adjacent_count</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">next</span><span class="p">[</span><span class="n">p</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">p</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'#'</span><span class="p">;</span>
		<span class="n">changed</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span> <span class="nf">if</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">p</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">p</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'#'</span> <span class="o">&amp;&amp;</span> <span class="n">adjacent_count</span><span class="o">&gt;=</span><span class="mi">4</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">next</span><span class="p">[</span><span class="n">p</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">p</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'L'</span><span class="p">;</span>
		<span class="n">changed</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">});</span>
	
<span class="n">grid</span> <span class="o">=</span> <span class="n">next</span><span class="p">;</span></code></pre>
</figure>

<p>We create a copy of all cells, and iterate over all coordinates. For each of those we iterate over all valid neighbors and count how many of them are occupied, setting the new value in our copy according to the given rules. We can’t set it in our current grid, as all cells should act as if they updated simultaneously and modifying the grid step by step would change results for later processed cells which contain already updated ones as neighbors.</p>

<h3 id="part-2-10">Part 2</h3>

<p>The difficulty was increased ever so slightly by not only considering direct neighbors but everything within ones line of sight. Nothing a simple loop can’t solve, thankfully:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">d</span><span class="o">:</span> <span class="n">directions</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">target</span> <span class="o">=</span> <span class="n">p</span><span class="o">+</span><span class="n">d</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="o">&lt;</span><span class="n">grid_width</span> <span class="o">&amp;&amp;</span> <span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="o">&gt;=</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="o">&lt;</span><span class="n">grid_height</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'#'</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="o">++</span><span class="n">adjacent_count</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="k">if</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'L'</span><span class="p">)</span>
			<span class="k">break</span><span class="p">;</span>
					
		<span class="n">target</span><span class="o">+=</span><span class="n">d</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<h2 id="day-12"><a href="https://github.com/philipplenk/adventofcode20/tree/main/12">Day 12</a></h2>

<h3 id="part-1-11">Part 1</h3>

<p>Given a number of instructions for moving a ship around on a simple 2 dimensional coordinate system (but with cardinal directions), we had to correctly determine which position we end up in. The minor difficulty arises from some directions not being absolute, but relative to the ships current orientation, which we also have to keep track of. Let’s not get ahead of ourselves and first declare the possible instructions and define how they are parsed:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">enum</span> <span class="k">class</span> <span class="nc">type</span>
<span class="p">{</span>
	<span class="n">turn_left</span><span class="p">,</span>
	<span class="n">turn_right</span><span class="p">,</span>
	<span class="n">move_forward</span><span class="p">,</span>
	<span class="n">move</span>
<span class="p">};</span>

<span class="k">struct</span> <span class="nc">instruction</span>
<span class="p">{</span>
	<span class="n">type</span> <span class="n">t</span><span class="p">;</span>
	<span class="kt">int</span> <span class="n">step</span><span class="p">;</span>
	<span class="n">vec2d</span> <span class="n">direction</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">in</span><span class="p">,</span> <span class="n">instruction</span><span class="o">&amp;</span> <span class="n">ins</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">char</span> <span class="n">c</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">c</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span>
	<span class="k">switch</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">case</span> <span class="sc">'N'</span><span class="p">:</span> <span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="o">=</span><span class="n">type</span><span class="o">::</span><span class="n">move</span><span class="p">;</span> <span class="n">ins</span><span class="p">.</span><span class="n">direction</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">};</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="sc">'E'</span><span class="p">:</span> <span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="o">=</span><span class="n">type</span><span class="o">::</span><span class="n">move</span><span class="p">;</span> <span class="n">ins</span><span class="p">.</span><span class="n">direction</span><span class="o">=</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">};</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="sc">'W'</span><span class="p">:</span> <span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="o">=</span><span class="n">type</span><span class="o">::</span><span class="n">move</span><span class="p">;</span> <span class="n">ins</span><span class="p">.</span><span class="n">direction</span><span class="o">=</span><span class="p">{</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">};</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="sc">'S'</span><span class="p">:</span> <span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="o">=</span><span class="n">type</span><span class="o">::</span><span class="n">move</span><span class="p">;</span> <span class="n">ins</span><span class="p">.</span><span class="n">direction</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">};</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="sc">'F'</span><span class="p">:</span> <span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="o">=</span><span class="n">type</span><span class="o">::</span><span class="n">move_forward</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="sc">'R'</span><span class="p">:</span> <span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="o">=</span><span class="n">type</span><span class="o">::</span><span class="n">turn_right</span><span class="p">;</span> <span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="o">/=</span><span class="mi">90</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="sc">'L'</span><span class="p">:</span> <span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="o">=</span><span class="n">type</span><span class="o">::</span><span class="n">turn_left</span><span class="p">;</span> <span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="o">/=</span><span class="mi">90</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">default</span><span class="o">:</span> <span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">return</span> <span class="n">in</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>I already did some minimal preprocessing here. For one, I chose to save the directions as 2d vectors for easier addition.</p>

<p>Furthermore, I noticed all turns happened in multiples of 90 degree, so instead of saving the angles, I remembered how many 90 degree turns they correspond to. 90 degree turns are easy:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">vec2d</span> <span class="nf">turn_left</span><span class="p">(</span><span class="n">vec2d</span> <span class="n">old</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">swap</span><span class="p">(</span><span class="n">old</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">old</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
	<span class="n">old</span><span class="p">.</span><span class="n">y</span><span class="o">=-</span><span class="n">old</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
	<span class="k">return</span> <span class="n">old</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">vec2d</span> <span class="nf">turn_right</span><span class="p">(</span><span class="n">vec2d</span> <span class="n">old</span><span class="p">)</span>
<span class="p">{</span>	
	<span class="n">std</span><span class="o">::</span><span class="n">swap</span><span class="p">(</span><span class="n">old</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">old</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
	<span class="n">old</span><span class="p">.</span><span class="n">x</span><span class="o">=-</span><span class="n">old</span><span class="p">.</span><span class="n">x</span><span class="p">;</span>
	<span class="k">return</span> <span class="n">old</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Whilst it could maybe have been solved more elegantly with complex multiplication, this works perfectly fine for now so and I really like the clarity of this code which is readable without much of a mathematical background (although it’s always nice to have that nonetheless).</p>

<p>Given this scaffolding, all that is left is iterating over the instructions and modifying either position or direction accordingly:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">for_each</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream_iterator</span><span class="o">&lt;</span><span class="n">instruction</span><span class="o">&gt;</span><span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">},{},[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">ins</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">switch</span><span class="p">(</span><span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">move</span><span class="p">:</span> <span class="n">pos</span><span class="o">+=</span><span class="n">ins</span><span class="p">.</span><span class="n">direction</span><span class="o">*</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">turn_left</span><span class="p">:</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">current_direction</span> <span class="o">=</span> <span class="n">turn_left</span><span class="p">(</span><span class="n">current_direction</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">turn_right</span><span class="p">:</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">current_direction</span> <span class="o">=</span> <span class="n">turn_right</span><span class="p">(</span><span class="n">current_direction</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
		<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">move_forward</span><span class="p">:</span> <span class="n">pos</span><span class="o">+=</span><span class="n">current_direction</span><span class="o">*</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">});</span></code></pre>
</figure>

<h3 id="part-2-11">Part 2</h3>

<p>Part 2 on this day was nearly identical, only the “move”-instructions were changed to not move the ship directly but modify its movement vector instead, which was applied on the “move-forward” command. The turn commands were also changed to turn the movement vector. Again, it could have been simplified with complex numbers, but worked out fine with my trivialized approach, the only change being one case of instruction handling:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">switch</span><span class="p">(</span><span class="n">ins</span><span class="p">.</span><span class="n">t</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">move</span><span class="p">:</span> <span class="n">waypoint</span><span class="o">+=</span><span class="n">ins</span><span class="p">.</span><span class="n">direction</span><span class="o">*</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">turn_left</span><span class="p">:</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">waypoint</span> <span class="o">=</span> <span class="n">turn_left</span><span class="p">(</span><span class="n">waypoint</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">turn_right</span><span class="p">:</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">waypoint</span> <span class="o">=</span> <span class="n">turn_right</span><span class="p">(</span><span class="n">waypoint</span><span class="p">);</span> <span class="k">break</span><span class="p">;</span>
	<span class="k">case</span> <span class="n">type</span><span class="o">::</span><span class="n">move_forward</span><span class="p">:</span> <span class="n">pos</span><span class="o">+=</span><span class="n">waypoint</span><span class="o">*</span><span class="n">ins</span><span class="p">.</span><span class="n">step</span><span class="p">;</span> <span class="k">break</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<h2 id="day-13"><a href="https://github.com/philipplenk/adventofcode20/tree/main/13">Day 13</a></h2>

<h3 id="part-1-12">Part 1</h3>

<p>Given a starting time and a number of bus ids - which also represented their round trip time - we were tasked with finding the first bus to arrive at or after the starting time. For this one, all busses started out at 0, meaning we only had determine the first multiple of each id &gt;= the starting time and choose the minimum of those. To do so, we compute the ceil(i.e. rounded up) result of dividing the starting time by id and subsequently multiply id by that result:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">long</span> <span class="n">min_time</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="kt">long</span><span class="o">&gt;::</span><span class="n">max</span><span class="p">();</span>
<span class="kt">long</span> <span class="n">best_id</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">id</span><span class="o">:</span><span class="n">ids</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">next_factor</span> <span class="o">=</span> <span class="n">first_timestamp</span><span class="o">/</span><span class="n">id</span> <span class="o">+</span> <span class="p">(</span><span class="n">first_timestamp</span><span class="o">%</span><span class="n">id</span><span class="o">!=</span><span class="mi">0</span><span class="p">);</span>
	<span class="k">auto</span> <span class="n">ts</span> <span class="o">=</span> <span class="n">next_factor</span> <span class="o">*</span> <span class="n">id</span><span class="p">;</span>
	
	<span class="k">if</span><span class="p">(</span><span class="n">ts</span><span class="o">&lt;</span><span class="n">min_time</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">best_id</span> <span class="o">=</span> <span class="n">id</span><span class="p">;</span>
		<span class="n">min_time</span> <span class="o">=</span> <span class="n">ts</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<h3 id="part-2-12">Part 2</h3>

<p>It really pays off to know a tiny bit of linear algebra from time to time ;-) Without it, this one would be really, really hard.</p>

<p>Given not only the periods, but a desired offset for each id, we had to determine the first time satisfying for which each bus arrived exactly its offset later. In other words, we had to solve a series of equations of the form</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>x = -a mod id0
x = -b mod id1
x = -c mod id2...
</code></pre></div></div>

<p>That is a case for the <a href="https://en.wikipedia.org/wiki/Chinese_remainder_theorem">famous Chinese remainder theorem</a>!</p>

<p>As such, we first need a way to compute <a href="https://en.wikipedia.org/wiki/Modular_multiplicative_inverse">modular multiplicative inverses</a>, which can be done with <a href="https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm">the extended euclidean algorithm</a>:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">auto</span> <span class="nf">multiplicative_inverse</span><span class="p">(</span><span class="kt">long</span> <span class="kt">long</span> <span class="n">a</span><span class="p">,</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">old_r</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
	<span class="k">auto</span> <span class="n">r</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span>
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">old_s</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">s</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">r</span><span class="o">!=</span><span class="mi">0</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">auto</span> <span class="n">quotient</span> <span class="o">=</span> <span class="n">old_r</span><span class="o">/</span><span class="n">r</span><span class="p">;</span>
		
		<span class="k">auto</span> <span class="n">new_r</span> <span class="o">=</span> <span class="n">old_r</span><span class="o">-</span><span class="n">quotient</span><span class="o">*</span><span class="n">r</span><span class="p">;</span>
		<span class="k">auto</span> <span class="n">new_s</span> <span class="o">=</span> <span class="n">old_s</span><span class="o">-</span><span class="n">quotient</span><span class="o">*</span><span class="n">s</span><span class="p">;</span>
		
		<span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">old_r</span><span class="p">,</span><span class="n">r</span><span class="p">)</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="n">new_r</span><span class="p">);</span>
		<span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">old_s</span><span class="p">,</span><span class="n">s</span><span class="p">)</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">tie</span><span class="p">(</span><span class="n">s</span><span class="p">,</span><span class="n">new_s</span><span class="p">);</span>
	<span class="p">}</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">old_s</span><span class="o">&lt;</span><span class="mi">0</span><span class="p">)</span>
		<span class="n">old_s</span><span class="o">+=</span><span class="n">b</span><span class="p">;</span>
		
	<span class="k">return</span> <span class="n">old_s</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>For each id, we compute the modular inverse of it with the product of all others and multiply it with that product and the desired offset. Our result is the sum of doing that for each id, modulo the product of all ids. Unfortunately, the offsets are negative in our case and modulo with negative numbers is - ummm - <a href="https://stackoverflow.com/questions/7594508/modulo-operator-with-negative-values">let’s say <em>special</em></a> in C++, so I used an expensive loop instead:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">long</span> <span class="kt">long</span> <span class="n">result</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">id</span><span class="o">:</span><span class="n">ids</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">mod</span> <span class="o">=</span> <span class="n">mod_product</span><span class="o">/</span><span class="n">id</span><span class="p">.</span><span class="n">mod</span><span class="p">;</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">inverse</span> <span class="o">=</span> <span class="n">multiplicative_inverse</span><span class="p">(</span><span class="n">mod</span><span class="p">,</span><span class="n">id</span><span class="p">.</span><span class="n">mod</span><span class="p">);</span>
	
	<span class="k">auto</span> <span class="n">off</span> <span class="o">=</span> <span class="o">-</span><span class="n">id</span><span class="p">.</span><span class="n">offset</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">off</span><span class="o">&lt;</span><span class="mi">0</span><span class="p">)</span> <span class="n">off</span><span class="o">+=</span><span class="n">id</span><span class="p">.</span><span class="n">mod</span><span class="p">;</span>

	<span class="n">result</span><span class="o">+=</span><span class="n">off</span><span class="o">*</span><span class="n">mod</span><span class="o">*</span><span class="n">inverse</span><span class="p">;</span>
	<span class="n">result</span><span class="o">%=</span><span class="n">mod_product</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<h2 id="day-14"><a href="https://github.com/philipplenk/adventofcode20/tree/main/14">Day 14</a></h2>

<h3 id="part-1-13">Part 1</h3>

<p>This time, we were supposed to trace modified writes to a special memory. Whenever a value is written, it is first modified based on a simple bitmap by either setting the bits to 0 or 1 or alternatively, leaving them as they were in case of an X. For example, given the following input:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
mem[8] = 11
</code></pre></div></div>

<p>memory at address 8 should obtain the value 1011 (i.e. binary 11), but adding a 1 bit at the 7th position and changing the 1 at the second one to a zero: 1001001 (which is 73 in decimal).</p>

<p>My implementation simply constructed two masks, one to &amp;(representing the X’s) and one to |(representing everything else), for those operations:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">update_mask</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">new_mask</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">mask_and</span> <span class="o">=</span> <span class="n">mask_or</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">shift</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">new_mask</span><span class="p">.</span><span class="n">rbegin</span><span class="p">();</span><span class="n">it</span><span class="o">!=</span><span class="n">new_mask</span><span class="p">.</span><span class="n">rend</span><span class="p">();</span><span class="o">++</span><span class="n">it</span><span class="p">,</span> <span class="o">++</span><span class="n">shift</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">mask_and</span> <span class="o">|=</span> <span class="p">(</span><span class="o">*</span><span class="n">it</span><span class="o">==</span><span class="sc">'X'</span><span class="o">?</span><span class="mi">1ll</span><span class="o">:</span><span class="mi">0ll</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">shift</span><span class="p">;</span>
		<span class="n">mask_or</span> <span class="o">|=</span> <span class="p">(</span><span class="o">*</span><span class="n">it</span><span class="o">==</span><span class="sc">'1'</span><span class="o">?</span><span class="mi">1ll</span><span class="o">:</span><span class="mi">0ll</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">shift</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">};</span></code></pre>
</figure>

<p>Which were then applied to modify assignments:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>memory[addr] = (value&amp;mask_and) | mask_or;	
</code></pre></div></div>

<p>As the address range was 36 bits and as such incredibly huge, whilst only a small number of cells could actually be used, I chose to represent it as a hashmap:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp">	<span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span><span class="o">&gt;</span> <span class="n">memory</span><span class="p">;</span></code></pre>
</figure>

<h3 id="part-2-13">Part 2</h3>

<p>Same input, same mask, but very different interpretation. Now an X does not mean the given value, but any possible one, meaning we will have to iterate over all combinations. Furthermore, 0 means to leave the input untouched(the role previously occupied by X), whilst we modify the address written to, not the value. As a first step, we now create 3 masks(one to set to 1, one to leave untouched and one to try all combinations on):</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">update_mask</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">new_mask</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">mask_and</span> <span class="o">=</span> <span class="n">mask_or</span> <span class="o">=</span> <span class="n">mask_float</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">shift</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">new_mask</span><span class="p">.</span><span class="n">rbegin</span><span class="p">();</span><span class="n">it</span><span class="o">!=</span><span class="n">new_mask</span><span class="p">.</span><span class="n">rend</span><span class="p">();</span><span class="o">++</span><span class="n">it</span><span class="p">,</span> <span class="o">++</span><span class="n">shift</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">mask_and</span> <span class="o">|=</span> <span class="p">(</span><span class="o">*</span><span class="n">it</span><span class="o">==</span><span class="sc">'X'</span><span class="o">?</span><span class="mi">0ull</span><span class="o">:</span><span class="mi">1ull</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">shift</span><span class="p">;</span>
		<span class="n">mask_or</span> <span class="o">|=</span> <span class="p">(</span><span class="o">*</span><span class="n">it</span><span class="o">==</span><span class="sc">'1'</span><span class="o">?</span><span class="mi">1ull</span><span class="o">:</span><span class="mi">0ull</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">shift</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="n">mask_float</span> <span class="o">=</span> <span class="p">(</span><span class="o">~</span><span class="n">mask_and</span><span class="p">)</span><span class="o">&amp;</span><span class="p">((</span><span class="mi">1ull</span><span class="o">&lt;&lt;</span><span class="mi">36</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
<span class="p">};</span></code></pre>
</figure>

<p>Listing all options might seem complicated at first, but luckily for us, our languages and computers already have a beautiful system to iterate over all combinations of 0 and 1 for a given number of those strung together: counting! So we do just that and simply shift the relevant bits into their desired places afterwards:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">foreach_address</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">addr</span><span class="p">,</span> <span class="k">auto</span> <span class="n">fun</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">addr</span> <span class="o">=</span> <span class="p">(</span><span class="n">addr</span><span class="o">&amp;</span><span class="n">mask_and</span><span class="p">)</span> <span class="o">|</span> <span class="n">mask_or</span><span class="p">;</span>
	
	<span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">set_bits</span> <span class="o">=</span> <span class="n">ptl</span><span class="o">::</span><span class="n">popcount</span><span class="p">(</span><span class="n">mask_float</span><span class="p">);</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">uint64_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="p">(</span><span class="mi">1ull</span><span class="o">&lt;&lt;</span><span class="n">set_bits</span><span class="p">);</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">auto</span> <span class="n">addr_cpy</span> <span class="o">=</span> <span class="n">addr</span><span class="p">;</span>
		<span class="k">auto</span> <span class="n">mask_cpy</span> <span class="o">=</span> <span class="n">mask_float</span><span class="p">;</span>
		<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">set_bits</span><span class="p">;</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">const</span> <span class="k">auto</span> <span class="n">bitpos</span> <span class="o">=</span> <span class="n">ptl</span><span class="o">::</span><span class="n">countr_zero</span><span class="p">(</span><span class="n">mask_cpy</span><span class="p">);</span>
			<span class="n">mask_cpy</span><span class="o">&amp;=~</span><span class="p">(</span><span class="mi">1ull</span><span class="o">&lt;&lt;</span><span class="n">bitpos</span><span class="p">);</span>
			<span class="n">addr_cpy</span><span class="o">|=</span><span class="p">((</span><span class="n">i</span><span class="o">&gt;&gt;</span><span class="n">j</span><span class="p">)</span><span class="o">&amp;</span><span class="mi">1ull</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">bitpos</span><span class="p">;</span>
		<span class="p">}</span>
		
		<span class="n">fun</span><span class="p">(</span><span class="n">addr_cpy</span><span class="p">);</span>
	<span class="p">}</span>
<span class="p">};</span></code></pre>
</figure>

<p>To count bits and determine bit positions, I would have loved to use standard functions, but the <a href="https://en.cppreference.com/w/cpp/header/bit">bit header</a> is only available from C++20 onwards and I was using C++17 only here. As such, I substituted my own inferior version created for <a href="https://github.com/philipplenk/paulchen332">my chess engine, paulchen332</a>.</p>

<h2 id="day-15"><a href="https://github.com/philipplenk/adventofcode20/tree/main/15">Day 15</a></h2>

<h3 id="part-1-14">Part 1</h3>

<p>Let’s play a number game. We start of by reading a bunch of given numbers and remembering the previous two times they were said. Now, after they were read once, the next number depends on the previous one. If it was spoken for the first time, we speak 0. Otherwise, we speak the difference between the last two times it was spoken. That is all. Our task was to determine the 2020th number spoken. Rather cryptic instructions to read and it took me a few minutes to comprehend what was asked of us, but once that fog had cleared, a solution is rather trivial. First define what we have to remember for each spoken number and a hashmap storing this piece of information:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">diff</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">prev</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">last</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">};</span>
<span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="n">diff</span><span class="o">&gt;</span> <span class="n">last_spoken</span><span class="p">;</span></code></pre>
</figure>

<p>And then simply simulate the process exactly as given:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">int</span> <span class="n">last</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="mi">2020</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">i</span><span class="o">&lt;</span><span class="n">numbers</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
	<span class="p">{</span>
		<span class="n">last</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
		<span class="n">last_spoken</span><span class="p">[</span><span class="n">numbers</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{</span><span class="n">i</span><span class="p">,</span><span class="n">i</span><span class="p">};</span>
	<span class="p">}</span>
	<span class="k">else</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">data</span> <span class="o">=</span> <span class="n">last_spoken</span><span class="p">[</span><span class="n">last</span><span class="p">];</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">dist</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">last</span><span class="o">-</span><span class="n">data</span><span class="p">.</span><span class="n">prev</span><span class="p">;</span>
		<span class="n">last</span> <span class="o">=</span> <span class="n">dist</span><span class="p">;</span>
		
		<span class="k">if</span><span class="p">(</span><span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">last_spoken</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">dist</span><span class="p">);</span> <span class="n">it</span><span class="o">==</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">last_spoken</span><span class="p">))</span>
		<span class="p">{</span>
			<span class="k">auto</span><span class="o">&amp;</span> <span class="n">to_change_data</span> <span class="o">=</span> <span class="n">last_spoken</span><span class="p">[</span><span class="n">dist</span><span class="p">];</span>
			
			<span class="n">to_change_data</span><span class="p">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
			<span class="n">to_change_data</span><span class="p">.</span><span class="n">last</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="k">else</span>
		<span class="p">{</span>
			<span class="k">auto</span><span class="o">&amp;</span> <span class="n">to_change_data</span> <span class="o">=</span> <span class="n">last_spoken</span><span class="p">[</span><span class="n">dist</span><span class="p">];</span>
			
			<span class="n">to_change_data</span><span class="p">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">to_change_data</span><span class="p">.</span><span class="n">last</span><span class="p">;</span>
			<span class="n">to_change_data</span><span class="p">.</span><span class="n">last</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<h3 id="part-2-14">Part 2</h3>

<p>Nothing changed, we are just asked for a significantly higher number of turns. Seems difficult at first, but I took the lucky shot and tested if my previous solution worked fast enough and it turns out it completed within 8 seconds with a correct result, jumping in leaderboard position from 1700-ish to 500-ish(far from global again, of course). Nonetheless, I was certain we can do better here.</p>

<p>The first trick I could think of, as it appeared occasionally in problems of this kind, is detecting cycles, so I tried this and it turns out, at least for my numbers and my bound, there was no cycle ;_; So we had to get smarter than that… aaand after far too much time spent on my own attempts I began to google and figured out that:</p>

<ol>
  <li>Given the right starting conditions it is actually a named sequence with an entry in the <a href="https://oeis.org/A181391">OEOIS</a></li>
  <li>There is a <a href="https://www.youtube.com/watch?v=etMJxB-igrc">numberphile video about it</a>, which I highly recommend watching. And - of course:</li>
  <li>There is no known way to get at the entries faster than brute force. So anything that is asymptotically better than what I wrote for part 1 would be a minor mathematical breakthrough ;-)</li>
</ol>

<p>As such, all I could do was optimize what I was already doing. The first and most obvious choice is cutting down on unnecessary allocations, by preallocating enough elements into my hashmap:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">last_spoken</span><span class="p">.</span><span class="n">reserve</span><span class="p">(</span><span class="mi">30000000</span><span class="p">);</span></code></pre>
</figure>

<p>This cut the runtime down to 5 seconds, which is quite a decent improvement for one line. Switching from a hashmap to a simple vector of 30000000 elements brought another similar improvement, getting the time down to just 2 seconds, switching the type saved from a wasteful std::size_t to int reduced it to 1.5 seconds. In the process, I also made my code look significantly more compact and beautiful than the horrid mess I showed you for part 1:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(;</span><span class="n">i</span><span class="o">&lt;</span><span class="mi">30000000</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">data</span> <span class="o">=</span> <span class="n">last_spoken</span><span class="p">[</span><span class="n">last</span><span class="p">];</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">dist</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">last</span><span class="o">-</span><span class="n">data</span><span class="p">.</span><span class="n">prev</span><span class="p">;</span>
	<span class="n">last</span> <span class="o">=</span> <span class="n">dist</span><span class="p">;</span>
	
	<span class="k">auto</span><span class="o">&amp;</span> <span class="n">to_change_data</span> <span class="o">=</span> <span class="n">last_spoken</span><span class="p">[</span><span class="n">dist</span><span class="p">];</span>
		
	<span class="n">to_change_data</span><span class="p">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">to_change_data</span><span class="p">.</span><span class="n">seen</span><span class="o">?</span><span class="n">to_change_data</span><span class="p">.</span><span class="n">last</span><span class="o">:</span><span class="n">i</span><span class="p">;</span>
	<span class="n">to_change_data</span><span class="p">.</span><span class="n">last</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
	<span class="n">to_change_data</span><span class="p">.</span><span class="n">seen</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Hacking around a tiny bit more to get a more compact memory layout by stealing a bit from “last” instead of having a separate variable for “seen” got the time down to about 1 second, at which point I stopped bothering.</p>

<h2 id="day-16"><a href="https://github.com/philipplenk/adventofcode20/tree/main/16">Day 16</a></h2>

<h3 id="part-1-15">Part 1</h3>

<p>More data validation, yeahy! *sigh*</p>

<p>We have a bunch of tickets with a number of fields, all identified in a language we do not understand. Luckily for us, we also know which fields have to follow which rules, so we might have a shot at ordering them. But first, let’s make sure our data is valid by identifying fields that cannot be valid for any rule and count them.</p>

<p>Rules are given in the form</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class: 1-3 or 5-7
</code></pre></div></div>

<p>which implies all entries of the “class” type have to be between 1 and 3(inclusive) or 5 and 7. It’s always exactly two non-overlapping ranges and the second always starts after the first. So here is how I represented and parsed the rulesets:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">inclusive_range</span>
<span class="p">{</span>
	<span class="kt">int</span> <span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">struct</span> <span class="nc">rule</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span><span class="p">;</span>
	<span class="n">inclusive_range</span> <span class="n">lower</span><span class="p">,</span> <span class="n">higher</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">in</span><span class="p">,</span> <span class="n">rule</span><span class="o">&amp;</span> <span class="n">r</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">r</span><span class="p">.</span><span class="n">name</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
	
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">part</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">part</span> <span class="o">&amp;&amp;</span> <span class="n">part</span><span class="p">.</span><span class="n">back</span><span class="p">()</span><span class="o">!=</span><span class="sc">':'</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">r</span><span class="p">.</span><span class="n">name</span><span class="o">+=</span><span class="n">part</span><span class="o">+</span><span class="sc">' '</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="n">r</span><span class="p">.</span><span class="n">name</span><span class="o">+=</span><span class="n">part</span><span class="p">;</span>
	<span class="n">r</span><span class="p">.</span><span class="n">name</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
	
	<span class="kt">char</span> <span class="n">skip_c</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">r</span><span class="p">.</span><span class="n">lower</span><span class="p">.</span><span class="n">start</span><span class="o">&gt;&gt;</span><span class="n">skip_c</span><span class="o">&gt;&gt;</span><span class="n">r</span><span class="p">.</span><span class="n">lower</span><span class="p">.</span><span class="n">end</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">part</span><span class="p">;</span>
	<span class="n">in</span><span class="o">&gt;&gt;</span><span class="n">r</span><span class="p">.</span><span class="n">higher</span><span class="p">.</span><span class="n">start</span><span class="o">&gt;&gt;</span><span class="n">skip_c</span><span class="o">&gt;&gt;</span><span class="n">r</span><span class="p">.</span><span class="n">higher</span><span class="p">.</span><span class="n">end</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">in</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>With the parsing out of the way, as not exactly infrequently, the real task is just a form of counting:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">error_rate</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">accumulate</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">tickets</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">tickets</span><span class="p">),</span><span class="mi">0</span><span class="p">,[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span> <span class="n">total</span><span class="p">,</span> <span class="k">const</span> <span class="k">auto</span> <span class="n">t</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="kt">int</span> <span class="n">sum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">e</span><span class="o">:</span><span class="n">t</span><span class="p">.</span><span class="n">entries</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="kt">bool</span> <span class="n">valid</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
			<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">r</span><span class="o">:</span><span class="n">rules</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="k">if</span><span class="p">(</span><span class="n">e</span><span class="o">&gt;=</span><span class="n">r</span><span class="p">.</span><span class="n">lower</span><span class="p">.</span><span class="n">start</span> <span class="o">&amp;&amp;</span> <span class="n">e</span><span class="o">&lt;=</span><span class="n">r</span><span class="p">.</span><span class="n">lower</span><span class="p">.</span><span class="n">end</span><span class="p">)</span>
					<span class="n">valid</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
					
				<span class="k">if</span><span class="p">(</span><span class="n">e</span><span class="o">&gt;=</span><span class="n">r</span><span class="p">.</span><span class="n">higher</span><span class="p">.</span><span class="n">start</span> <span class="o">&amp;&amp;</span> <span class="n">e</span><span class="o">&lt;=</span><span class="n">r</span><span class="p">.</span><span class="n">higher</span><span class="p">.</span><span class="n">end</span><span class="p">)</span>
					<span class="n">valid</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
			<span class="p">}</span>
			<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">valid</span><span class="p">)</span>
				<span class="n">sum</span><span class="o">+=</span><span class="n">e</span><span class="p">;</span>
		<span class="p">}</span>
		
		<span class="k">return</span> <span class="n">total</span> <span class="o">+</span> <span class="n">sum</span><span class="p">;</span>
	<span class="p">});</span></code></pre>
</figure>

<h3 id="part-2-15">Part 2</h3>

<p>Alright, now we get to the ever so slightly more interesting part: Identifying which column belongs to which field. The simplest way to do this is checking all options. The somewhat more clever one I could think of is to determine the first rule by finding one that can only be valid for one column. Afterwards, rinse and repeat:</p>

<p>First, we setup variables to keep track of which rules and fields we have already identified:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;&gt;</span> <span class="n">found_target_entry</span><span class="p">;</span>
<span class="n">found_target_entry</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">rules</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> 

<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;&gt;</span> <span class="n">found_target_rule</span><span class="p">;</span>
<span class="n">found_target_rule</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">rules</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> 

<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">rules_found_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span></code></pre>
</figure>

<p>Determining if one and only one previously unassigned entry fits a given rule is done via this lovely lambda:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">determine_unique_entry_for</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">int</span> <span class="n">rule_id</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span> <span class="n">entry_n</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">j</span><span class="o">&lt;</span><span class="n">tickets</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">entries</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">j</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">found_target_rule</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
			<span class="k">continue</span><span class="p">;</span>
				
		<span class="k">const</span> <span class="k">auto</span> <span class="n">valid</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">all_of</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">tickets</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">tickets</span><span class="p">),[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">t</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">return</span> <span class="n">is_valid</span><span class="p">(</span><span class="n">t</span><span class="p">.</span><span class="n">entries</span><span class="p">[</span><span class="n">j</span><span class="p">],</span><span class="n">rules</span><span class="p">[</span><span class="n">rule_id</span><span class="p">]);</span>
		<span class="p">});</span>
				
		<span class="k">if</span><span class="p">(</span><span class="n">valid</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">if</span><span class="p">(</span><span class="n">entry_n</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="n">entry_n</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">nullopt</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="p">}</span>
			<span class="k">else</span>
				<span class="n">entry_n</span> <span class="o">=</span> <span class="n">j</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
	
	<span class="k">return</span> <span class="n">entry_n</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>It checks all, skipping over all assigned ones and checks validity. If no option or more than one valid option is found, we return nullopt, otherwise we return the index.</p>

<p>We then repeat it for all rules until everything becomes clear:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">while</span><span class="p">(</span><span class="n">rules_found_count</span><span class="o">&lt;</span><span class="n">rules</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">rules</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">found_target_entry</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
		<span class="p">{</span>
			<span class="k">if</span><span class="p">(</span><span class="k">auto</span> <span class="n">entry_n</span> <span class="o">=</span> <span class="n">determine_unique_entry_for</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="n">entry_n</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="n">found_target_entry</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">*</span><span class="n">entry_n</span><span class="p">;</span>
				<span class="n">found_target_rule</span><span class="p">[</span><span class="o">*</span><span class="n">entry_n</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
				<span class="o">++</span><span class="n">rules_found_count</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="p">}</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>And that’s it for the day. It would - of course - fail spectacularly if more than one valid solution exited ;-)</p>

<p>Whilst I am not generally too big a fan of the validation type puzzles - as they really mostly test if you are capable of correctly reading instructions and data - the second part today was amazing and a lot of fun!</p>

<h2 id="day-17"><a href="https://github.com/philipplenk/adventofcode20/tree/main/17">Day 17</a></h2>

<h3 id="part-1-16">Part 1</h3>

<p>We already had one <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Game of Life</a> type puzzle this year, so seeing this one did not excite me too much at first. But in this tragic year it seemed needed and - reiterating the idea of <a href="https://en.wikipedia.org/wiki/Spiral_approach">spiraling</a> - this one did take the previous one up to 11. Or rather 3 and eventually 4.</p>

<p>We start of with an infinite 3 dimensional “Conway Cube” with only one slight slice initialized and are supposed to extrapolate its growth.</p>

<p>For this first task, I chose the probably worst possible representation of an expanding, very sparsely packed three dimensional grid possible: a vector of vector of string.</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">using</span> <span class="n">layer</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">layer</span><span class="o">&gt;</span> <span class="n">grid3d</span><span class="p">;</span></code></pre>
</figure>

<p>Doing it like this made the update step incredibly unwieldy and tedious, as I had to take care to add two layers and resize every layer by 2, whilst keeping track of shifted indices and different bounds for the updated copy:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">update_grid</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">]()</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">layer</span><span class="o">&gt;</span> <span class="n">ret_val</span><span class="p">;</span>
	
	<span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">z</span><span class="o">=-</span><span class="mi">1</span><span class="p">;</span><span class="n">z</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">grid3d</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span><span class="o">++</span><span class="n">z</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">ret_val</span><span class="p">.</span><span class="n">push_back</span><span class="p">({});</span>
		<span class="n">ret_val</span><span class="p">.</span><span class="n">back</span><span class="p">().</span><span class="n">resize</span><span class="p">(</span><span class="n">grid_height</span><span class="o">+</span><span class="mi">2</span><span class="p">);</span>
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">row</span><span class="o">:</span> <span class="n">ret_val</span><span class="p">.</span><span class="n">back</span><span class="p">())</span>
			<span class="n">row</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">grid_width</span><span class="o">+</span><span class="mi">2</span><span class="p">);</span>
		
		<span class="n">foreach_in_square</span><span class="p">({</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">},{</span><span class="n">grid_width</span><span class="p">,</span><span class="n">grid_height</span><span class="p">},[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">auto</span> <span class="n">p2</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">auto</span> <span class="n">p3</span> <span class="o">=</span> <span class="n">point3d</span><span class="p">{</span><span class="n">p2</span><span class="p">.</span><span class="n">x</span><span class="p">,</span><span class="n">p2</span><span class="p">.</span><span class="n">y</span><span class="p">,</span><span class="n">z</span><span class="p">};</span>
			
			<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
			<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">v</span><span class="o">:</span> <span class="n">directions</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="k">if</span><span class="p">(</span><span class="k">auto</span> <span class="n">target</span> <span class="o">=</span> <span class="n">p3</span><span class="o">+</span><span class="n">v</span><span class="p">;</span> <span class="n">valid_in_original</span><span class="p">(</span><span class="n">target</span><span class="p">))</span>					
					<span class="n">count</span> <span class="o">+=</span> <span class="n">grid3d</span><span class="p">[</span><span class="n">target</span><span class="p">.</span><span class="n">z</span><span class="p">][</span><span class="n">target</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">target</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'#'</span><span class="p">;</span>
			<span class="p">}</span>
			 
			<span class="k">if</span><span class="p">(</span><span class="n">valid_in_original</span><span class="p">(</span><span class="n">p3</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="n">grid3d</span><span class="p">[</span><span class="n">p3</span><span class="p">.</span><span class="n">z</span><span class="p">][</span><span class="n">p3</span><span class="p">.</span><span class="n">y</span><span class="p">][</span><span class="n">p3</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">==</span><span class="sc">'#'</span><span class="p">)</span>
				<span class="n">ret_val</span><span class="p">.</span><span class="n">back</span><span class="p">()[</span><span class="n">p3</span><span class="p">.</span><span class="n">y</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="n">p3</span><span class="p">.</span><span class="n">x</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">count</span><span class="o">==</span><span class="mi">2</span> <span class="o">||</span> <span class="n">count</span><span class="o">==</span><span class="mi">3</span><span class="p">)</span><span class="o">?</span><span class="sc">'#'</span><span class="o">:</span><span class="sc">'.'</span><span class="p">;</span>
			<span class="k">else</span>
				<span class="n">ret_val</span><span class="p">.</span><span class="n">back</span><span class="p">()[</span><span class="n">p3</span><span class="p">.</span><span class="n">y</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="n">p3</span><span class="p">.</span><span class="n">x</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">count</span><span class="o">==</span><span class="mi">3</span><span class="p">)</span><span class="o">?</span><span class="sc">'#'</span><span class="o">:</span><span class="sc">'.'</span><span class="p">;</span>
		<span class="p">});</span>
	<span class="p">}</span>
	
	<span class="n">grid_width</span><span class="o">+=</span><span class="mi">2</span><span class="p">;</span>
	<span class="n">grid_height</span><span class="o">+=</span><span class="mi">2</span><span class="p">;</span>
	<span class="k">return</span> <span class="n">ret_val</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>Certainly not the best code I have ever written, if you care for your eyes you should avert them.</p>

<h3 id="part-2-16">Part 2</h3>

<p>You thought 3 dimensions was fun? Let’s add another one and consider 4D hypercubes. My first surprisingly working solution simply extended the approach above logically. Instead of a vector of vector of string, I kept a vector of vector of vector of string and proceeded similarly to above, just one more nesting deeper. Quite the abomination, too horrendous to ever share with any living thing. I did, however, eventually see the error of my ways and recognized the problem description clearly screams for generalization of n dimensions, so generalize is what I did.</p>

<p>First of all, I needed arbitrarily dimensional vector and point structs</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">dim</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">vec</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="n">dim</span><span class="o">&gt;</span> <span class="n">coordinate</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">dim</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">point</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="n">dim</span><span class="o">&gt;</span> <span class="n">coordinate</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>with appropriate operator overloads like this:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">dim</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="n">point</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;&amp;</span> <span class="k">operator</span><span class="o">+=</span><span class="p">(</span><span class="n">point</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;&amp;</span> <span class="n">lhs</span><span class="p">,</span> <span class="k">const</span> <span class="n">vec</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;&amp;</span> <span class="n">rhs</span><span class="p">)</span> <span class="k">noexcept</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">dim</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
		<span class="n">lhs</span><span class="p">.</span><span class="n">coordinate</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">+=</span><span class="n">rhs</span><span class="p">.</span><span class="n">coordinate</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
	
	<span class="k">return</span> <span class="n">lhs</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Computing vectors to all neighbors can be done with some simple recursion:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">dim</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">neighbor_vectors</span><span class="p">()</span> <span class="k">noexcept</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">vec</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;</span><span class="p">,</span><span class="n">pow</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="n">dim</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="o">&gt;</span> <span class="n">ret_val</span><span class="p">;</span>
	
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	
	<span class="k">const</span> <span class="k">auto</span> <span class="n">recursive_fill</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="n">vec</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;</span> <span class="n">current</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">coord</span><span class="p">,</span> <span class="k">auto</span> <span class="n">recurse</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">coord</span><span class="o">==</span><span class="n">dim</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">std</span><span class="o">::</span><span class="n">all_of</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">current</span><span class="p">.</span><span class="n">coordinate</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">current</span><span class="p">.</span><span class="n">coordinate</span><span class="p">),[](</span><span class="k">auto</span> <span class="n">v</span><span class="p">){</span> <span class="k">return</span> <span class="n">v</span><span class="o">==</span><span class="mi">0</span><span class="p">;</span> <span class="p">}))</span>
				<span class="n">ret_val</span><span class="p">[</span><span class="n">count</span><span class="o">++</span><span class="p">]</span><span class="o">=</span><span class="n">current</span><span class="p">;</span>
			<span class="k">return</span><span class="p">;</span>
		<span class="p">}</span>
		
		<span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="o">=-</span><span class="mi">1</span><span class="p">;</span><span class="n">v</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span><span class="o">++</span><span class="n">v</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">current</span><span class="p">.</span><span class="n">coordinate</span><span class="p">[</span><span class="n">coord</span><span class="p">]</span><span class="o">=</span><span class="n">v</span><span class="p">;</span>
			<span class="n">recurse</span><span class="p">(</span><span class="n">current</span><span class="p">,</span> <span class="n">coord</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">recurse</span><span class="p">);</span>
		<span class="p">}</span>
	<span class="p">};</span>
	
	<span class="n">recursive_fill</span><span class="p">({},</span><span class="mi">0</span><span class="p">,</span><span class="n">recursive_fill</span><span class="p">);</span>
	
	<span class="k">return</span> <span class="n">ret_val</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Given all that, I needed a better, less wasteful representation of the grid/cube/hypercube/whatever, i.e. of infinite space in arbitrary dimensions. The one I chose was a simple set of active/occupied cells:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">constexpr</span> <span class="k">auto</span> <span class="n">dim</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="n">point</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;&gt;</span> <span class="n">cells</span><span class="p">;</span></code></pre>
</figure>

<p>An unordered_set, i.e. a hashset, might have been more efficient than this tree based one, but I really did not know how to define a good hash function for an arbitrarily large collection of integers, whilst a operator&lt; is very natural.</p>

<p>The update function becomes much better than in part 1, even bearable to look at:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">update_cells</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">]()</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">point</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span> <span class="n">counts</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">p</span><span class="o">:</span> <span class="n">cells</span><span class="p">)</span>
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">n</span><span class="o">:</span> <span class="n">neighbor_vectors</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;</span><span class="p">())</span>
			<span class="o">++</span><span class="n">counts</span><span class="p">[</span><span class="n">p</span><span class="o">+</span><span class="n">n</span><span class="p">];</span>
	
	<span class="n">std</span><span class="o">::</span><span class="n">set</span><span class="o">&lt;</span><span class="n">point</span><span class="o">&lt;</span><span class="n">dim</span><span class="o">&gt;&gt;</span> <span class="n">new_cells</span><span class="p">;</span>
	
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">p</span><span class="p">,</span><span class="n">count</span><span class="p">]</span><span class="o">:</span> <span class="n">counts</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">count</span><span class="o">==</span><span class="mi">3</span> <span class="o">||</span> <span class="p">(</span><span class="n">count</span><span class="o">==</span><span class="mi">2</span> <span class="o">&amp;&amp;</span> <span class="n">cells</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">p</span><span class="p">)</span><span class="o">!=</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">cells</span><span class="p">)))</span>
			<span class="n">new_cells</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
	<span class="p">}</span>

	<span class="k">return</span> <span class="n">new_cells</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>I first iterate over all active/set cells and add one to the neighbor count of each of their neighbors. I then iterate over those counts to create the new active cells according to the rules given. Almost beautiful ;-)</p>

<h2 id="day-18"><a href="https://github.com/philipplenk/adventofcode20/tree/main/18">Day 18</a></h2>

<h3 id="part-1-17">Part 1</h3>

<p>Expression parsing and evaluation! Great thing I have written some very simple toy (and still simple, but not so toy) compilers before :). First thing is simply evaluating with no precedence at all, just considering parenthesis and left to right, which can easily be done in one pass.</p>

<p>First, we define how to parse a single operation:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">operation</span> <span class="nf">parse_operation</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">expression</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">expression</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">ws</span><span class="p">;</span>
	
	<span class="n">operation</span> <span class="n">op</span><span class="p">;</span>
	<span class="k">if</span><span class="p">(</span><span class="n">expression</span><span class="p">.</span><span class="n">peek</span><span class="p">()</span><span class="o">==</span><span class="sc">'*'</span><span class="p">)</span>
		<span class="n">op</span><span class="o">=</span><span class="n">operation</span><span class="o">::</span><span class="n">multiply</span><span class="p">;</span>
	<span class="k">else</span>
		<span class="n">op</span><span class="o">=</span><span class="n">operation</span><span class="o">::</span><span class="n">add</span><span class="p">;</span>

	<span class="n">expression</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
		
	<span class="k">return</span> <span class="n">op</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Skip all whitespace and return operation::add or operation::multiply depending on the character seen(We should only support addition and multiplication). Nothing fancy so far. Parsing an operand, however, already contains most of the logic:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">long</span> <span class="kt">long</span> <span class="nf">parse_operand</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">expression</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">expression</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">ws</span><span class="p">;</span>
	
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">if</span><span class="p">(</span><span class="n">expression</span><span class="p">.</span><span class="n">peek</span><span class="p">()</span><span class="o">==</span><span class="sc">'('</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">expression</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
		<span class="n">value</span> <span class="o">=</span> <span class="n">evaluate</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
	<span class="p">}</span>
	<span class="k">else</span>
		<span class="n">expression</span><span class="o">&gt;&gt;</span><span class="n">value</span><span class="p">;</span>

	<span class="k">return</span> <span class="n">value</span><span class="p">;</span>
<span class="p">}</span>	</code></pre>
</figure>

<p>If the operand is a simple number, we read and return it. Otherwise, we first recursively evaluate the subexpression describing it and then return its result. Evaluation itself can now be described in terms of the two functions above:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">long</span> <span class="kt">long</span> <span class="nf">evaluate</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">expression</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">result</span> <span class="o">=</span> <span class="n">parse_operand</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
	
	<span class="k">do</span>
	<span class="p">{</span>
		<span class="n">operation</span> <span class="n">op</span> <span class="o">=</span> <span class="n">parse_operation</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
		
		<span class="kt">long</span> <span class="kt">long</span> <span class="n">rhs</span> <span class="o">=</span> <span class="n">parse_operand</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
			
		<span class="n">result</span> <span class="o">=</span> <span class="n">op</span><span class="o">==</span><span class="n">operation</span><span class="o">::</span><span class="n">add</span><span class="o">?</span><span class="p">(</span><span class="n">result</span><span class="o">+</span><span class="n">rhs</span><span class="p">)</span><span class="o">:</span><span class="p">(</span><span class="n">result</span><span class="o">*</span><span class="n">rhs</span><span class="p">);</span>

		<span class="n">expression</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">ws</span><span class="p">;</span>
		<span class="k">if</span><span class="p">(</span><span class="n">expression</span><span class="p">.</span><span class="n">peek</span><span class="p">()</span><span class="o">==</span><span class="sc">')'</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">expression</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
	<span class="k">while</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
	
	<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>We first parse the left operand, followed by the operation and its right operand. Our result gets computed as the result of applying the operator to it and the right operand. While there are still more operations to process, we repeat the procedure with result as the new left operand.</p>

<p>Not the most pretty, not the most ugly, just simple enough and it gave the correct result on first try and me place 185th on the damn global leaderboard. So close, yet so far…</p>

<h3 id="part-2-17">Part 2</h3>

<p>Now we do have a precedence, just the opposite of what is commonly used. In hindsight, it might have been worth it to just swap the symbols, let some automatic parenthesizing program run over it, swap them again and use bc or something like it. Or copy the expressions to code and use custom types with overloaded operators. I believe many solutions worked exactly like that, taking advantage of already properly implemented precedence rules in languages and calculators. I, as I tend to do in life, went the long and tedious route:</p>

<p>It wasn’t really that long and tedious so. All that had to be adjusted was the evaluate function and the change was rather minimal and intuitive. Ignore subexpressions for a moment - as those are handled recursively by parse_operand anyway - and simply consider what is happening here:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1+2*3+4+5*6+7*9+8+7
</code></pre></div></div>

<p>That is interpreted as:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(1+2)*(3+4+5)*(6+7)*(9+8+7)
</code></pre></div></div>

<p>As you can see, we have a product of sums. What we can do, as such, is keep a running product, starting with 1 and a running sum, starting with the first operand. We then add to the sum until we encounter a multiply, at which point we multiply our running product by the sum and reset sum to zero.</p>

<p>With our example:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>product = 1, sum = 1;
sum = 3
product = 1*3, sum = 0
sum = 3
sum = 7
sum = 12
product = 3*12, sum = 0
</code></pre></div></div>

<p>and so on. At the very end, we return the running product multiplied by the last sum. Here it is in code:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">long</span> <span class="kt">long</span> <span class="nf">evaluate</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span><span class="o">&amp;</span> <span class="n">expression</span><span class="p">)</span>
<span class="p">{</span>	
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">lhs</span> <span class="o">=</span> <span class="n">parse_operand</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
	
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">product</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	<span class="k">do</span>
	<span class="p">{</span>
		<span class="n">operation</span> <span class="n">op</span> <span class="o">=</span> <span class="n">parse_operation</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
		
		<span class="kt">long</span> <span class="kt">long</span> <span class="n">rhs</span> <span class="o">=</span> <span class="n">parse_operand</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
			
		<span class="k">if</span><span class="p">(</span><span class="n">op</span><span class="o">==</span><span class="n">operation</span><span class="o">::</span><span class="n">multiply</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">product</span><span class="o">*=</span><span class="n">lhs</span><span class="p">;</span>
			<span class="n">lhs</span> <span class="o">=</span> <span class="n">rhs</span><span class="p">;</span>
		<span class="p">}</span>
		<span class="k">else</span>
			<span class="n">lhs</span><span class="o">+=</span><span class="n">rhs</span><span class="p">;</span>
			
		<span class="n">expression</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">ws</span><span class="p">;</span>
		<span class="k">if</span><span class="p">(</span><span class="n">expression</span><span class="p">.</span><span class="n">peek</span><span class="p">()</span><span class="o">==</span><span class="sc">')'</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">expression</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
	<span class="k">while</span><span class="p">(</span><span class="n">expression</span><span class="p">);</span>
	
	<span class="k">return</span> <span class="n">product</span><span class="o">*</span><span class="n">lhs</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<h2 id="day-19"><a href="https://github.com/philipplenk/adventofcode20/tree/main/19">Day 19</a></h2>

<h3 id="part-1-18">Part 1</h3>

<p>More parsing fun, but this time the difficulty is not so much in parsing but in writing a proper parser. We are given a bunch of simple replacement rules and are supposed to tell how many of the input strings match the rules. At first, they are non-recursive and provided in a simple form:</p>

<p>0: 1 2
1: “a”
2: 1 3 | 3 1
3: “b”</p>

<p>This is basically a very simple <a href="https://en.wikipedia.org/wiki/Formal_grammar">grammar</a>, with numbers as nonterminals and characters as terminals. I chose to represent the production rules as a simple struct:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">enum</span> <span class="k">class</span> <span class="nc">type</span>
<span class="p">{</span>
	<span class="n">terminal</span><span class="p">,</span>
	<span class="n">nonterminal</span>
<span class="p">};</span>

<span class="k">struct</span> <span class="nc">rule</span>
<span class="p">{</span>
	<span class="n">type</span> <span class="n">t</span><span class="p">;</span>
	<span class="kt">char</span> <span class="n">c</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">long</span><span class="o">&gt;&gt;</span> <span class="n">sequences</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>If type is terminal, the char matters, otherwise the vector of alternative sequences is relevant. Given that exclusivity, I would have done better to use a <a href="https://en.cppreference.com/w/cpp/utility/variant">std::variant</a> instead, but I guess I was feeling particularly lazy that day.</p>

<p>The parser itself is, as so frequently, a simple recursive function with this signature:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="n">std</span><span class="o">::</span><span class="n">string_view</span> <span class="n">str</span><span class="p">,</span> <span class="kt">long</span> <span class="n">rule_id</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">deque</span><span class="o">&lt;</span><span class="kt">long</span><span class="o">&gt;</span> <span class="n">follow</span><span class="p">,</span> <span class="k">auto</span> <span class="n">recurse</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">bool</span></code></pre>
</figure>

<p>“str” is what remains of the input, “rule_id” identifies the first rule we are trying to match, whilst “follow” is a list of rules we have to match after that first one.</p>

<p>Matching differentiates based on the next rule type. If it is a terminal, i.e. a single character, we simply compare the next input character:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">str</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">str</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">==</span><span class="n">r</span><span class="p">.</span><span class="n">c</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">str</span><span class="p">.</span><span class="n">remove_prefix</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
	<span class="k">if</span><span class="p">(</span><span class="n">follow</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
		<span class="k">return</span> <span class="n">str</span><span class="p">.</span><span class="n">empty</span><span class="p">();</span>
			
	<span class="k">auto</span> <span class="n">next</span> <span class="o">=</span> <span class="n">follow</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
	<span class="n">follow</span><span class="p">.</span><span class="n">pop_front</span><span class="p">();</span>
	<span class="k">return</span> <span class="n">recurse</span><span class="p">(</span><span class="n">str</span><span class="p">,</span><span class="n">next</span><span class="p">,</span><span class="n">follow</span><span class="p">,</span><span class="n">recurse</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span>
	<span class="k">return</span> <span class="nb">false</span><span class="p">;</span></code></pre>
</figure>

<p>If it does not match, we failed. If it succeeded and we have no more rules to match, we succeed exactly if we consumed all of our input. Otherwise, we recursively try to match the next rule in our sequence.</p>

<p>If, on the contrary, we are dealing with a nonterminal, matching is a little more complicated, as we have to try all options:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">seq</span><span class="o">:</span> <span class="n">r</span><span class="p">.</span><span class="n">sequences</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">follow_cpy</span> <span class="o">=</span> <span class="n">follow</span><span class="p">;</span>
	<span class="n">follow_cpy</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">follow_cpy</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">seq</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">seq</span><span class="p">));</span>
	<span class="k">auto</span> <span class="n">next</span> <span class="o">=</span> <span class="n">follow_cpy</span><span class="p">.</span><span class="n">front</span><span class="p">();</span>
	<span class="n">follow_cpy</span><span class="p">.</span><span class="n">pop_front</span><span class="p">();</span>
	<span class="k">if</span><span class="p">(</span><span class="n">recurse</span><span class="p">(</span><span class="n">str</span><span class="p">,</span><span class="n">next</span><span class="p">,</span><span class="n">follow_cpy</span><span class="p">,</span><span class="n">recurse</span><span class="p">))</span>
		<span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>
	
<span class="k">return</span> <span class="nb">false</span><span class="p">;</span></code></pre>
</figure>

<p>For each of our possible sequences, we first create a copy of what has to follow so far and prepend that with the sequence we are currently testing. Then we proceed as we did in the terminal case above, by taking off the first of that sequence and recursing. If any one of the recursive calls succeeded, we propagate success. Otherwise, we propagate failure.</p>

<h3 id="part-2-18">Part 2</h3>

<p>For part 2, we were supposed to replace two rules, thereby introducing right recursion. We were warned - in not too weak terms - that we should only try to handle our special case and a general solution would be significantly more difficult. I was stumped for several minutes trying to figure out what such a special cased solution would look like, until I decided to try and see what my solution would do with the modified input. Turns out it seems to have been perfectly general already and spewed out the correct answer within the fraction of a second. Wasted minutes and leaderboard opportunities… Oh well, next year is another chance xD</p>

<h2 id="day-20"><a href="https://github.com/philipplenk/adventofcode20/tree/main/20">Day 20</a></h2>

<h3 id="part-1-19">Part 1</h3>

<p>This one was quite interesting. A puzzle that was literally… a puzzle ;-). Given a bunch of “tiles”, i.e. small rectangles of either “.” or “#”, the task was to reassemble a complete image by placing, rotating and flipping the tiles such that all borders match up. Part 1, however, was a significantly easier first step to this grand endeavor: Determining which tiles are corner tiles. A tiny bit of thought reveals that all tiles appearing on the inside match at least 3 other tiles on at least 3 of their borders. As such, we first need to determine the 4 borders:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">get_borders</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">grid</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="n">borders</span><span class="p">;</span>
	<span class="n">borders</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="n">grid</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
	<span class="n">borders</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">grid</span><span class="p">.</span><span class="n">back</span><span class="p">();</span>
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">line</span><span class="o">:</span> <span class="n">grid</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">borders</span><span class="p">[</span><span class="mi">2</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
		<span class="n">borders</span><span class="p">[</span><span class="mi">3</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">line</span><span class="p">.</span><span class="n">back</span><span class="p">());</span>
	<span class="p">}</span>
	<span class="k">return</span> <span class="n">borders</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>“grid” here is a vector of string, the unfortunately inefficient representation I chose at the time. For this part, it was entirely unnecessary to save more than the borders and those could have been a simple bitset/integer instead. Nonetheless, due to an irresistible bout of laziness and in anticipation of what was to come, for better or worse, I did as I did.</p>

<p>Given a way to get at the borders for any given tile, we need a way to check if any borders of two tiles could match, regardless of orientation:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">match_sides</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">grid_lhs</span><span class="p">,</span> <span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">grid_rhs</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">lhs_borders</span> <span class="o">=</span> <span class="n">get_borders</span><span class="p">(</span><span class="n">grid_lhs</span><span class="p">);</span>
	<span class="k">auto</span> <span class="n">rhs_borders</span> <span class="o">=</span> <span class="n">get_borders</span><span class="p">(</span><span class="n">grid_rhs</span><span class="p">);</span>
	
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">lhs</span><span class="o">:</span> <span class="n">lhs_borders</span><span class="p">)</span>
		<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">rhs</span><span class="o">:</span> <span class="n">rhs_borders</span><span class="p">)</span>
			<span class="k">if</span><span class="p">(</span><span class="n">lhs</span><span class="o">==</span><span class="n">rhs</span><span class="p">)</span>
				<span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
				
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="n">rhs</span><span class="o">:</span> <span class="n">rhs_borders</span><span class="p">)</span>
		<span class="n">std</span><span class="o">::</span><span class="n">reverse</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">rhs</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">rhs</span><span class="p">));</span>
	
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">lhs</span><span class="o">:</span> <span class="n">lhs_borders</span><span class="p">)</span>
		<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">rhs</span><span class="o">:</span> <span class="n">rhs_borders</span><span class="p">)</span>
			<span class="k">if</span><span class="p">(</span><span class="n">lhs</span><span class="o">==</span><span class="n">rhs</span><span class="p">)</span>
				<span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
				
	<span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>We then can, in horrendously quadratic brute force fashion, determine all possible neighbors for all tiles:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">tiles</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span> <span class="n">it</span><span class="o">!=</span><span class="n">tiles</span><span class="p">.</span><span class="n">end</span><span class="p">();</span><span class="o">++</span><span class="n">it</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">other_it</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">next</span><span class="p">(</span><span class="n">it</span><span class="p">);</span> <span class="n">other_it</span><span class="o">!=</span><span class="n">tiles</span><span class="p">.</span><span class="n">end</span><span class="p">();</span><span class="o">++</span><span class="n">other_it</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">match_sides</span><span class="p">(</span><span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">,</span><span class="n">other_it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">))</span>
		<span class="p">{</span>
			<span class="n">neighbors</span><span class="p">[</span><span class="n">it</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">other_it</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">);</span>
			<span class="n">neighbors</span><span class="p">[</span><span class="n">other_it</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">it</span><span class="o">-&gt;</span><span class="n">first</span><span class="p">);</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>The looked for tiles are those with exactly 2 possible neighbors and we were supposed to return the product of their ids:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">long</span> <span class="n">product</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">id</span><span class="p">,</span><span class="n">neighbors</span><span class="p">]</span><span class="o">:</span> <span class="n">neighbors</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">neighbors</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span>
		<span class="n">product</span><span class="o">*=</span><span class="n">id</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="n">product</span><span class="o">&lt;&lt;</span><span class="sc">'\n'</span><span class="p">;</span></code></pre>
</figure>

<p>All of this could, of course, have failed miserably, as there is no real reason why a corner tile could not match any additional tiles on at least one side, but it seems like we were supposed to get lucky.</p>

<h3 id="part-2-19">Part 2</h3>

<p>Alright, now that we have the corners, solving the complete puzzle and reassembling our image should be trivial, right? Well, it should be…</p>

<p>I did, however, run into some troubles along the way, wrapping my head around it was the cause of some minor and major headaches and I spent far more time than I’d be willing to admit until I got all the details just right. My code is a bit of mess, so before we get to it, allow me to explain in general terms what I eventually came up with:</p>

<p>Assume we start out with an empty grid</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>....
....
....
....
</code></pre></div></div>

<p>Begin by setting any arbitrary corner tile:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0...
....
....
....
</code></pre></div></div>

<p>As corner has exactly 2 neighbors and we do not care if our assembled image is in the “correct” orientation - whatever that even means - we can randomly assign one of them to the right and the other to the bottom:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>01..
2...
....
....
</code></pre></div></div>

<p>What now? Consider the position marked “X”:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>01..
2X..
....
....
</code></pre></div></div>

<p>What do we know about the tile which will eventually end up there? It has 4 neighbors, two of which will be 1 and 2. It is also the only tile adjacent to both of them! Two placed neighbors are always enough to uniquely identify any tiles position. As such, we can place all tiles with that property:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>01..
23..
....
....
</code></pre></div></div>

<p>Aaaand, we are stuck again. Or are we? 1 and 2 have exactly one unplaced neighbor left and exactly one space to put it. As such, we can place those, leaving us with:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>014.
23..
5...
....
</code></pre></div></div>

<p>Which provides us with two more positions clearly defined by two neighbors. Filling them gives us two more tiles on the edges. Rinse and repeat until the grid is filled.</p>

<p>Which brings us to the god awful implementation. We first do exactly what we did in part 1, just instead of outputting some value based on the corner ids, we select one of them as the starting point for whatever we will do next:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">long</span> <span class="n">start</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">id</span><span class="p">,</span><span class="n">neighbors</span><span class="p">]</span><span class="o">:</span> <span class="n">neighbors</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">neighbors</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">start</span> <span class="o">=</span> <span class="n">id</span><span class="p">;</span>
		<span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>For simplicities sake, I once again inefficiently represented a grid as map and used a hashmap to keep track of which tiles were already set:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">long</span><span class="p">,</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">used</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">point2d</span><span class="p">,</span><span class="kt">long</span><span class="o">&gt;</span> <span class="n">grid</span><span class="p">;</span></code></pre>
</figure>

<p>Filling the grid is done as described above:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">fill</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="n">point2d</span> <span class="n">p</span><span class="p">,</span> <span class="kt">long</span> <span class="n">id</span><span class="p">,</span> <span class="kt">long</span> <span class="n">right_id</span><span class="p">,</span> <span class="kt">long</span> <span class="n">down_id</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">used</span><span class="p">[</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
	<span class="n">used</span><span class="p">[</span><span class="n">right_id</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
	<span class="n">used</span><span class="p">[</span><span class="n">down_id</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
	
	<span class="n">grid</span><span class="p">[</span><span class="n">p</span><span class="p">]</span> <span class="o">=</span> <span class="n">id</span><span class="p">;</span>
	<span class="n">grid</span><span class="p">[</span><span class="n">p</span><span class="o">+</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">}]</span> <span class="o">=</span> <span class="n">right_id</span><span class="p">;</span>
	<span class="n">grid</span><span class="p">[</span><span class="n">p</span><span class="o">+</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">}]</span> <span class="o">=</span> <span class="n">down_id</span><span class="p">;</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">grid</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">&lt;</span><span class="n">neighbors</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
	<span class="p">{</span>
		<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">id</span><span class="p">,</span> <span class="n">n</span><span class="p">]</span><span class="o">:</span> <span class="n">neighbors</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">defined_count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
			<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">n_id</span><span class="o">:</span> <span class="n">n</span><span class="p">)</span>
				<span class="n">defined_count</span> <span class="o">+=</span> <span class="n">used</span><span class="p">[</span><span class="n">n_id</span><span class="p">]</span><span class="o">?</span><span class="mi">1</span><span class="o">:</span><span class="mi">0</span><span class="p">;</span>
				
			<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">used</span><span class="p">[</span><span class="n">id</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">defined_count</span><span class="o">&gt;=</span><span class="mi">2</span><span class="p">)</span>
				<span class="n">place_tile</span><span class="p">(</span><span class="n">id</span><span class="p">);</span>
			
		<span class="p">}</span>
		
		<span class="n">right_id</span> <span class="o">=</span> <span class="n">place_missing_at</span><span class="p">(</span><span class="n">right_id</span><span class="p">,</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">});</span>
		<span class="n">down_id</span> <span class="o">=</span> <span class="n">place_missing_at</span><span class="p">(</span><span class="n">down_id</span><span class="p">,</span><span class="n">vec2d</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">});</span>
	<span class="p">}</span>
<span class="p">};</span></code></pre>
</figure>

<p>First, we set the three initial tiles and then, until we have set all of them, we fill in those with two neighbors, advance the ones on the borders and repeat.</p>

<p>To find where to place one with two neighbors, we find the position of those neighbors and take the max of their x and y coordinates:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">place_tile</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">long</span> <span class="n">id</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">found</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">point2d</span><span class="p">,</span><span class="mi">2</span><span class="o">&gt;</span> <span class="n">n_coord</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">p</span><span class="p">,</span><span class="n">n_id</span><span class="p">]</span><span class="o">:</span> <span class="n">grid</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">n</span><span class="o">:</span> <span class="n">neighbors</span><span class="p">[</span><span class="n">id</span><span class="p">])</span>
			<span class="k">if</span><span class="p">(</span><span class="n">n_id</span><span class="o">==</span><span class="n">n</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="n">n_coord</span><span class="p">[</span><span class="n">found</span><span class="o">++</span><span class="p">]</span><span class="o">=</span><span class="n">p</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="p">}</span>
		<span class="k">if</span><span class="p">(</span><span class="n">found</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span>
			<span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="k">const</span> <span class="n">point2d</span> <span class="n">place_at</span> <span class="o">=</span> <span class="p">{</span><span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">n_coord</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">,</span><span class="n">n_coord</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">(</span><span class="n">n_coord</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span><span class="p">,</span><span class="n">n_coord</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span><span class="p">)};</span>
	<span class="n">used</span><span class="p">[</span><span class="n">id</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
	<span class="n">grid</span><span class="p">[</span><span class="n">place_at</span><span class="p">]</span> <span class="o">=</span> <span class="n">id</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>The direction for the other case is predefined, so we only need to find the unset neighbor and add the direction vector:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">place_missing_at</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">long</span> <span class="n">set_neighbor_id</span><span class="p">,</span> <span class="n">vec2d</span> <span class="n">direction</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">point2d</span> <span class="n">n_coord</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">};</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">p</span><span class="p">,</span><span class="n">n_id</span><span class="p">]</span><span class="o">:</span> <span class="n">grid</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">n_id</span> <span class="o">==</span> <span class="n">set_neighbor_id</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">n_coord</span><span class="o">=</span><span class="n">p</span><span class="p">;</span>
			<span class="k">break</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
	
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">n_id</span><span class="o">:</span> <span class="n">neighbors</span><span class="p">[</span><span class="n">set_neighbor_id</span><span class="p">])</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">used</span><span class="p">[</span><span class="n">n_id</span><span class="p">])</span>
		<span class="p">{</span>			
			<span class="n">used</span><span class="p">[</span><span class="n">n_id</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
			<span class="k">return</span> <span class="n">grid</span><span class="p">[</span><span class="n">n_coord</span><span class="o">+</span><span class="n">direction</span><span class="p">]</span> <span class="o">=</span> <span class="n">n_id</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
	
	<span class="k">return</span> <span class="n">set_neighbor_id</span><span class="p">;</span>
	
<span class="p">};</span></code></pre>
</figure>

<p>Afterwards, we still have to correct flips and rotations, remove the border, compose a complete grid and search for a specified pattern - an ascii art sea monster - within that image. As that is not particularly interesting, quite tedious and even repetitive, I refer you to <a href="https://github.com/philipplenk/adventofcode20/tree/main/20/02.cpp">the complete code</a> instead of elaborating on it any further. It is a mess and you have been warned ;-)</p>

<h2 id="day-21"><a href="https://github.com/philipplenk/adventofcode20/tree/main/21">Day 21</a></h2>

<h3 id="part-1-20">Part 1</h3>

<p>Given a list of unknown ingredients and a list of allergens contained in them (each allergen appearing in exactly one ingredient, each ingredient containing at most one allergen and not all allergens listed every time), we are tasked with figuring out which ingredient contains which allergen. Well, first of all we are asked a simpler question: which ingredients do definitely not contain any allergen.
It took me a while to understand what exactly was asked here, but it all comes down to set intersections and differences. Whenever an allergen is contained in two lists, it must be contained in the intersection of those lists, not in the difference. Thanks to the beauty of the C++ standard library, this simple insight leads to a very straightforward solution using simple calls to std::set_intersection and std::set_difference:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">d</span><span class="o">:</span> <span class="n">dishes</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">a</span><span class="o">:</span> <span class="n">d</span><span class="p">.</span><span class="n">allergens</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">auto</span><span class="o">&amp;</span> <span class="n">old</span> <span class="o">=</span> <span class="n">allergen_to_ingredient</span><span class="p">[</span><span class="n">a</span><span class="p">];</span>
		<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">corrected</span><span class="p">;</span>
		
				<span class="n">std</span><span class="o">::</span><span class="n">set_intersection</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">old</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">old</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">d</span><span class="p">.</span><span class="n">ingredients</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">d</span><span class="p">.</span><span class="n">ingredients</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">corrected</span><span class="p">));</span>
		<span class="n">old</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">corrected</span><span class="p">);</span>
	<span class="p">}</span>
<span class="p">}</span>
	
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">harmless</span> <span class="o">=</span> <span class="n">all_ingredients</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">a</span><span class="p">,</span><span class="n">ing</span><span class="p">]</span> <span class="o">:</span><span class="n">allergen_to_ingredient</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">corrected</span><span class="p">;</span>
		<span class="n">std</span><span class="o">::</span><span class="n">set_difference</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">harmless</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">harmless</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">ing</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">ing</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">corrected</span><span class="p">));</span>
	<span class="n">harmless</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">corrected</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</figure>

<h3 id="part-2-20">Part 2</h3>

<p>Having solved this simple question, we now have to uniquely identify which ingredient contains which allergen. Given our previous solution and knowing it is uniquely solvable, this is rather trivial. First, identify one allergen that can only be in one ingredient. Remove it as a possibility from all other allergens. Rinse and repeat:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">done_cnt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">do</span>
<span class="p">{</span>
	<span class="n">done_cnt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">a</span><span class="p">,</span><span class="n">ing</span><span class="p">]</span> <span class="o">:</span><span class="n">allergen_to_ingredient</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">ing</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="o">++</span><span class="n">done_cnt</span><span class="p">;</span>
			<span class="k">for</span><span class="p">(</span><span class="k">auto</span><span class="o">&amp;</span> <span class="p">[</span><span class="n">a_other</span><span class="p">,</span><span class="n">ing_other</span><span class="p">]</span> <span class="o">:</span><span class="n">allergen_to_ingredient</span><span class="p">)</span>
			<span class="p">{</span>
				<span class="k">if</span><span class="p">(</span><span class="n">a_other</span><span class="o">==</span><span class="n">a</span> <span class="o">||</span> <span class="n">ing_other</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">==</span><span class="mi">1</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
				<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">corrected</span><span class="p">;</span>
				<span class="n">std</span><span class="o">::</span><span class="n">set_difference</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">ing_other</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">ing_other</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">ing</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">ing</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">corrected</span><span class="p">));</span>
				<span class="n">ing_other</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">corrected</span><span class="p">);</span>
			<span class="p">}</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span>
<span class="k">while</span><span class="p">(</span><span class="n">done_cnt</span><span class="o">&lt;</span><span class="n">allergen_to_ingredient</span><span class="p">.</span><span class="n">size</span><span class="p">());</span></code></pre>
</figure>

<h2 id="day-22"><a href="https://github.com/philipplenk/adventofcode20/tree/main/22">Day 22</a></h2>

<h3 id="part-1-21">Part 1</h3>

<p>Space Cards! Almost missed them from last year, when they proved <a href="https://adventofcode.com/2019/day/22">one of the most interesting challenges</a>, due to their sheer number alone. This year, however, we are far more relaxed. Hardly any shuffling involved, just a <a href="https://en.wikipedia.org/wiki/War_(card_game)">simple game between two players</a>.</p>

<p>Both are given a deck of numbered cards and repeatedly and simultaneously draw and reveal their top card. The owner of the higher valued one wins the lower one and puts both cards below their own deck. Once a deck is cleared, the other player is declared the winner. Rather straightforward so far:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">player0</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">player1</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">player0</span><span class="p">.</span><span class="n">back</span><span class="p">()</span><span class="o">&gt;</span><span class="n">player1</span><span class="p">.</span><span class="n">back</span><span class="p">())</span>
	<span class="p">{</span>
		<span class="k">auto</span> <span class="n">other</span> <span class="o">=</span> <span class="n">player1</span><span class="p">.</span><span class="n">back</span><span class="p">();</span>
		<span class="n">player0</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="n">player0</span><span class="p">.</span><span class="n">back</span><span class="p">());</span>
		<span class="n">player0</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="n">other</span><span class="p">);</span>
		<span class="n">player0</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
		<span class="n">player1</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
	<span class="p">}</span>
	<span class="k">else</span>
	<span class="p">{</span>
		<span class="k">auto</span> <span class="n">other</span> <span class="o">=</span> <span class="n">player0</span><span class="p">.</span><span class="n">back</span><span class="p">();</span>
		<span class="n">player1</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="n">player1</span><span class="p">.</span><span class="n">back</span><span class="p">());</span>
		<span class="n">player1</span><span class="p">.</span><span class="n">push_front</span><span class="p">(</span><span class="n">other</span><span class="p">);</span>
		<span class="n">player0</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
		<span class="n">player1</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>If we only wanted to know who wins, it would be enough to check who owns the highest card in the beginning. The required result, however, was a score computed based on the order in the final deck and I couldn’t think of any better solution than a simple simulation.</p>

<h3 id="part-2-21">Part 2</h3>

<p>Part 2, as usual, is where things get interesting. Whenever the two top numbers are smaller than what is left of the respective decks, we recurse on a copy of the top that many cards to determine the winner. If a position repeats, player 0 wins by default.</p>

<p>That rule was a bit ambiguous and hard to grasp. What player 0 wins is that single subgame. Not the current round and not the whole game. I lost about 10 minutes on misunderstanding that, as I thought it referred to the round only and got an error I failed to understand. The given example input does not trigger that specific case and erroneous behavior, yielding the correct result even with the misunderstanding. Well, the rest was fairly easy with the difficulty coming mainly from more or less efficiently implementing the game rules, which I notably did not do.</p>

<p>I am certain it could be optimized significantly, as my solution takes about half a second on my laptop, which is huge. I am, however, lazy, so I declared it adequate.</p>

<p>The main game logic is pretty much equivalent to the one from part 1. I just cleaned it up a little bit and used a call to a more complicated function to determine who wins the next card instead of simply comparing the top ones:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">decks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">empty</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">decks</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">empty</span><span class="p">())</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">pair</span> <span class="n">cache_id</span> <span class="o">=</span> <span class="p">{</span><span class="n">compute_id</span><span class="p">(</span><span class="n">decks</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span><span class="n">compute_id</span><span class="p">(</span><span class="n">decks</span><span class="p">[</span><span class="mi">1</span><span class="p">])};</span>
	<span class="k">if</span><span class="p">(</span><span class="n">cache</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">cache_id</span><span class="p">)</span><span class="o">!=</span><span class="n">cache</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
		<span class="k">return</span> <span class="n">ret_val_t</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="n">compute_score</span><span class="p">(</span><span class="n">decks</span><span class="p">[</span><span class="mi">0</span><span class="p">])};</span>
	
	<span class="n">cache</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">cache_id</span><span class="p">);</span>
			
	<span class="k">const</span> <span class="k">auto</span> <span class="n">winner</span> <span class="o">=</span> <span class="n">next_card_winner</span><span class="p">();</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">loser</span> <span class="o">=</span> <span class="n">winner</span><span class="o">==</span><span class="mi">0</span><span class="o">?</span><span class="mi">1</span><span class="o">:</span><span class="mi">0</span><span class="p">;</span>
	
	<span class="k">const</span> <span class="k">auto</span> <span class="n">other</span> <span class="o">=</span> <span class="n">decks</span><span class="p">[</span><span class="n">loser</span><span class="p">].</span><span class="n">back</span><span class="p">();</span>
	<span class="n">decks</span><span class="p">[</span><span class="n">winner</span><span class="p">].</span><span class="n">push_front</span><span class="p">(</span><span class="n">decks</span><span class="p">[</span><span class="n">winner</span><span class="p">].</span><span class="n">back</span><span class="p">());</span>
	<span class="n">decks</span><span class="p">[</span><span class="n">winner</span><span class="p">].</span><span class="n">push_front</span><span class="p">(</span><span class="n">other</span><span class="p">);</span>
	<span class="n">decks</span><span class="p">[</span><span class="n">winner</span><span class="p">].</span><span class="n">pop_back</span><span class="p">();</span>
	<span class="n">decks</span><span class="p">[</span><span class="n">loser</span><span class="p">].</span><span class="n">pop_back</span><span class="p">();</span>			
<span class="p">}</span></code></pre>
</figure>

<p>I also kept a set of already appeared deck combinations, to implement the “player 1 wins on repetition” rule. <em>next_card_winner</em> is equally trivial:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">next_card_winner</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">]()</span>
<span class="p">{</span>		
	<span class="k">if</span><span class="p">(</span><span class="n">decks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">back</span><span class="p">()</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">decks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">())</span> <span class="o">&amp;&amp;</span> <span class="n">decks</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">back</span><span class="p">()</span><span class="o">&lt;</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="n">decks</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">size</span><span class="p">()))</span>
	<span class="p">{</span>
		<span class="k">auto</span> <span class="n">decks_new</span> <span class="o">=</span> <span class="n">decks</span><span class="p">;</span>
		<span class="n">decks_new</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">pop_back</span><span class="p">();</span>
		<span class="n">decks_new</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">pop_back</span><span class="p">();</span>
		
		<span class="n">decks_new</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">erase</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">decks_new</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">decks_new</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="o">+</span><span class="n">decks_new</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="n">decks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">back</span><span class="p">());</span>
		<span class="n">decks_new</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">erase</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">decks_new</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">decks_new</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="o">+</span><span class="n">decks_new</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="n">decks</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">back</span><span class="p">());</span>
				
		<span class="k">auto</span> <span class="n">result</span> <span class="o">=</span> <span class="n">recurse</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">decks_new</span><span class="p">),</span><span class="n">recurse</span><span class="p">);</span>
		<span class="k">return</span> <span class="n">result</span><span class="p">.</span><span class="n">winner_id</span><span class="p">;</span>
	<span class="p">}</span>	
		
	<span class="k">return</span> <span class="n">decks</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">back</span><span class="p">()</span><span class="o">&gt;</span><span class="n">decks</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">back</span><span class="p">()</span><span class="o">?</span><span class="mi">0</span><span class="o">:</span><span class="mi">1</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>If there are enough cards in both decks, we recurse into a subgame and return the winner of that. Otherwise, the higher card wins.</p>

<h2 id="day-23"><a href="https://github.com/philipplenk/adventofcode20/tree/main/23">Day 23</a></h2>

<p>Well, that was an experience… My sleep deprivation at this point might have hit a new high, causing me to have somewhat less concentration and a much better excuse than usual, but it is just an excuse and I failed to see the obvious solution right in front of my eyes. But that’s something for later, first, lets describe the problem:</p>

<h3 id="part-1-22">Part 1</h3>

<p>Given a bunch of numbered cups, arranged in a circle, our opponent - a very intelligent crab, apparently the <a href="https://en.wikipedia.org/wiki/Carcinisation">pinnacle of evolution</a> - rearranges them according to a number of simple rules. We have to determine where a specific cup ends up after a given number of moves. In each move, the crab picks up three cups clockwise after the “current” one and moves them right after the next lower numbered cup. The one after the newly inserted ones then becomes the next “current” cup.</p>

<p>Here is my hacky, god-awful looking and performing code simulating one such move:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">move</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">current</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">original_value</span> <span class="o">=</span> <span class="n">cups</span><span class="p">[</span><span class="n">current</span><span class="p">];</span>
	<span class="k">auto</span> <span class="n">target_value</span> <span class="o">=</span> <span class="n">cups</span><span class="p">[</span><span class="n">current</span><span class="p">]</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span>
	<span class="k">if</span><span class="p">(</span><span class="n">target_value</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="n">target_value</span> <span class="o">=</span> <span class="mi">9</span><span class="p">;</span>
	 
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">3</span><span class="o">&gt;</span> <span class="n">taken</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="mi">3</span><span class="p">;</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">taken</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">cups</span><span class="p">[(</span><span class="n">current</span><span class="o">+</span><span class="mi">1</span><span class="o">+</span><span class="n">i</span><span class="p">)</span><span class="o">%</span><span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">()];</span>
		<span class="n">cups</span><span class="p">[(</span><span class="n">current</span><span class="o">+</span><span class="mi">1</span><span class="o">+</span><span class="n">i</span><span class="p">)</span><span class="o">%</span><span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">()]</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="n">cups</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">remove</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="mi">0</span><span class="p">),</span><span class="n">cups</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">find</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">taken</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">taken</span><span class="p">),</span><span class="n">target_value</span><span class="p">)</span><span class="o">!=</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">taken</span><span class="p">))</span>
		<span class="n">target_value</span> <span class="o">=</span> <span class="n">target_value</span><span class="o">==</span><span class="mi">1</span><span class="o">?</span><span class="mi">9</span><span class="o">:</span><span class="p">(</span><span class="n">target_value</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
	
	<span class="k">auto</span> <span class="n">target_pos</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">find</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="n">target_value</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
		
	<span class="n">cups</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">target_pos</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">taken</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">taken</span><span class="p">));</span>
	
	<span class="k">auto</span> <span class="n">original_pos</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">find</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="n">original_value</span><span class="p">)</span> <span class="o">-</span> <span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">cups</span><span class="p">);</span>
		
	<span class="k">if</span><span class="p">(</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">long</span><span class="o">&gt;</span><span class="p">(</span><span class="n">current</span><span class="p">)</span><span class="o">&lt;</span><span class="n">original_pos</span><span class="p">)</span>
		<span class="n">std</span><span class="o">::</span><span class="n">rotate</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">cups</span><span class="p">)</span><span class="o">+</span><span class="p">(</span><span class="n">original_pos</span><span class="o">-</span><span class="n">current</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">cups</span><span class="p">));</span>
	<span class="k">else</span>
		<span class="n">std</span><span class="o">::</span><span class="n">rotate</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">rbegin</span><span class="p">(</span><span class="n">cups</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">rbegin</span><span class="p">(</span><span class="n">cups</span><span class="p">)</span><span class="o">+</span><span class="p">(</span><span class="n">current</span><span class="o">-</span><span class="n">original_pos</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">rend</span><span class="p">(</span><span class="n">cups</span><span class="p">));</span>
	
	<span class="k">return</span> <span class="p">(</span><span class="n">current</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
<span class="p">};</span></code></pre>
</figure>

<p>As you can see, I chose to represent the cups as integers in a giant array and copied and shifted them around, which was likely the worst, most expensive representation possible and which came back to bite me in part 2.</p>

<h3 id="part-2-22">Part 2</h3>

<p>Part 2 took the problem up to 11. Or rather up to 1000000 cups * 10000000 moves, causing this most trivial of brute force solutions to fail horrendously.</p>

<p>For the longest of times, I suspected there must be some sort of clever closed form solution. Turns out it was just an issue with implementing it in a little less brain dead way. A lot of cursing later, I realized that - of course - this is <strong>NOT</strong> a <a href="https://www.youtube.com/watch?v=UZmeDQL4LaE">rotate</a>, its simply a freaking linked list and that is one of the very few cases where using one actually proves more efficient and beneficial than a simple vector. Especially as we can still find any given list element in O(1), as they only contain one number. So <a href="https://github.com/philipplenk/adventofcode20/tree/main/23/02_unordered_map.cpp">this simple solution</a> finally gave me my desired star, using two hashmaps to represent the lists:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">unordered_map</span><span class="o">&lt;</span><span class="kt">long</span><span class="p">,</span><span class="kt">long</span><span class="o">&gt;</span> <span class="n">next</span><span class="p">,</span> <span class="n">prev</span><span class="p">;</span>

<span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">();</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">next</span><span class="p">[</span><span class="n">cups</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span><span class="o">=</span><span class="n">cups</span><span class="p">[(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">()];</span>
	<span class="n">prev</span><span class="p">[</span><span class="n">cups</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span><span class="o">=</span><span class="n">cups</span><span class="p">[</span><span class="n">i</span><span class="o">==</span><span class="mi">0</span><span class="o">?</span><span class="p">(</span><span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">:</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">)];</span>
<span class="p">}</span>

<span class="k">const</span> <span class="k">auto</span> <span class="n">move</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">int</span> <span class="n">original_value</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">target_value</span> <span class="o">=</span> <span class="n">original_value</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span>
	<span class="k">if</span><span class="p">(</span><span class="n">target_value</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span> <span class="n">target_value</span> <span class="o">=</span> <span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
	 
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">long</span><span class="p">,</span><span class="mi">3</span><span class="o">&gt;</span> <span class="n">taken</span><span class="p">;</span>
	<span class="n">taken</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="n">next</span><span class="p">[</span><span class="n">original_value</span><span class="p">];</span>
	<span class="n">taken</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">next</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">0</span><span class="p">]];</span>
	<span class="n">taken</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">=</span><span class="n">next</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">1</span><span class="p">]];</span>
	
	<span class="n">prev</span><span class="p">[</span><span class="n">next</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">2</span><span class="p">]]]</span> <span class="o">=</span> <span class="n">original_value</span><span class="p">;</span>
	<span class="n">next</span><span class="p">[</span><span class="n">original_value</span><span class="p">]</span> <span class="o">=</span> <span class="n">next</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">2</span><span class="p">]];</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">find</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">taken</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">taken</span><span class="p">),</span><span class="n">target_value</span><span class="p">)</span><span class="o">!=</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">taken</span><span class="p">))</span>
		<span class="n">target_value</span> <span class="o">=</span> <span class="n">target_value</span><span class="o">==</span><span class="mi">1</span><span class="o">?</span><span class="n">cups</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">:</span><span class="p">(</span><span class="n">target_value</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
	
	<span class="n">next</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span> <span class="o">=</span> <span class="n">next</span><span class="p">[</span><span class="n">target_value</span><span class="p">];</span>
	<span class="n">next</span><span class="p">[</span><span class="n">target_value</span><span class="p">]</span> <span class="o">=</span> <span class="n">taken</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
	<span class="n">prev</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">target_value</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">next</span><span class="p">[</span><span class="n">original_value</span><span class="p">];</span>
<span class="p">};</span></code></pre>
</figure>

<p>That is - of course - an utter waste and neither hashmaps nor doubly linked lists are required here. Instead, we can simply store the indices of our followup elements as a sort of in place forward list</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">forward_list_element</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">uint32_t</span> <span class="n">next</span><span class="p">;</span>
<span class="p">};</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">forward_list_element</span><span class="o">&gt;</span> <span class="n">list</span><span class="p">;</span>
<span class="n">list</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="mi">1000000</span><span class="p">);</span></code></pre>
</figure>

<p>and implement a move by changing the followup indices of the current element and the last one taken:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">move</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">int</span> <span class="n">original_value</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">auto</span> <span class="n">target_value</span> <span class="o">=</span> <span class="n">original_value</span><span class="o">==</span><span class="mi">0</span><span class="o">?</span><span class="p">(</span><span class="n">list</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">:</span><span class="p">(</span><span class="n">original_value</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
	 
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">,</span><span class="mi">3</span><span class="o">&gt;</span> <span class="n">taken</span><span class="p">;</span>
	<span class="n">taken</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="n">list</span><span class="p">[</span><span class="n">original_value</span><span class="p">].</span><span class="n">next</span><span class="p">;</span>
	<span class="n">taken</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="n">list</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">0</span><span class="p">]].</span><span class="n">next</span><span class="p">;</span>
	<span class="n">taken</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">=</span><span class="n">list</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">1</span><span class="p">]].</span><span class="n">next</span><span class="p">;</span>
	
	<span class="n">list</span><span class="p">[</span><span class="n">original_value</span><span class="p">].</span><span class="n">next</span> <span class="o">=</span> <span class="n">list</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">2</span><span class="p">]].</span><span class="n">next</span><span class="p">;</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">find</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">taken</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">taken</span><span class="p">),</span><span class="n">target_value</span><span class="p">)</span><span class="o">!=</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">taken</span><span class="p">))</span>
		<span class="n">target_value</span> <span class="o">=</span> <span class="n">target_value</span><span class="o">==</span><span class="mi">0</span><span class="o">?</span><span class="n">list</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="o">:</span><span class="p">(</span><span class="n">target_value</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span>
	
	<span class="n">list</span><span class="p">[</span><span class="n">taken</span><span class="p">[</span><span class="mi">2</span><span class="p">]].</span><span class="n">next</span> <span class="o">=</span> <span class="n">list</span><span class="p">[</span><span class="n">target_value</span><span class="p">].</span><span class="n">next</span><span class="p">;</span>
	<span class="n">list</span><span class="p">[</span><span class="n">target_value</span><span class="p">].</span><span class="n">next</span> <span class="o">=</span> <span class="n">taken</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
	
	<span class="k">return</span> <span class="n">list</span><span class="p">[</span><span class="n">original_value</span><span class="p">].</span><span class="n">next</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<h2 id="day-24"><a href="https://github.com/philipplenk/adventofcode20/tree/main/24">Day 24</a></h2>

<h3 id="part-1-23">Part 1</h3>

<p>Flipping tiles in a hex grid. Fun, if only I remembered to get my stupid hex coordinates right. Took me a while to get back to it and in my learning I discovered <a href="https://www.redblobgames.com/grids/hexagons/">a beautiful resource going into great detail</a>, which I highly recommend reading.</p>

<p>Especially the little graphic under axial coordinates listing neighbors really saved my skin this time. Everything but this was, of course, rather trivial.</p>

<p>Starting out with an infinitely extending hexagonal grid, all of which white, we were given a number of pathes from a starting point and were supposed to flip the tiles on the destinations to black(or back to white if they were reached a second time).</p>

<p>As such, we need to represent binary colors and offer a way to flip them:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">enum</span> <span class="k">class</span> <span class="nc">color</span>
<span class="p">{</span>
	<span class="n">white</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
	<span class="n">black</span>
<span class="p">};</span>

<span class="n">color</span> <span class="nf">flip</span><span class="p">(</span><span class="n">color</span> <span class="n">c</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">return</span> <span class="n">c</span><span class="o">==</span><span class="n">color</span><span class="o">::</span><span class="n">white</span><span class="o">?</span><span class="n">color</span><span class="o">::</span><span class="n">black</span><span class="o">:</span><span class="n">color</span><span class="o">::</span><span class="n">white</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>As well as the 6 possible hexadecimal directions and a way to compute coordinates based on them:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">enum</span> <span class="k">class</span> <span class="nc">hex_direction</span>
<span class="p">{</span>
	<span class="n">e</span><span class="p">,</span>
	<span class="n">w</span><span class="p">,</span>
	<span class="n">se</span><span class="p">,</span>
	<span class="n">sw</span><span class="p">,</span>
	<span class="n">ne</span><span class="p">,</span>
	<span class="n">nw</span>
<span class="p">};</span>

<span class="n">vec2d</span> <span class="nf">to_vec2d</span><span class="p">(</span><span class="n">hex_direction</span> <span class="n">dir</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">switch</span><span class="p">(</span><span class="n">dir</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">case</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">e</span><span class="p">:</span> <span class="k">return</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">};</span>
		<span class="k">case</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">w</span><span class="p">:</span> <span class="k">return</span> <span class="p">{</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">};</span>
		<span class="k">case</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">se</span><span class="p">:</span> <span class="k">return</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">};</span>
		<span class="k">case</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">sw</span><span class="p">:</span> <span class="k">return</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">};</span>
		<span class="k">case</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">ne</span><span class="p">:</span> <span class="k">return</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">};</span>
		<span class="k">case</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">nw</span><span class="p">:</span> <span class="k">return</span> <span class="p">{</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">};</span>
	<span class="p">}</span>
	
	<span class="k">return</span><span class="p">{};</span>
<span class="p">}</span></code></pre>
</figure>

<p>As you can see, I chose axial coordinates. To understand why exactly that works, I would like to once again refer you to <a href="https://www.redblobgames.com/grids/hexagons/">this wonderful explanation</a>, which is far better than anything I could offer on that topic.</p>

<p>With that groundwork laid(and an overloaded operator» for parsing directions), the input based flipping is rather straightforward:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">point2d</span><span class="p">,</span><span class="n">color</span><span class="o">&gt;</span> <span class="n">colors</span><span class="p">;</span>

<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">line</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">getline</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">,</span><span class="n">line</span><span class="p">))</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">stringstream</span> <span class="n">strm</span><span class="p">;</span>
	<span class="n">strm</span><span class="o">&lt;&lt;</span><span class="n">line</span><span class="p">;</span>
	
	<span class="n">point2d</span> <span class="n">pos</span><span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">};</span>
	<span class="n">hex_direction</span> <span class="n">d</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">strm</span><span class="o">&gt;&gt;</span><span class="n">d</span><span class="p">)</span>
		<span class="n">pos</span><span class="o">+=</span><span class="n">to_vec2d</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>
	
	<span class="n">colors</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span><span class="o">=</span><span class="n">flip</span><span class="p">(</span><span class="n">colors</span><span class="p">[</span><span class="n">pos</span><span class="p">]);</span>
<span class="p">}</span></code></pre>
</figure>

<h3 id="part-2-23">Part 2</h3>

<p>And here we come to the reason for all those shenanigans. We had a seating area cellular automaton, we had a 4 dimensional cellular automaton, why not have one on a hex grid?</p>

<p>The code is almost identical to the one used for arbitrarily dimensional hypercubes before, so in case anything is unclear, I suggest looking at my solution for Day 17. If anything remains unclear, feel free to leave a comment on my blog or simply send me an email ;-)</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">update</span><span class="o">=</span><span class="p">[</span><span class="o">&amp;</span><span class="p">]()</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">point2d</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="o">&gt;</span> <span class="n">counts</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">p</span><span class="p">,</span><span class="n">c</span><span class="p">]</span><span class="o">:</span> <span class="n">colors</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">if</span><span class="p">(</span><span class="n">c</span><span class="o">==</span><span class="n">color</span><span class="o">::</span><span class="n">white</span><span class="p">)</span>
			<span class="k">continue</span><span class="p">;</span>
		
		<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">n</span><span class="o">:</span> <span class="p">{</span><span class="n">hex_direction</span><span class="o">::</span><span class="n">e</span><span class="p">,</span><span class="n">hex_direction</span><span class="o">::</span><span class="n">w</span><span class="p">,</span><span class="n">hex_direction</span><span class="o">::</span><span class="n">ne</span><span class="p">,</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">nw</span><span class="p">,</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">sw</span><span class="p">,</span> <span class="n">hex_direction</span><span class="o">::</span><span class="n">se</span><span class="p">})</span>
			<span class="o">++</span><span class="n">counts</span><span class="p">[</span><span class="n">p</span><span class="o">+</span><span class="n">to_vec2d</span><span class="p">(</span><span class="n">n</span><span class="p">)];</span>
	<span class="p">}</span>
	
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">p</span><span class="p">,</span><span class="n">c</span><span class="p">]</span><span class="o">:</span> <span class="n">colors</span><span class="p">)</span>
		<span class="k">if</span><span class="p">(</span><span class="n">c</span><span class="o">==</span><span class="n">color</span><span class="o">::</span><span class="n">black</span><span class="p">)</span>
			<span class="n">counts</span><span class="p">[</span><span class="n">p</span><span class="p">]</span><span class="o">=</span><span class="n">counts</span><span class="p">[</span><span class="n">p</span><span class="p">];</span>
	
	<span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="p">[</span><span class="n">p</span><span class="p">,</span><span class="n">cnt</span><span class="p">]</span><span class="o">:</span> <span class="n">counts</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">auto</span><span class="o">&amp;</span> <span class="n">c</span> <span class="o">=</span> <span class="n">colors</span><span class="p">[</span><span class="n">p</span><span class="p">];</span>
		<span class="k">if</span><span class="p">(</span><span class="n">c</span><span class="o">==</span><span class="n">color</span><span class="o">::</span><span class="n">black</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="n">cnt</span><span class="o">==</span><span class="mi">0</span> <span class="o">||</span> <span class="n">cnt</span><span class="o">&gt;</span><span class="mi">2</span><span class="p">))</span>
			<span class="n">c</span><span class="o">=</span><span class="n">color</span><span class="o">::</span><span class="n">white</span><span class="p">;</span>
		<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">c</span><span class="o">==</span><span class="n">color</span><span class="o">::</span><span class="n">white</span> <span class="o">&amp;&amp;</span> <span class="n">cnt</span><span class="o">==</span><span class="mi">2</span><span class="p">)</span>
			<span class="n">c</span><span class="o">=</span><span class="n">color</span><span class="o">::</span><span class="n">black</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">};</span></code></pre>
</figure>

<h2 id="day-25"><a href="https://github.com/philipplenk/adventofcode20/tree/main/25">Day 25</a></h2>

<p>For the final task this year, which - as is traditional - came in just one part, we had to break what was basically a <a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange">Diffie-Hellman key exchange</a> with very small, brute forceable numbers.</p>

<p>I was so glad I had that multiplicative inverse function from day 13 lying around that I immediately used it to determine the loop number:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">long</span><span class="o">&gt;</span> <span class="n">powers_of_7</span><span class="p">;</span>
<span class="n">powers_of_7</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="mi">100000000</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">generate</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">powers_of_7</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">powers_of_7</span><span class="p">),[</span><span class="n">curr</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">long</span> <span class="kt">long</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1</span><span class="p">)]()</span> <span class="k">mutable</span> <span class="p">{</span> <span class="k">auto</span> <span class="n">ret_val</span> <span class="o">=</span> <span class="n">curr</span><span class="p">;</span> <span class="n">curr</span><span class="o">=</span><span class="n">curr</span><span class="o">*</span><span class="mi">7</span><span class="o">%</span><span class="n">modulus</span><span class="p">;</span> <span class="k">return</span> <span class="n">ret_val</span><span class="p">;</span> <span class="p">});</span>

<span class="k">const</span> <span class="k">auto</span> <span class="n">which_power_of_7</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">long</span> <span class="kt">long</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">find</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">powers_of_7</span><span class="p">),</span><span class="n">std</span><span class="o">::</span><span class="n">end</span><span class="p">(</span><span class="n">powers_of_7</span><span class="p">),</span><span class="n">n</span><span class="p">)</span><span class="o">-</span><span class="n">std</span><span class="o">::</span><span class="n">begin</span><span class="p">(</span><span class="n">powers_of_7</span><span class="p">)</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">const</span> <span class="k">auto</span> <span class="n">find_factor</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">long</span> <span class="kt">long</span> <span class="n">key</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">const</span> <span class="k">auto</span> <span class="n">inv</span> <span class="o">=</span> <span class="n">multiplicative_inverse</span><span class="p">(</span><span class="n">subject_number</span><span class="p">,</span><span class="n">modulus</span><span class="p">);</span>
	<span class="k">auto</span> <span class="n">n</span> <span class="o">=</span> <span class="p">(</span><span class="n">inv</span><span class="o">*</span><span class="n">key</span><span class="p">)</span><span class="o">%</span><span class="n">modulus</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">which_power_of_7</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
<span class="p">};</span></code></pre>
</figure>

<p>Using that result, I could simply execute the algorithm as described to obtain the unknown key:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">transform_with</span> <span class="o">=</span> <span class="p">[](</span><span class="kt">long</span> <span class="kt">long</span> <span class="n">subject_number</span><span class="p">,</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">loop_size</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	
	<span class="k">while</span><span class="p">(</span><span class="n">loop_size</span><span class="o">--</span><span class="p">)</span>
		<span class="n">value</span><span class="o">=</span><span class="n">value</span><span class="o">*</span><span class="n">subject_number</span><span class="o">%</span><span class="n">modulus</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">value</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>Turns out, however, that this is incredibly wasteful and instead of precomputing all those powers, I could simply do the same computations with the known key whilst counting the iterations:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">const</span> <span class="k">auto</span> <span class="n">find_factor</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">long</span> <span class="kt">long</span> <span class="n">key</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">long</span> <span class="kt">long</span> <span class="n">value</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">loop</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">while</span><span class="p">(</span><span class="n">value</span><span class="o">!=</span><span class="n">key</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">value</span><span class="o">*=</span><span class="n">subject_number</span><span class="p">;</span>
		<span class="n">value</span><span class="o">%=</span><span class="n">modulus</span><span class="p">;</span>
		<span class="o">++</span><span class="n">loop</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">return</span> <span class="n">loop</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<h1 id="conclusion">Conclusion</h1>

<h2 id="closing-thoughts-on-this-edition">Closing thoughts on this edition</h2>

<p>And that is it for this year. I tragically never made it onto the leaderboard, but that doesn’t matter.<sup id="fnref:pain" role="doc-noteref"><a href="#fn:pain" class="footnote" rel="footnote">11</a></sup> I had a tremendous amount of fun and learned a lot.</p>

<p>There were a bunch of problems that made me think for what seemed like eons, searching, despairing, believing that there must be some better solution available. Yet, just like real life 2020, things really were as bad as they seemed and all we could do was try and grind through. Save our energy, do it as efficient as possible, with as little lasting damage as possible, but still: the only way out was putting in the work. Every single step. Slowly and tediously crawling to the finishing line.</p>

<p>Sadly, 2020 also marked the day of <a href="https://en.wikipedia.org/wiki/John_Horton_Conway">John Conway’s</a> passing, his absence was felt and his legacy honored with variations of his <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Game of Life</a> featured rather prominently.</p>

<p>This edition was - in my humble opinion - not the most difficult edition ever and quite harmless compared to 2019. Whilst I was hoping for a bit more of a challenge, that property proved really useful for convincing beginners to try it and learn from it. It is a delicate balance to strike.</p>

<h2 id="what-now">What now?</h2>

<p>After the event, someone posted a famous picture on reddit, <a href="https://www.reddit.com/r/adventofcode/comments/kkfl3e/morning_after_the_end_of_aoc_2020/">captioned “Morning after the end of AOC 2020”</a>
which so adequately expressed my feeling on the eve of the end that I have no choice but to reproduce it here:</p>

<p><img src="/images/advent_sadness.jpg" alt="Emptyness" title="What now?" class="centered-image" width="40%" /></p>

<p>After all this time of the puzzles being an integral part of my daily routine, it simply… ended.</p>

<p>This gaping hole in my chest had to be filled, I was craving for something, just anything to make this insufferable feeling of emptiness go away.</p>

<p>There are, of course, previous editions and you can still try and solve all of them. Unfortunately, that was no longer an option:</p>

<p><img src="/images/advent_complete.jpg" alt="Bragging" title="What now?" class="centered-image" width="40%" /></p>

<p>Great, I know. For all those who really like the interpreter exercises - and I really loved 2019’s intcode - there is one of Eric Wastl’s older puzzles, the <a href="https://challenge.synacor.com/">Synacor Challenge</a>. Alas, that was the path I took last year.</p>

<p>Oh right, there is one more option. The final day was great, I like cryptography and there is <a href="https://cryptopals.com/">the cryptopals challenge.</a> Why did that come to mind? Ah yes, I remember, I did that three years ago.</p>

<p>Luckily for me, after lots of soul and google searching, I discovered <a href="https://www.codingame.com">codingame</a>. Not only do they have a number of high quality puzzles, they foster a vibrant community - with puzzle solving and competitions regularly being live streamed and featured on the main site - and their <a href="https://www.codingame.com/multiplayer/clashofcode">clash of code</a> format, quick 15 minute speed coding competitions, proved mildly addicting. I might be spending an unhealthy amount of time on there. Please send help.</p>

<p>So, if you feel like I did, maybe one of the things mentioned above could be for you. Feel free to <a href="https://www.codingame.com/profile/a41e5f2d496e10e016a00669702741317380214">invite me to a clash</a> sometime, I am always up for a challenge.</p>

<p>If you fall into really deep despair and desperately need to bridge that gap some other way, you might as well read a blog post about it that appeared way too late for anyone to care ;-)</p>

<p>In my next post, which I will publish much much sooner, I promise, I shall return to the topic of emulation. In the meantime, I am looking forward to being destroyed in the comments.</p>

<hr />
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:celebrate" role="doc-endnote">
      <p>both of which I don’t particularly enjoy celebrating anyway <a href="#fnref:celebrate" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:why" role="doc-endnote">
      <p>As written about <a href="/2020/05/16/why.html">in my very first article on this blog</a> <a href="#fnref:why" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:party" role="doc-endnote">
      <p>It has likely long since ended, but that’s ok. Who likes parties anyway? I am sure - even without me - it was <a href="https://www.youtube.com/watch?v=KLoYVjDTYsM"><em>fine</em></a> <a href="#fnref:party" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:easter" role="doc-endnote">
      <p>One day I will <a href="https://adventofcode.com/2016/day/1">have my revenge!</a> <a href="#fnref:easter" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:excuse" role="doc-endnote">
      <p>And I get a most convenient excuse ;-) <a href="#fnref:excuse" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:advent_credit" role="doc-endnote">
      <p>image taken with gratitude <a href="https://en.wikipedia.org/wiki/File:Diciembre.jpg">from here</a> <a href="#fnref:advent_credit" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:speed" role="doc-endnote">
      <p>one might argue, however, that this very care does give non-compiled languages a special benefit for speed solving, but that is just me being bitter xD <a href="#fnref:speed" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:failure" role="doc-endnote">
      <p>which ultimately proved unsuccessful. <a href="#fnref:failure" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:ring" role="doc-endnote">
      <p>Unfortunately, we did not get a ring in C++20 either. Can anyone tell me what happend to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0059r4.pdf">p0059?</a> <a href="#fnref:ring" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:mathy" role="doc-endnote">
      <p>which is a good thing! <a href="#fnref:mathy" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:pain" role="doc-endnote">
      <p>Of course it does, my soul is crushed. If I have such a thing. Whatever that even means… <a href="#fnref:pain" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Hannah Lenk</name><email>hannah.lenk@codemetas.de</email></author><category term="adventofcode" /><category term="2020" /><category term="c++" /><summary type="html"><![CDATA[My most valued readers! So glad you could drop by again! You are just in time to catch me singing the praises - almost as belated as they are deserved - for an annual coding competition that can be classified as the highlight of many a programmer each year. In addition, I also show and explain all my solutions for it.]]></summary></entry><entry><title type="html">The Royal Game</title><link href="http://localhost:4000/2020/11/22/The-Royal-Game.html" rel="alternate" type="text/html" title="The Royal Game" /><published>2020-11-22T22:03:15+01:00</published><updated>2020-11-22T22:03:15+01:00</updated><id>http://localhost:4000/2020/11/22/The%20Royal%20Game</id><content type="html" xml:base="http://localhost:4000/2020/11/22/The-Royal-Game.html"><![CDATA[<p><em>Welcome back - or so I hope - for yet another exciting installment of the grand, illustrious and ultimately pointless epic of “What have I wasted my freetime on in recent years”. This time around, I shall tell you about the royal game, i.e. chess, or rather of my humble attempts at contributing to its rich ecosystem of non-human players.</em></p>

<p>I will begin by explaining what I am talking about, briefly<sup id="fnref:briefly" role="doc-noteref"><a href="#fn:briefly" class="footnote" rel="footnote">1</a></sup> recap the fascinating history of computer chess and in the course of that highlight the importance of game playing for showcasing, popularizing and driving machine intelligence research as well as its public perception. I shall further elaborate on my personal connection and love for the game and detail why - even in the face of a recent uptake of machine learning based techniques far more successful than my puny attempts could ever hope to be - an old-school, classical approach can still be a valuable investment of time and energy.<br />
Afterwards, once my poor readers have slogged through this somewhat unnecessary prelude<sup id="fnref:skip" role="doc-noteref"><a href="#fn:skip" class="footnote" rel="footnote">2</a></sup>, I will get just a little more technical and provide a high level explanation of the general structure underlying many chess playing programs, culminating in a walkthrough of code implementing the UCI protocol used to communicate with GUIs and other programs pitting different human and non-human connoisseurs of the game against one another.<br />
As a loyal and faithful reader you will, of course, have realized that this is quite similar in nature to <a href="/2020/06/22/klobigb_overview.html">my initial game boy emulation article</a>, in that most of this post is focused on motivations, history and providing an overview, with only a very brief fragment of code at the end. Unlike that time, however, I do not restrict myself to publishing only selected snippets within an article but have already released the <a href="https://github.com/philipplenk/paulchen332">complete code for a working engine</a> into the wild. 
All of this sounds like kind of a huge undertaking, so before I lose your valuable attention, let’s dive right in.</p>

<div class="post_toc">
  <h4>Contents</h4>
  <blockquote>
<ul id="markdown-toc">
  <li><a href="#what-is-an-engine-anyway---a-brief-history" id="markdown-toc-what-is-an-engine-anyway---a-brief-history">What is an <em>engine</em> anyway? - A brief history</a>    <ul>
      <li><a href="#imagination" id="markdown-toc-imagination">Imagination</a></li>
      <li><a href="#reality" id="markdown-toc-reality">Reality</a></li>
      <li><a href="#dominance" id="markdown-toc-dominance">Dominance</a></li>
    </ul>
  </li>
  <li><a href="#why" id="markdown-toc-why">Why?</a></li>
  <li><a href="#introducing-" id="markdown-toc-introducing-">Introducing …</a></li>
  <li><a href="#how" id="markdown-toc-how">How?</a>    <ul>
      <li><a href="#overview" id="markdown-toc-overview">Overview</a></li>
      <li><a href="#uci" id="markdown-toc-uci">UCI</a></li>
    </ul>
  </li>
  <li><a href="#outlook" id="markdown-toc-outlook">Outlook</a></li>
</ul>

  </blockquote>
</div>

<h1 id="what-is-an-engine-anyway---a-brief-history">What is an <em>engine</em> anyway? - A brief history</h1>

<p>I will, from this point on, begin throwing a bit of jargon around, which might cause a minor amount of confusion. As confusion could lead to stress and nervous tension, which are now serious problems in all parts of the galaxy, I will attempt to not exacerbate this situation further by revealing at least some terminology in advance.</p>

<p>Contrary to popular opinion and willfully ignoring some popular applications of the word “engine”, I am not talking about cars, as those have rather little to do with chess and programming. Yes, they might be tangentially related, as self-driving cars are somewhat in vogue right now and also a topic of machine intelligence, but this connection is almost as tenuous as my interest in automobiles.<sup id="fnref:auto" role="doc-noteref"><a href="#fn:auto" class="footnote" rel="footnote">3</a></sup></p>

<p>In case the term is new to you, dear reader, allow me to clarify: When we use the phrase “chess engine” we quite simply refer to any program that is capable of playing a game of chess. You somehow feed it a representation of a given game state and it chooses a move it deems wise. That is all there is to it. Seems trivial, right?</p>

<h2 id="imagination">Imagination</h2>

<p>The idea of and desire for a program fulfilling this specification is indeed so blindingly obvious that it predates even the computers that could run it. In what is slowly but surely becoming sort of a theme in my articles - and not entirely unintentionally so - the basic concepts we rely on are, of course, based on work <a href="https://en.wikipedia.org/wiki/Alan_Turing">the great Alan Turing</a> and others did somewhen in the 1940s.</p>

<p>Actually, the history here goes back significantly further, centuries even if you allow for various ‘fake’ chess playing automaton regularly displayed to amaze, entertain and dazzle nobility as well as the general public, the most famous of which likely being <a href="https://en.wikipedia.org/wiki/The_Turk">the Mechanical Turk</a>.</p>

<p><img src="/images/mechanical_turk.jpg" alt="The Mechanical Turk" title="A copper engraving of the Mechanical 	Turk" class="centered-image" width="40%" /></p>

<p>This elaborate ‘machine’ was originally constructed by Wolfgang von Kempelen in 1770, toured throughout Europe, playing various illustrious celebrities in the process, was bought by Johann Nepomuk Mälzel in 1805, who exhibited it for another 33 years in even more areas - now including the United States, Canada and Cuba - only to eventually be lost to a fire in 1854.</p>

<p>Even so it turned out to be an elaborate hoax that managed to hide a skilled human operator within the devices seemingly complex interior, its mere existence and more than 60 year long reign during which it captivated the imagination of many an intellectual is quite telling. Consider, for a moment, the sentiment expressed by the great Penn Jillette <a href="https://www.youtube.com/watch?v=S3vTld5pNlI">in this short clip</a> when discussing a scene from the movie <a href="https://en.wikipedia.org/wiki/The_Prestige_(film)">The Prestige</a>:</p>

<blockquote>
  <p>[…]There is a sense that movies never get, where everything being done in a magic show has to be in some way plausible. […] If a trick is so perfect that there is only one way to do it, well than that is the way you did it.</p>
</blockquote>

<p>When you attend a magic show, you obviously know you will be fooled. Magicians happen to be the most honest liars you could possibly encounter, so they usually tell you upfront, directly or by implication, that what you will observe uses no supernatural powers, no divine intervention or other impossibilities, only lies, deception and trickery. If they do their job well, than despite your best efforts to see through it, regardless of your unwillingness, your disbelief is suspended. For a brief moment, in spite of all your knowledge and better judgment, you are left utterly dumbfounded, stunned, forced to question the very nature of your reality.<sup id="fnref:foolus" role="doc-noteref"><a href="#fn:foolus" class="footnote" rel="footnote">4</a></sup> Nonetheless, if the effect presented is too outlandish, too extreme, it dulls the wonder. Disappearing some huge public monument, to me, holds far less magnificence than an apparently simple card trick.</p>

<p>This rings even more true if you are trying to sell something as not a trick<sup id="fnref:morals" role="doc-noteref"><a href="#fn:morals" class="footnote" rel="footnote">5</a></sup>, which goes to show that automatically playing a game of chess must have, at the time, seemed fantastical, absolutely wondrous and almost entirely impossible. Almost. There was this tiny sliver of hope. What if it were actually possible? What if Mälzels Machine were in fact just that, a machine? What other feats of mechanical wonder would be possible? How much farther can technologies boundary be stretched?</p>

<p>It is precisely this atmosphere which is evident in the opening paragraphs of a <a href="https://en.wikisource.org/wiki/Maelzel%27s_Chess-Player">famous essay written by the illustrious Edgar Allen Poe and treating the subject matter of the Turk</a>. He describes the automaton as “an object of intense curiosity, to all persons who think”, some of which pronounced it “the most astonishing of the inventions of mankind” and compared it with the “calculating machine of Mr. Babbage” - described with clear reverence - claiming even it would be “altogether beneath it”, were it real.<sup id="fnref:babbage" role="doc-noteref"><a href="#fn:babbage" class="footnote" rel="footnote">6</a></sup>
He then proceeds to meticulously describe, analyze and dissect observations of the machines exhibitions and presumed workings to outline an argument for why he believed it to be an illusion and purported to reveal how said illusion was achieved.</p>

<p>Now, I absolutely adore Poes prose and whilst one could claim that especially <a href="https://en.wikisource.org/wiki/The_Masque_of_the_Red_Death">The Masque of the Red Death</a> was rather clairvoyant and bears eerie similarities to current events, not everything in this particular article has aged quite as well. Most of it is well reasoned and shows careful deliberation, yet a number of competing explanations are deemed obviously absurd, not meriting even a refutation, whilst the prospect of the machine being a true automaton, acting without human intervention and trickery, was deemed preposterous on the assumption that it was not playing perfectly enough. On the other hand, he asserted that the ability to play chess is in some way fundamentally different from computation, thereby both over- and severely underestimating technologies potential.</p>

<p>A pure and perfect fully autonomous chess machine was eventually constructed in 1912, almost a century after Poes essay. <a href="https://en.wikipedia.org/wiki/El_Ajedrecista">El Ajedrecista</a> did not play an arbitrary game from beginning to end, but restricted to one specific ending - two kings and one rook - it invariably managed to checkmate its opponent.
Just a few decades later, with the advent of general purpose computing, development accelerated significantly and complete - so not necessarily good - games played automatically were no longer constrained to mere fantasy. Effort from this point on, however, shifted more to the programs and algorithms used rather than mechanical contraptions controlled by it. Nonetheless, even in this regard, we have have come a long way. Some of the <a href="https://www.youtube.com/watch?v=AQLOj-TylGg">brilliant products</a> <a href="https://squareoffnow.com/product/gks">one could buy today</a><sup id="fnref:squareoff" role="doc-noteref"><a href="#fn:squareoff" class="footnote" rel="footnote">7</a></sup> certainly would have exceed even the vivid imagination of a brilliant writer like Poe, seeming so far beyond comprehension <a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/ClarkesThirdLaw">to be indistinguishable from real magic</a>.</p>

<p>The topic of early hoaxes and machines - as you can see - is rather extensive and cannot possibly be done justice in so small and puny a blogpost. There are some glaring omissions and much more fascinating details to be researched. Several books can and have been dedicated to the subject and some more could clearly be written, but are quite certainly out of scope for this article.<sup id="fnref:moxon" role="doc-noteref"><a href="#fn:moxon" class="footnote" rel="footnote">8</a></sup>
Which is why we return, once again, to Turing.</p>

<h2 id="reality">Reality</h2>

<p>In the early days, at a time when the field of computer science itself was still in its infancy and physical computers were playing catch up with the brilliant minds of their creators, B. V. Bowden set out to publish a small volume detailing the history, present and likely future of digital computers. Addressed at a general audience, <a href="https://archive.org/details/fasterthanthough00bvbo">Faster than thought</a> collected very accessible contributions by many eminent scientists of the era and is, even today, well worth a read in its entirety.</p>

<p>What I would like to draw your specific attention to right now, however, is <a href="https://docs.google.com/file/d/0B0xb4crOvCgTNmEtRXFBQUIxQWs/">a fascinating article submitted by Turing</a>. 
Not only did this rather short read break new ground by introducing a contender for the very first chess program, the explanations it contains are among the most lucid and illuminating I could find on the topic of game playing, with many of the concepts and ideas still relevant and in use today. In addition, this seminal paper can serve - not entirely unlike Poes treatise on the Turk above - as a wonderful lens by which to glean the perception of and attitude towards computing in those days, as I’d claim all writing, even technical and explanatory one, in some way reflects the society in which it is produced.</p>

<p>For instance, I mentioned earlier that with the rise of electronic computers effort shifted from machines to programs and a quick perusal of the paper will yield a concise explanation of why this might have been the case. After outlining the questions it seeks to answer, it contains this small gem justifying the approach taken:</p>

<blockquote>
  <p>“could one make a machine to…” might equally well be replaced by “could one programme an electronic computer to…”</p>
</blockquote>

<p>This alone serving as ample justification illustrates just how far public understanding had progressed. No longer was a game playing machine considered altogether above a mere calculator. On the contrary, it seemed almost self-evident that if it could be built at all, it could be expressed as a calculation. Computers were slowly starting to be recognized as the very epitome of machine.</p>

<p>To drive home this observation and emphasize the grand promise it held, please allow me to quickly point out two special questions listed at the papers beginning:</p>

<blockquote>
  <ul>
    <li>Could one make a machine which would answer questions put to it, in such a way that it would not be possible to distinguish its answers from that of a man?</li>
    <li>Could one make a machine which would have feelings like you and I do?</li>
  </ul>
</blockquote>

<p>Whilst Turing concedes these might not be <em>directly</em> related to the problem at hand - that of chess playing - he claims they are nonetheless connected and likely to be at the tip of the readers tongue.<sup id="fnref:turing_answer" role="doc-noteref"><a href="#fn:turing_answer" class="footnote" rel="footnote">9</a></sup> 
In this particular work - as well as in this post - such intriguing questions are merely raised, pondered very briefly and then brushed aside, as the author proceeds to prove the central claim: That a machine could be made to play a game of chess.</p>

<p>He does so by first describing clear, deterministic steps such a machine should take and then, lacking a computer capable of actually executing such a program, promptly does it himself.<sup id="fnref:reverse_turing" role="doc-noteref"><a href="#fn:reverse_turing" class="footnote" rel="footnote">10</a></sup>
The human imitating the hypothetical program later dubbed TuroChamp might have lost to a simple fork, but to my eyes, this does not make the achievement any less monumental. If there was even the shadow of a doubt left about the possibility, this game was more than sufficient to eradicate it. The stage was set for <em>real</em> engines to be created.</p>

<p>Turing himself later attempted to translate his descriptions into a working program, ambitions which were unfortunately left unfinished. <a href="https://en.wikipedia.org/wiki/Alan_Turing#Conviction_for_indecency">As his life was tragically cut short by a society too cruel and backwards to deserve him</a>, it was left for others to pick up the mantle and continue the work. The list of those who did reads almost like a who’s who of eminent computer science pioneers:  <a href="https://en.wikipedia.org/wiki/Claude_Shannon">Claude Shannon</a>, the man who introduced <a href="https://en.wikipedia.org/wiki/A_Mathematical_Theory_of_Communication">the term bit</a>, provided us with an <a href="https://en.wikipedia.org/wiki/Shannon_number">estimate of the games complexity</a> and <a href="https://www.chessprogramming.org/Claude_Shannon#Shannon.27s_Types">a useful classification of search algorithms</a>. <a href="https://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)">John McCarthy</a>, inventor of Lisp and garbage collection, proposed <a href="https://www.chessprogramming.org/Alpha-Beta">Alpha-Beta Pruning</a>. <a href="https://en.wikipedia.org/wiki/Donald_Knuth">Donald Knuth</a>, who really should not need an introduction among my readership, analyzed it in detail and in so doing formulated the notion of <a href="https://www.chessprogramming.org/Node_Types">the different node types</a>. <a href="https://en.wikipedia.org/wiki/Ken_Thompson">Ken Thompson</a>, well known for C, Go, Awk and myriad other miracles, contributed to <a href="https://www.chessprogramming.org/Belle">Belle</a> and was involved in the creation of the first <a href="https://en.wikipedia.org/wiki/Endgame_tablebase">endgame tablebase</a>.</p>

<p>This was but a small selection and I glossed over many a contribution, but you get the idea. What was fiction turned into solid theory, which turned into reality. Eventually, in 2012, even Turings original paper machine was <a href="https://en.chessbase.com/post/reconstructing-turing-s-paper-machine">finally constructed as a real, functional computer program</a> and managed to play what was described as a passable game against <a href="https://en.wikipedia.org/wiki/Garry_Kasparov">the great Garry Kasparov</a>, which it lost in 16 moves.<sup id="fnref:turochamp" role="doc-noteref"><a href="#fn:turochamp" class="footnote" rel="footnote">11</a></sup> That story might, for most of my readers, evoke some memories, as the name Kasparov is of course also inextricably linked with yet another famous and fateful human vs computer match…</p>

<h2 id="dominance">Dominance</h2>

<p>With playing a game of chess now not only a possibility but a reality, the discussion shifted again, to whether a program could play chess better than a human could. <a href="https://www.youtube.com/watch?v=ipRvjS7q1DI&amp;feature=youtu.be&amp;t=44">Not just any human so, it had to be the best of the best</a>.</p>

<p>You see, the battle for most of us was already lost very early on. Nonetheless, <a href="https://en.wikipedia.org/wiki/Hubert_Dreyfus%27s_views_on_artificial_intelligence#Reaction">when we hear a prominent AI critic first mocked chess computers for losing to a 10 year old, only to subsequently lose to a machine</a> in the 60s, it might be an amusing story, but it doesn’t really impress us much. After all, it is just the failure of one man and he - like most of us - was merely an amateur. As long as somewhere out there, there existed at least a single human being who could still reliably best the machines most of the time, we felt safe in our superiority. If one of us is better, we all could be. Humanity still reigns supreme.</p>

<p>It is fitting then, that when in 1997 IBM organized a much publicized match of its custom built <a href="https://en.wikipedia.org/wiki/Deep_Blue_(chess_computer)">Deep Blue</a> chess computer against Garry Kasparov, then incumbent world champion and seen by many to this day as the greatest chess player ever, Newsweek magazine not only <a href="https://www.newsweek.com/man-vs-machine-173038">ran a piece on it</a> but sported a cover adequately expressing the weight placed on one solitary humans shoulders:</p>

<p><img src="/images/newsweek_deep_blue.png" alt="&quot;The Brain's Last Stand&quot;" title="what to say?" class="centered-image" width="40%" /></p>

<p>Printed in the lead-up to what was to become a historic event, Kasparov was quoted as stating “This is much bigger than a world-championship match”. And indeed it was. The rather meager 500 seats available to watch live were sold out and millions throughout the world actively followed the games on IBMs website.<sup id="fnref:viewership" role="doc-noteref"><a href="#fn:viewership" class="footnote" rel="footnote">12</a></sup> This match was special. It was <em>not</em> just one man and he was the very opposite of an amateur. This man had not lost even a single match in his entire career. If the machine could beat him, it could beat everybody. He was humankinds champion. The brains last stand. And he lost.</p>

<p>Much has been written and said in the immediate aftermath of the event, mostly downplaying or elevating the scope of the achievement, revelling in either its significance or lack thereof. The match itself was riddled with controversy as the clash of business interests, a spirit of scientific inquiry and the chess players competitive personality gave rise to a battle fought almost as much away from the board as on it. When early on the machine did not play perfectly enough and decided on a move - later assumed to be caused by a simple bug - that seemed almost too human, Kasparov began to suspect foul play and grandmaster intervention, an accusation he hinted at in thinly veiled comments during a press conference. Coupled with the companies generally adversarial treatment of the world champion, like uncomfortable conditions in the playing hall, not providing any games to study his opponent and their inability to convincingly refute his accusations by providing logs, Kasparov grew enraged and convinced his opponents goal was to crush him, not by superior chess playing, but by any means necessary. Atypically for him, the grandmaster never quite managed to regain his composure.</p>

<p>So once victory came, it was not glorious. The triumphant team was not only booed but instructed to not smile, lest such reckless gloating could hurt stock prices. The machine was quickly dismantled and a rematch request denied. The grand winner proved to be not computer science, but IBM, whose value skyrocketed, whilst the consensus soon seemed to be that it wasn’t Deep Blue who won the match, it was Kasparov who lost it.</p>

<p>If one were to look for a pivotal point, there are a number of other candidates of arguably equal or maybe even greater technical importance, even so they were much less advertised outside of specialist communities: The first Deep Blue match, one year prior, contained the first game won by a chess computer against a reigning world champion, paving the way for the rematch and defeat in 1997. In 1998, <a href="https://www.rebel.nl/anand.htm">a match was held between Viswanathan Anand, then world number two and later world champion, and the commercially available chess engine Rebel running on consumer grade, not specially built, hardware</a> and was won by the machine. In 2002, Vladimir Kramnik, the man who eventually dethroned Kasparov, sparred with Deep Fritz in an event dubbed <a href="https://en.wikipedia.org/wiki/Brains_in_Bahrain">Brains in Bahrain</a> and despite being given several advantages only managed to score a draw.</p>

<p>Nevertheless, to the general public, this one fateful encounter in 1997 marked the end of an era, the public culmination of more than half a century of research, the last time any human could realistically hope to beat the best of the machines. The end of our dominance and the beginning of theirs.<sup id="fnref:deep_blue_more" role="doc-noteref"><a href="#fn:deep_blue_more" class="footnote" rel="footnote">13</a></sup></p>

<p>After the match, Kasparov continued to dominate the human chess world for a while, eventually retired into politics and became a fervent advocate <a href="https://www.amazon.com/Deep-Thinking-Machine-Intelligence-Creativity/dp/1473653517">for cooperating with machine intelligence to maximize both of our potential</a>.<br />
IBM, meanwhile has moved on to other ventures, but still sees the value of game playing for advertising progress. Not only has their <a href="https://en.wikipedia.org/wiki/Watson_(computer)">Watson system</a> defeated humans at <a href="https://en.wikipedia.org/wiki/Jeopardy!">Jeopardy!</a>, another system of theirs participated <a href="https://www.youtube.com/watch?v=3_yy0dnIc58">in a competitive debate</a>.<br />
Chess engines since have inexorably marched on and exploded in strength. When Kasparov, <a href="https://www.youtube.com/watch?v=8RVa0THWUWw&amp;feature=youtu.be&amp;t=1814">in more recent interviews</a>, points out that modern engines would laugh at the moves made by both him and Deep Blue and smartphones could easily crush IBMs monster, it is not only true but also <a href="https://www.reddit.com/r/chess/comments/76cwz4/15_years_of_chess_engine_development/">not only a statement about the progress in hardware</a>.</p>

<h1 id="why">Why?</h1>

<p>More could be said, but there is work to do and your time is valuable, which is why I shall end my history lesson at this point. I believe it is evident that at all times, since the very inception of computer science and even long before that, game playing was stretching and redefining what was considered possible with <em>mere</em> machines.</p>

<p>Which is all very interesting, yet why should I - or worse, even you dear reader - bother to replicate the brilliant work of others? This story is beautiful, but it clearly sounds as if it had already ended? Why push for yet another unnecessary and unsatisfying sequel? Haven’t we had enough of those lately?</p>

<p>The short answer is - as with pretty much all topics covered on this lovely blog of mine - because it is interesting, fun and educational. I really cannot stress this enough, so at the risk of repeating myself, allow me to stoop down to the level of <a href="https://en.wikipedia.org/wiki/Argument_from_authority">argument from authority</a>:<br />
With big companies, like IBM and Google, there are obviously economic interests and publicity at play, but that is not sufficient to explain the motivation of all the above mentioned outstanding individuals to spend time and energy on a problem which is ultimately no more than a pleasurable pastime. Apparently, an interest in game playing programs is - at least superficially - linked with an interest and excellence in computer science. What better method is there, than imitation, to truly grasp what it is that feels so fascinating, what drew in all those brilliant people to lay the foundations I and myriad others can now build on? <sup id="fnref:bragging_rights" role="doc-noteref"><a href="#fn:bragging_rights" class="footnote" rel="footnote">14</a></sup> There are giants on whose shoulders I stand, yet I fail to see as far as they did. I would love to change that.</p>

<p>“Well ok then”, I hear you concur, “but why chess? Why not Go? Why not Shogi?<sup id="fnref:shogi" role="doc-noteref"><a href="#fn:shogi" class="footnote" rel="footnote">15</a></sup> Why not <a href="https://en.wikipedia.org/wiki/Arimaa">Arimaa</a>?”. The reason here is twofold.</p>

<p>On one hand is obviously my personal love for chess. It already captivated me when I was taught to play the game by my stepfather in my early teens, but ever since me and a bunch of good friends<sup id="fnref:better" role="doc-noteref"><a href="#fn:better" class="footnote" rel="footnote">16</a></sup> managed to survive a particularly boring and tedious stretch of school by continuously playing behind our <em>“teachers”</em> backs it irreversibly managed to occupy a very special place in my heart.</p>

<p>On the other hand, the story is far from over. There is the occasional, <a href="https://en.wikipedia.org/wiki/Cobra_Kai">rare sequel that turns out to improve upon the original</a>. After it turned the world of Go upside down with <a href="https://en.wikipedia.org/wiki/AlphaGo">AlphaGo</a> 4 years ago, DeepMind continued to crush its own creation with <a href="https://en.wikipedia.org/wiki/AlphaGo_Zero">yet another devastating innovation</a>, which it promptly applied to chess to defeat the strongest engine to date. <a href="https://en.wikipedia.org/wiki/Leela_Chess_Zero">Leela</a>, the open source descendant of this experiment, continued to push chess engine development into less established and more innovative directions. Just a little more than a month ago, <a href="https://www.chess.com/news/view/stockfish-absorbs-nnue-100-elo">Stockfish(and various other top engines) absorbed NNUE</a>, an <a href="https://en.wikipedia.org/wiki/Efficiently_updatable_neural_network">evaluation technique originally developed for shogi</a> to gain a never before seen <a href="https://github.com/glinscott/fishtest/wiki/Regression-Tests">jump in playing strength</a>. Computer chess today is more vibrant and fast moving than ever before.</p>

<p>“Alright”, you concede, “but do you think me a fool?! I looked - as any diligent reader should - at the code you linked and it does not apply any of the wondrous things you mentioned. There is no NNUE! There is no <a href="https://en.wikipedia.org/wiki/Monte_Carlo_tree_search">MCTS</a>! Not a single neural network in sight, nothing special, just plain old alpha-beta and hand crafted evaluation functions! Justify yourself!”</p>

<p>Ok, you got me. I admit, I am not quite there yet. Even so I admire the progress made, I just can’t bring myself to like the methods used. Machine learning in general and neural networks in particular are far more useful than they have any right to be. Unfortunately, you can’t argue with results and <a href="https://en.wikipedia.org/wiki/GPT-3">GPT-3</a> has clearly taught us that quantity has a quality all its own. Nevertheless, the fields unnaturally successful approach of beating quality with quantity, processing power and energy just doesn’t ring right with me.</p>

<p><a href="https://en.wikiquote.org/wiki/John_von_Neumann">With four parameters I can fit an elephant, and with five I can make him wiggle his trunk.</a>. And with a few million we can win at chess, but what have we learned?<sup id="fnref:obligatory_xkcd" role="doc-noteref"><a href="#fn:obligatory_xkcd" class="footnote" rel="footnote">17</a></sup></p>

<p>Classic, hand crafted evaluation functions <a href="https://hxim.github.io/Stockfish-Evaluation-Guide/">can explain themselves</a>. Many parameters are, of course, found by automated tuning and it is hard or impossible to see why any particular one is right or wrong. Nonetheless, by inspecting how they turn out, I can learn something and gain understanding previously not available to me. By inspecting which weight is given to which feature of a given position, I myself should ideally be able to improve.</p>

<p>Neural network powered engines, on the other hand, are much closer to <a href="https://www.youtube.com/watch?v=fp7Pq7_tHsY&amp;feature=youtu.be&amp;t=1356">a real black box</a> and it is often impossible to understand the solutions they provide. No useful information can be gleaned from their output except the obvious: which move was chosen and how likely a specific outcome is believed to be. It is nice to know that the answer is 42, but without really knowing which questions we asked the only ones to really profit are pundits proclaiming to know what they cannot.</p>

<p>As such, at least for now, I shall keep my Pokemon Syndrome - wanting to be the very best - in check, stubbornly refuse to bow to the overwhelming power of the networks and try to see how far I can get without them. I am fully aware that my behavior is unnecessarily and unjustifiably prideful, whilst my understanding of what I am criticizing remains severely lacking. Yet, this is supposed to be fun and educational, so I shall do it my way, all shortcomings included.</p>

<h1 id="introducing-">Introducing …</h1>

<p>And so we - once again - arrive at a point in an article where I perform a sudden and abrupt turn and the tone switches from one of calm, dispassionate objectivity to overtly emotional and sentimental. You see, when introducing this topic I mentioned in passing and comically warped the slightly worn Newton quote about standing on the shoulders of giants. Well, here is one giant unlike any other on whose shoulders I stood, leaned and sat:</p>

<p><img src="/images/papa.png" alt="Engine Logo" title="My father" class="centered-image" width="40%" /></p>

<p>You are looking at a picture of my father<sup id="fnref:hand" role="doc-noteref"><a href="#fn:hand" class="footnote" rel="footnote">18</a></sup>, now 61 years of age. Or he would have been, had he not died suddenly and tragically slightly more than one year ago. There is so much more I have to thank him for than I could adequately express here and unfortunately more than I managed to express in his lifetime. Without his upbringing, his influence, I would not have developed the necessary patience, perseverance and confidence to complete and publish a work like this. As such I would like to dedicate the release to his memory. I have long struggled with naming my engine - we all know the adage about the two really hard problems in computer science: cache misses, naming and off by one errors - and for far too long a time my working title was the beautifully arrogant, self-centered and simplistic ‘philchess’. Now, if it were punny, I could accept that, it would be a good thing. Madchess is a brilliant name, I love it and Erik Madsen deserves all the credit he can get for his <a href="https://www.madchess.net/">helpful and wonderful blog</a>. But with my name, this just doesn’t work. Hence, I have now decided to baptize my engine <strong><em>paulchen332</em></strong>, reusing the online handle my father adopted eons ago. Allow me to introduce you:</p>

<p><img src="/images/pchess_logo.png" alt="Engine Logo" title="Isn't it lovely?" class="centered-image" width="40%" /></p>

<p>It might just be a tiny pawn now, but its aim is to be the very best, it just got serious - as you can see by the turned cap - and it needs just one small step to become the strongest there is.<sup id="fnref:2dpixx" role="doc-noteref"><a href="#fn:2dpixx" class="footnote" rel="footnote">19</a></sup> You can pay it a visit by heading over to <a href="https://github.com/philipplenk/paulchen332">github</a> ;-).<sup id="fnref:source_incomplete" role="doc-noteref"><a href="#fn:source_incomplete" class="footnote" rel="footnote">20</a></sup></p>

<h1 id="how">How?</h1>

<p>If you have read from the very beginning, dear reader, and managed to stay with me up to here, I would like to thank you for your incredible patience, commend your study of history and express my eternal gratitude. If you have not and simply skipped to here, I am most grateful for your interest in my work, glad you could join us and urge you to read on, as I finally begin to explain just how a chess playing program actually works.<sup id="fnref:favor" role="doc-noteref"><a href="#fn:favor" class="footnote" rel="footnote">21</a></sup></p>

<p>In my glorious introduction, I pointed out structural similarities this article shares with my <a href="/2020/06/22/klobigb_overview.html">first one about gameboy emulation</a>. The parallels do not stop at simply being structural so. Just like the work on my emulator, in the grand scheme of things, this is all rather insignificant and hardly innovative. What I have done and what I will write about is not exactly new. Others have done great jobs and I have not fundamentally reinvented the wheel. My implementations are, however, my own. I have put considerable thought into every detail, I have adjusted known algorithms to serve my own needs and I try my very best at providing the most accessible explanations possible. I hope and believe my perspectives and approach will be enlightening and of use to all of you, if only in part.</p>

<h2 id="overview">Overview</h2>

<p>On a very, very high level, I have already specified the requirements our program has to fulfill at the <a href="#imagination">beginning of our history section</a>. Allow me to reiterate this most complicated of descriptions with some much needed visual aid:</p>

<p><img src="/images/pchess_purpose.png" alt="Game State -&gt; Engine -&gt; Best Move" title="Simple?" class="centered-image" width="80%" /></p>

<p>That is really all there is to it. The details responsible for how we get there, however, might be a little more involved. Despite the wonderful illustration above, the task before us might still seem ever so slightly daunting and even you, my most lovely and intelligent readers, might be stumped as to where to start.</p>

<p>The problems already begin with the apparently simple input and output this construction demands, which I have left woefully underspecified. What exactly constitutes what I described as the “game state”? How is it conveyed? What does it mean for a move to be “the best”?</p>

<p>Answers to those questions are not exactly trivial and deserve at least one article each<sup id="fnref:future" role="doc-noteref"><a href="#fn:future" class="footnote" rel="footnote">22</a></sup>, but they can guide us. To help us get going at all, we can even simplify a little. For reasons I shall elaborate on in one of those future articles, which move is best cannot necessarily be determined with certainty in most positions. As such, if we were content with playing very, very badly, with the occasional brilliancy interspersed, simply choosing one move at random is perfectly sufficient.</p>

<p>This might seem significantly easier, yet when thinking about it for a few moments, we encounter another issue to be solved:</p>

<p><img src="/images/chess_invalid_move0.svg" alt="A nonsensical move" title="Bishops only move on diagonal" class="centered-image" width="40%" /></p>

<p>It is impossible to move from a1 to a3 here, as the piece on a1 is neither a rook nor a queen, but a bishop. Not all moves are possible at all times.</p>

<p>Further, not all moves which seem possible at a glance are necessarily legal:</p>

<p><img src="/images/chess_invalid_move1.svg" alt="An illegal move" title="We may not leave our king in check" class="centered-image" width="40%" /></p>

<p>Capturing with the pawn on h4 in this position would expose our king, which could subsequently be viciously slaughtered by a member of the clergy, something the rules do not allow.</p>

<p>There are multiple other intricacies and subtleties involved, mostly with castling and en passant. Which leaves us with the following conclusion: In order to determine which move we <em>should</em> play, we must first know which moves we <em>could</em> play.</p>

<p>This interesting problem, of determining legal moves for a given position, is called - unsurprisingly - <a href="https://www.chessprogramming.org/Move_Generation"><strong>move generation</strong></a> and is one of the most frequently employed parts inside a chess program. As such, it turns out to be a major target for optimization.<sup id="fnref:movegen" role="doc-noteref"><a href="#fn:movegen" class="footnote" rel="footnote">23</a></sup></p>

<p>The reason it has to be used so often is that we rarely look at a single position in isolation. It proves much more helpful to examine multiple potential future positions, and to reach any of those a chain of legal moves has to be followed. This process, determining which continuations to observe and from that drawing conclusions about which lines are most promising to pursue, is what we refer to - in grand tradition of obvious names - as the <a href="https://www.chessprogramming.org/Search"><strong>Search</strong></a>.</p>

<p>Search itself does, however, suffer from one major flaw. We should not - and cannot - follow every possible sequence of moves to its ultimate conclusion. At some point, we have to decide to terminate the search and guess how good or bad the thus chosen final position looks for either player. Occasionally, this is downright trivial:</p>

<p><img src="/images/chess_overwhelming_material.svg" alt="Overwhelming advantage" title="Which side is better?" class="centered-image" width="40%" /></p>

<p>Whilst there is no immediate mate to be seen, without even trying to find one most humans will, at but a cursory glance, recognize which side is winning here. Most other positions are ever so slightly more subtle so, which is why the quality of such <a href="https://www.chessprogramming.org/Evaluation"><strong>static evaluation</strong></a> plays a large role in determining an engines playing strength.</p>

<p>In order to execute all of those operations, we have to somehow keep a representation of our chessboard in memory and operate on it. This <a href="https://www.chessprogramming.org/Board_Representation"><strong>board representation</strong></a> should be carefully chosen to allow the most common operations to be executed as efficiently as possible.</p>

<p>And with that, we shall conclude our high level overview. I do hope this listing of major building blocks has proven somewhat illuminating and I managed to convey a general idea of how the parts interact. The post you are currently reading will, however, not explore them further, as I have thus far neglected one minor issue of paramount importance: how do we get our state to the engine and how does it report its move back?</p>

<h2 id="uci">UCI</h2>

<p>If all we desired were the minimal viable interface, it would be perfectly sufficient to simply input some arbitrary form of from-square/to-square pair on standard input and output the same. Unfortunately for us, most non professional humans are not particularly adept at or in favor of blind chess and manually keeping track on a real board is certainly more tedious than strictly necessary. As such, the majority of our users would be significantly more satisfied if we managed to place some form of graphical representation resembling a physical board in front of them and allowed them to act on it.</p>

<p>Such a thing is certainly both possible and interesting. Implementing a beautiful and intuitive user interface poses fascinating challenges which can only help us grow as developers, yet those challenges are very different and quite far removed from the one we are actually attempting to solve. We could easily end up being too distracted to get the core parts into working order any time soon.</p>

<p>Furthermore, lovely pictures being the only way to interact with our program would render playing other machines annoyingly difficult. Interfaces created for humans are often notoriously hard for machines to process and vice versa, so tying our code too closely to one particular participant will necessarily inconvenience the other.<sup id="fnref:cars_again" role="doc-noteref"><a href="#fn:cars_again" class="footnote" rel="footnote">24</a></sup></p>

<p>Luckily for us, others recognized this way before I even started considering writing an engine of my own and have taken measures to solve it. You see, dear reader, I have not been completely upfront with you earlier. Or at least, I have simplified a little, as it is not entirely accurate to refer to just any chess playing program as an engine. If it had a built in GUI, it would be more than that. The reason we use the term <em>engine</em> is because the thus described program might be central and drive the machine, but is usually not used on its own. To take full advantage of it, we do not execute it directly but in conjunction with a third party program, like the wonderful and incredibly useful <a href="https://github.com/cutechess/cutechess">Cutechess</a>, which can invoke one or multiple engines in the background and mediate between them and us pesky humans.</p>

<p>To avoid duplicated and repetitive effort, it proved beneficial for most programs to agree on how exactly to talk to the outside world. This way complete decoupling is achieved and anyone can write a user interface that can talk to any engine following the protocol. Conversely, all an engine author has to do is implement the protocol and users are free to chose their favorite GUI to play against it. There are two popular such communication protocols to choose from, <a href="https://www.chessprogramming.org/Chess_Engine_Communication_Protocol">CECP</a> and <a href="https://www.chessprogramming.org/UCI">UCI</a>.</p>

<p>For reasons which are not entirely rational and shall as such remain unmentioned, I decided on UCI. The exact details for all supported commands are specified <a href="http://download.shredderchess.com/div/uci.zip">here</a> and I shall not bore you by repeating each and every one of them. Instead, I’ll just explain how it works in the most general terms and illustrate with some hopefully well chosen examples how I went about integrating the processing of UCI commands in my code. If you are interested in more, you can always check out <a href="https://github.com/philipplenk/paulchen332/tree/main/include/philchess/uci">the complete source code</a>.</p>

<p>To begin examining how the protocol works, let’s have a quick look at a typical session:</p>

<noscript><a href="https://asciinema.org/a/gkqumLPEpJnsA41hFDmVksaOo" target="_blank"><img src="https://asciinema.org/a/gkqumLPEpJnsA41hFDmVksaOo.svg" /></a></noscript>
<script id="asciicast-gkqumLPEpJnsA41hFDmVksaOo" src="https://asciinema.org/a/gkqumLPEpJnsA41hFDmVksaOo.js" async></script>

<p>As you can see, all communication is done via standard input and output of text commands, one line each. Communication is initiated by a simple “uci” and terminated with the intuitive “quit”. Other commands might have a varying number of optional arguments attached. An interesting property with large implications on possible implementations can be observed in the second call to go. During processing, before the search is completed and a result returned, another command - “stop” - is entered, causing the search to terminate prematurely. To put it in the words of the official documentation:  “the engine must always be able to process input from stdin, even while thinking”.</p>

<p>Before continuing, I would like to offer a word of advice to my dear readers: The details which follow cannot be explained generically, so I shall assume some familarity with the C++ programming language and, lacking that, following my explanations might be neither easy nor valuable. If, at any point, you feel overwhelmed, feel free to <a href="#outlook">skip to the end</a>.</p>

<p>Brief intermissions aside, postponing the problem of parallelism for a moment and assuming we had an engine class with appropriate member functions, connecting those to a command line interface becomes downright trivial:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">ENGINE_T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">IO_T</span><span class="p">,</span> <span class="k">typename</span> <span class="o">...</span><span class="nc">ARGS_T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="nf">run_cli</span><span class="p">(</span><span class="n">IO_T</span> <span class="n">io</span><span class="p">,</span> <span class="n">ARGS_T</span><span class="o">&amp;&amp;</span><span class="p">...</span> <span class="n">args</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">ENGINE_T</span> <span class="n">engine</span><span class="p">{</span><span class="n">io</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">forward</span><span class="o">&lt;</span><span class="n">ARGS_T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="p">)...};</span>
	
	<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="o">::</span><span class="n">string_view_literals</span><span class="p">;</span>
	<span class="k">using</span> <span class="n">command_handler_t</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">add_pointer_t</span><span class="o">&lt;</span><span class="kt">void</span><span class="p">(</span><span class="n">ENGINE_T</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">istringstream</span><span class="o">&amp;</span><span class="p">)</span><span class="o">&gt;</span><span class="p">;</span>
	
	<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">command_map</span><span class="o">=</span><span class="n">ptl</span><span class="o">::</span><span class="n">make_fixed_flatmap</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string_view</span><span class="p">,</span> <span class="n">command_handler_t</span><span class="o">&gt;</span><span class="p">(</span>
	<span class="p">{</span>
		<span class="p">{</span> <span class="s">"uci"</span><span class="n">sv</span><span class="p">,</span>			<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">uci</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"debug"</span><span class="n">sv</span><span class="p">,</span>		<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">debug</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"isready"</span><span class="n">sv</span><span class="p">,</span>		<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">isready</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"setoption"</span><span class="n">sv</span><span class="p">,</span>	<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">setoption</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"register"</span><span class="n">sv</span><span class="p">,</span>		<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">do_register</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"ucinewgame"</span><span class="n">sv</span><span class="p">,</span>	<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">ucinewgame</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"position"</span><span class="n">sv</span><span class="p">,</span>		<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">position</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"go"</span><span class="n">sv</span><span class="p">,</span>			<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">go</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"stop"</span><span class="n">sv</span><span class="p">,</span>			<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">stop</span><span class="o">&gt;</span> <span class="p">},</span>
		<span class="p">{</span> <span class="s">"ponderhit"</span><span class="n">sv</span><span class="p">,</span>	<span class="n">detail</span><span class="o">::</span><span class="n">call_helper_v</span><span class="o">&lt;&amp;</span><span class="n">ENGINE_T</span><span class="o">::</span><span class="n">ponderhit</span><span class="o">&gt;</span> <span class="p">},</span>
	<span class="p">});</span>
	
	<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">line</span><span class="p">,</span> <span class="n">cmd</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(;;)</span>
	<span class="p">{</span>
		<span class="n">line</span><span class="o">=</span><span class="n">io</span><span class="p">.</span><span class="n">input</span><span class="p">();</span>
		<span class="n">std</span><span class="o">::</span><span class="n">istringstream</span> <span class="n">stream</span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
		<span class="n">stream</span><span class="o">&gt;&gt;</span><span class="n">cmd</span><span class="p">;</span>
		
		<span class="k">if</span><span class="p">(</span><span class="n">cmd</span><span class="o">==</span><span class="s">"quit"</span><span class="n">sv</span><span class="p">)</span>
			<span class="k">break</span><span class="p">;</span>
		
		<span class="k">if</span><span class="p">(</span><span class="k">auto</span> <span class="n">it</span><span class="o">=</span><span class="n">command_map</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">cmd</span><span class="p">);</span> <span class="n">it</span><span class="o">!=</span><span class="n">command_map</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
			<span class="n">it</span><span class="o">-&gt;</span><span class="n">second</span><span class="p">(</span><span class="n">engine</span><span class="p">,</span><span class="n">stream</span><span class="p">);</span>
		<span class="k">else</span>
			<span class="n">io</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="s">"Unknown command '"</span><span class="p">,</span><span class="n">cmd</span><span class="p">,</span><span class="s">"' ;_;"</span><span class="p">);</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre>
</figure>

<p>To the uninitiated, it might look like there is a lot going on here, but it is really not. About half of the code is only concerned with constructing an object of the engine class with the passed arguments and defining a simple map providing one function pointer for each command. Afterwards it simply loops, repeatedly reading one line of input and decomposing it into its first word and the rest. The <a href="https://en.cppreference.com/w/cpp/io/basic_istringstream">stringstream</a> conveniently skips over any leading and trailing whitespace, which is another requirement of the UCI protocol. A quit command ends our processing, any other one is searched for in the map. If found, the relevant function pointer is invoked, passing the engine object and the stringstream containing the rest of the line. I’d claim the most interesting parts are those very function pointers and how we get them, so let’s examine that in some more detail.</p>

<p>They are apparently some sort of variable template named <em>detail::call_helper_v</em> instantiated with a member function pointer.<sup id="fnref:register" role="doc-noteref"><a href="#fn:register" class="footnote" rel="footnote">25</a></sup> Here it is:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="k">auto</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">call_helper</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">C</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">R</span><span class="p">,</span> <span class="k">typename</span><span class="o">...</span> <span class="nc">ARG_T</span><span class="p">,</span> <span class="n">R</span><span class="p">(</span><span class="n">C</span><span class="o">::*</span><span class="n">memfun</span><span class="p">)(</span><span class="n">ARG_T</span><span class="p">...)&gt;</span>
<span class="k">class</span> <span class="nc">call_helper</span><span class="o">&lt;</span><span class="n">memfun</span><span class="o">&gt;</span>
<span class="p">{</span>
	<span class="nl">public:</span>
	<span class="k">static</span> <span class="kt">void</span> <span class="n">call</span><span class="p">(</span><span class="n">C</span><span class="o">&amp;</span> <span class="n">handler</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">istringstream</span><span class="o">&amp;</span> <span class="n">data</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">call_impl</span><span class="p">(</span><span class="n">handler</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">index_sequence_for</span><span class="o">&lt;</span><span class="n">ARG_T</span><span class="p">...</span><span class="o">&gt;</span><span class="p">{});</span>
	<span class="p">}</span>
	
	<span class="k">private</span><span class="o">:</span>
	<span class="k">template</span> <span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="p">...</span><span class="n">IDX</span><span class="p">&gt;</span>
	<span class="k">static</span> <span class="kt">void</span> <span class="nf">call_impl</span><span class="p">(</span><span class="n">C</span><span class="o">&amp;</span> <span class="n">handler</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">istringstream</span><span class="o">&amp;</span> <span class="n">data</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">index_sequence</span><span class="o">&lt;</span><span class="n">IDX</span><span class="p">...</span><span class="o">&gt;</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">decay_t</span><span class="o">&lt;</span><span class="n">ARG_T</span><span class="o">&gt;</span><span class="p">...</span><span class="o">&gt;</span> <span class="n">args</span><span class="p">;</span>
		<span class="p">((</span><span class="n">data</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="n">IDX</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="p">)),...);</span>
		
		<span class="p">(</span><span class="n">handler</span><span class="p">.</span><span class="o">*</span><span class="n">memfun</span><span class="p">)(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="n">IDX</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="p">))...);</span>
	<span class="p">}</span>
<span class="p">};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">auto</span> <span class="n">v</span><span class="p">&gt;</span>
<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">call_helper_v</span> <span class="o">=</span> <span class="n">call_helper</span><span class="o">&lt;</span><span class="n">v</span><span class="o">&gt;::</span><span class="n">call</span><span class="p">;</span></code></pre>
</figure>

<p>Now this might be a bit harder to swallow for casual C++ users, but please bear with me for a little longer. To get this out of the way first, what the code actually accomplishes is simple: it extracts arguments of the appropriate type from the stringstream (which holds the rest of the input line) and calls the dedicated member function. So our goal here is for a member function like <em>void gun(int a, const float&amp;b)</em> to be invocable with the command line “gun 42 3.14” and do the right thing. With this preamble, allow me to describe how the code above manages to accomplish just that.</p>

<p>The variable template <em>call_helper_v</em> at the end would not be necessary and exists just as a convenience to save us from repeatedly typing <em>::call</em> at the site of usage, whilst the real work is done by the class template declaration above. It expects a <a href="https://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter">non-type template parameter</a> of arbitrary allowed type, but is only specialized for member function pointers. The purpose of this somewhat convoluted construction is to get at the argument types expected by said member function, which are now available as the parameter pack <em>ARG_T</em>. So if we had a simple class like this:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">struct</span> <span class="nc">fun</span>
<span class="p">{</span>
	<span class="kt">void</span> <span class="n">gun</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="kt">float</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">);</span> 
<span class="p">};</span></code></pre>
</figure>

<p>and instantiated the template as</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">call_helper</span><span class="o">&lt;&amp;</span><span class="n">fun</span><span class="o">::</span><span class="n">gun</span><span class="o">&gt;</span><span class="p">;</span></code></pre>
</figure>

<p>C would equal fun (our class), R would be void (our return type) and ARG_T would be &lt;int,const float&amp;&gt; (the argument types). This allows us to define a <a href="https://en.cppreference.com/w/cpp/utility/tuple">std::tuple</a> capable of holding variables for storing all argument values, regardless of which combination the member function expects. In the running example, <em>args</em> would be a <em>std::tuple&lt;int,float&gt;</em>. Notice that I dropped the const qualifier and reference, a job done in the code by <a href="https://en.cppreference.com/w/cpp/types/decay">std::decay</a>. Our function might expect a reference, but this reference must have something to refer to, which is the tuple element we store.</p>

<p>Now that we have our variables - one for each function argument - we utilize the normal, potentially overloaded, <a href="https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt">operator»</a> to extract values from our input line into those variables. So the code we would want our template to generate ought to look something like this:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">data</span><span class="o">&gt;&gt;</span><span class="n">first_argument</span><span class="p">;</span>
<span class="n">data</span><span class="o">&gt;&gt;</span><span class="n">second_argument</span><span class="p">;</span>
<span class="c1">//...</span></code></pre>
</figure>

<p>As the variables are stored as members of a std::tuple, we have to utilize <a href="https://en.cppreference.com/w/cpp/utility/tuple/get">std::get</a> to use them:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">data</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="n">tuple</span><span class="p">);</span>
<span class="n">data</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;</span><span class="p">(</span><span class="n">tuple</span><span class="p">);</span>
<span class="c1">//...</span></code></pre>
</figure>

<p>This looks, to the untrained eye, suspiciously close to the most basic use case of a simplistic for loop. And indeed it would be, if “0” and “1” above were function arguments, not non-type template parameters. As it stands, the following code we would like to write will unfortunately fail to compile:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">i</span><span class="o">&lt;</span><span class="k">sizeof</span><span class="p">...(</span><span class="n">ARG_T</span><span class="p">);</span><span class="o">++</span><span class="n">i</span><span class="p">)</span>
	<span class="n">data</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="n">i</span><span class="o">&gt;</span><span class="p">(</span><span class="n">tuple</span><span class="p">);</span></code></pre>
</figure>

<p>Lacking a constexpr variation of for, we have to resort to more functional methods to achieve the same result. This is why the private function template with a <a href="https://en.cppreference.com/w/cpp/utility/integer_sequence">std::index_sequence</a> argument is needed. <em>std::index_sequence_for&lt;int,const float&amp;&gt;</em> will yield a std::index_sequence&lt;0,1&gt;, and passing this as a parameter to the call_impl will deduce &lt;0,1&gt; as the IDX pack, exactly the values our for loop would have iterated over. With this pack we can, at compile time, employ a <a href="https://en.cppreference.com/w/cpp/language/fold">fold expression</a> to generate the calls to std::get we so desired:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="p">((</span><span class="n">data</span><span class="o">&gt;&gt;</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="n">IDX</span><span class="o">&gt;</span><span class="p">(</span><span class="n">args</span><span class="p">)),...);</span></code></pre>
</figure>

<p>We then employ the same “trick” to generate an argument list for the function call and our work is done. Slightly more complicated arguments, like chess positions as <a href="https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation">FEN strings</a> or similar are cleanly delegated to dedicated <a href="https://github.com/philipplenk/paulchen332/blob/main/include/philchess/uci/types.hpp">types and overloads for stream extraction</a>.</p>

<p>Which leaves only two problems we shall now try to solve in tandem: one of tight coupling and the one of parallelism already mentioned above: Preferably we would like to have most of our engine code isolated from all this protocol madness. Maybe one day I will realize the errors of my ways, see the light and convert to CECP? If so, do I really want to change huge parts of my code? Maybe one day, in a bout of utter madness, I will suddenly decide that it could be a cute idea to replicate Turochamp for modern GUIs? If so, would I really want to duplicate all the UCI specific member functions which are rather tedious and independent?<sup id="fnref:past_turo" role="doc-noteref"><a href="#fn:past_turo" class="footnote" rel="footnote">26</a></sup> Furthermore, the core engine code does not only have to be isolated structurally but also in execution, as it must run concurrently with command processing.</p>

<p>How do we solve this, you ask? With yet another level of indirection of course! We wrap our engine in another class providing the required interface<sup id="fnref:facade" role="doc-noteref"><a href="#fn:facade" class="footnote" rel="footnote">27</a></sup> and safely executing engine functionality in a dedicated thread. Here is the declaration:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">ENGINE_T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">IO_T</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">wrapper</span>
<span class="p">{</span>
	<span class="nl">public:</span>
	<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span><span class="o">...</span> <span class="nc">ARGS</span><span class="p">&gt;</span>
	<span class="n">wrapper</span><span class="p">(</span><span class="n">IO_T</span> <span class="n">io</span><span class="p">,</span> <span class="n">ARGS</span><span class="o">&amp;&amp;</span> <span class="p">...</span><span class="n">args</span><span class="p">);</span>
	
	<span class="o">~</span><span class="n">wrapper</span><span class="p">();</span>
	
	<span class="kt">void</span> <span class="n">uci</span><span class="p">();</span>
	
	<span class="kt">void</span> <span class="n">debug</span><span class="p">(</span><span class="n">debug_setting</span> <span class="n">setting</span><span class="p">);</span>
	
	<span class="c1">//[...] one function for each UCI command </span>
		
	<span class="nl">private:</span>
	<span class="n">IO_T</span> <span class="n">io_</span><span class="p">;</span>
	<span class="n">pcl</span><span class="o">::</span><span class="n">monitor</span><span class="o">&lt;</span><span class="n">ENGINE_T</span><span class="o">&gt;</span> <span class="n">engine_</span><span class="p">;</span>
		
	<span class="n">std</span><span class="o">::</span><span class="kr">thread</span> <span class="n">worker_thd_</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="n">atomic</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span> <span class="n">should_stop_</span><span class="p">;</span>
	<span class="n">pcl</span><span class="o">::</span><span class="n">locked_queue</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">function</span><span class="o">&lt;</span><span class="kt">bool</span><span class="p">()</span><span class="o">&gt;&gt;</span> <span class="n">task_queue_</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>I omitted most UCI functions for the sake of brevity, but the general idea should be reasonably easy to grasp. This wrapper template requires an engine type and a type to handle input/output and stores an instance of each of these as a member variable. The engine is stored in a <a href="https://en.wikipedia.org/wiki/Monitor_(synchronization)">monitor</a>, which simply pairs it with a <a href="https://en.cppreference.com/w/cpp/thread/mutex">std::mutex</a> and ensures it can only be accessed when a lock is held. Further, it holds a thread responsible for doing all the real work, hence its name, and a simple thread safe queue to communicate with that thread. <em>should_stop_</em> is passed to the engines search function to potentially notify it of interruption.</p>

<p>The worker thread itself is incredibly simple:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="n">worker_thd_</span><span class="p">{[</span><span class="k">this</span><span class="p">]()</span>
<span class="p">{</span>
	<span class="k">for</span><span class="p">(;;)</span>
	<span class="p">{</span>
		<span class="k">auto</span> <span class="n">fun</span><span class="o">=</span><span class="n">task_queue_</span><span class="p">.</span><span class="n">wait_and_pop</span><span class="p">();</span>
		<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">fun</span><span class="p">())</span>
			<span class="k">break</span><span class="p">;</span>
	<span class="p">}</span>
<span class="p">}},</span></code></pre>
</figure>

<p>It simply loops, waits until it can pull something from the queue, executes whatever function it finds there and quits the loop and thread if this function call returns false.<sup id="fnref:bool_return" role="doc-noteref"><a href="#fn:bool_return" class="footnote" rel="footnote">28</a></sup> The queue is filled when certain UCI commands are triggered, for instance:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">ENGINE_T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">IO_T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="n">wrapper</span><span class="o">&lt;</span><span class="n">ENGINE_T</span><span class="p">,</span> <span class="n">IO_T</span><span class="o">&gt;::</span><span class="n">position</span><span class="p">(</span><span class="n">board_position</span> <span class="n">pos</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">should_stop_</span><span class="o">=</span><span class="nb">true</span><span class="p">;</span>
	<span class="n">task_queue_</span><span class="p">.</span><span class="n">push</span><span class="p">([</span><span class="k">this</span><span class="p">,</span><span class="n">pos</span><span class="o">=::</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">pos</span><span class="p">)]()</span>
	<span class="p">{</span>
		<span class="n">engine_</span><span class="p">([</span><span class="o">&amp;</span><span class="p">](</span><span class="n">ENGINE_T</span><span class="o">&amp;</span> <span class="n">engine</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">engine</span><span class="p">.</span><span class="n">setup</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">fen</span><span class="p">);</span>
			<span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="n">m</span><span class="o">:</span><span class="n">pos</span><span class="p">.</span><span class="n">moves</span><span class="p">)</span>
				<span class="n">engine</span><span class="p">.</span><span class="n">do_move</span><span class="p">(</span><span class="n">m</span><span class="p">);</span>
		<span class="p">});</span>
		<span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
	<span class="p">});</span>
<span class="p">}</span></code></pre>
</figure>

<p>Other commands are entirely independent and do not even interact with the worker thread:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">ENGINE_T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">IO_T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="n">wrapper</span><span class="o">&lt;</span><span class="n">ENGINE_T</span><span class="p">,</span> <span class="n">IO_T</span><span class="o">&gt;::</span><span class="n">isready</span><span class="p">()</span>
<span class="p">{</span>
	<span class="n">io_</span><span class="p">.</span><span class="n">output</span><span class="p">(</span><span class="s">"readyok"</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</figure>

<p>As always, check out <a href="https://github.com/philipplenk/paulchen332/blob/main/include/philchess/uci/wrapper.hpp">the source code</a> for all details and feel free to ask for clarifications or teach me the inevitable shortcomings of my design.</p>

<h1 id="outlook">Outlook</h1>

<p>Once again, allow me to quickly recap what we have done:</p>

<p>I have taken you on a whirlwind tour of history to explain how we got to having the great abundance of amazingly strong chess playing programs we have today. In so doing I hopefully managed to wet your appetite to start working on your own engine or at the very least care tangentially about mine. To help you along in that journey, I have <a href="https://github.com/philipplenk/paulchen332">published my code</a> and begun the process of explaining it, first at a high level, then in some detail for a selected small but essential part. More details will follow in subsequent articles. With my next post in this series, I plan to cover board representations and the trade-offs involved.</p>

<p>As usual, I tried to mention and acknowledge as many sources of inspiration and motivation as I possibly could, but there is little doubt in my mind that I missed some. If so, you can trust it was ineptitude, not ill intent. I am a firm believer in <a href="https://en.wikipedia.org/wiki/Hanlon%27s_razor">Hanlon’s razor</a> and like to apply it to myself as well as others. If there is any particular sin of omission you, dear reader, feel I have committed, pray tell me in the comments below and I will try to amend this post.</p>

<p>If you wish to leave constructive feedback, any other thoughts or even praises for me and your fellow readers to find, I am happy to accept those, too. If you feel strongly about anything I wrote and would like to educate me on how irresponsibly uneducated I am, I welcome your insults and threats of violence. The opposite of love is not hate, but indifference. As such, I am delighted about any and all interaction and am looking forward to responses of any kind ;-)</p>

<hr />
<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:briefly" role="doc-endnote">
      <p>whom am I kidding at this point, really? <a href="#fnref:briefly" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:skip" role="doc-endnote">
      <p>or simply skipped it. If you are not interested in my random ruminations and just want to get down to details, you can jump ahead to <a href="#how">“How?”</a>, it does not really depend on what came before. <a href="#fnref:skip" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:auto" role="doc-endnote">
      <p>for which I might even harbor a certain disdain. Hardly noticeable in my writing… <a href="#fnref:auto" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:foolus" role="doc-endnote">
      <p>Hell, there is even <a href="https://en.wikipedia.org/wiki/Penn_%26_Teller:_Fool_Us">an entire show based on the premise of concealing and guessing the methods used</a> and I freaking love it. The child like joy and occasionally anger Penn&amp;Teller display when fooled is almost as fascinating to watch as the dedication, ingenuity and creativity of the presenting magicians themselves. <a href="#fnref:foolus" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:morals" role="doc-endnote">
      <p>the moral implications of doing so might warrant another, longer and more thorough discussion. I belief it’s pretty reprehensible so. <a href="#fnref:morals" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:babbage" role="doc-endnote">
      <p>Judging by the release date of the article, I assume this must have referred to <a href="https://en.wikipedia.org/wiki/Difference_engine">the Difference Engine</a>, not the more general <a href="https://en.wikipedia.org/wiki/Analytical_engine">Analytical Engine</a> which is considered to be one of the first <a href="https://en.wikipedia.org/wiki/Turing-complete">Turing Complete</a> designs. <a href="#fnref:babbage" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:squareoff" role="doc-endnote">
      <p>and which I would love to own. <a href="#fnref:squareoff" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:moxon" role="doc-endnote">
      <p>The influence all of this had on fiction is quite fascinating. <a href="https://en.wikisource.org/wiki/Moxon%27s_Master">Moxon’s Master</a>, for instance, contains descriptions which seem clearly inspired by the Turk and might be the first depiction of a robot in english language literature. <a href="#fnref:moxon" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:turing_answer" role="doc-endnote">
      <p>In case you are wondering: The first is answered in the affirmative, whilst the second is deemed unknowable. <a href="https://docs.google.com/file/d/0B0xb4crOvCgTNmEtRXFBQUIxQWs/">Just read the paper ;-)</a> <a href="#fnref:turing_answer" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:reverse_turing" role="doc-endnote">
      <p>Somewhat ironically, he technically failed at this sort-of reverse <a href="https://en.wikipedia.org/wiki/Turing_test">Turing Test</a> by introducing some miscalculations. <a href="#fnref:reverse_turing" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:turochamp" role="doc-endnote">
      <p>It was also <a href="https://github.com/philipplenk/paulchen332/blob/main/tests/turochamp.cpp">reconstructed by yours truly</a>, just for this post and the fun of it xD. Interestingly, my version produces the same amount of deviations as the <a href="https://en.chessbase.com/post/reconstructing-turing-s-paper-machine">chessbase one</a>, but different ones, so I guess I might have misunderstood something fundamental. I do, however, believe part of their analysis is wrong, as at one point they mention “The black pawn on e5 has disappeared, and with it the bonus for the two rows it had advanced (+0.4 for White).”, whereas Turings paper only mentioned “each white piece […] and the black king”. I therefore believe the position of black pawns was not taken into account for computing the position-play value. I am also not entirely sure their interpretation of Turings quiescence search is accurate. They write “captures had to be followed up at least to the point where no further capture was immediately possible”, but the paper machine has a notion of standing pat. The value of a position was supposed to be the greatest of “the positions obtained by considerable moves” or “the position itself evaluated as if a dead position”. <a href="#fnref:turochamp" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:viewership" role="doc-endnote">
      <p><a href="https://www.ibm.com/ibm/history/ibm100/us/en/icons/deepblue/">IBM itself writes of more than three billion impressions</a> <a href="#fnref:viewership" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:deep_blue_more" role="doc-endnote">
      <p>This fascinating story is, of course, as all the other parts of this historical overview, far too interesting and extensive to be covered exhaustively in so small a post. As such, I would like to invite my dear readers to dig deeper. To give you some hints as to where you could start, I’d like to point out, that there is <a href="https://en.wikipedia.org/wiki/Game_Over:_Kasparov_and_the_Machine">a documentary featuring Kasparov himself</a> which rather obviously hints at the suspicions of foul play. I also recently watched <a href="https://www.youtube.com/watch?v=HwF229U2ba8">a much more nuanced, detailed and fair treatment of the whole affair on Youtube</a>. And <a href="https://www.scientificamerican.com/article/20-years-after-deep-blue-how-ai-has-advanced-since-conquering-chess/">here</a> is a fairly recent interview with one member of the Deep Blue team. Oh, and once you are done with all that, I warmly recommend <a href="https://www.youtube.com/watch?v=zhkTHkIZJEc">this conversation</a> between Kasparov and <a href="https://en.wikipedia.org/wiki/Demis_Hassabis">Demis Hassabis</a> of <a href="https://www.youtube.com/watch?v=WXuK6gekU1Y">AlphaGo</a> fame. In general, the story of AlphaGo shares some truly striking parallels and some notable differences which are well worth investigating. <a href="#fnref:deep_blue_more" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:bragging_rights" role="doc-endnote">
      <p>Additionally, Turing, in his paper cited above, claimed that the better a program, “the more ingenious perhaps the designer”. Being indirectly praised by the father of computer science himself should earn at least some minor bragging rights, wouldn’t you agree? <a href="#fnref:bragging_rights" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:shogi" role="doc-endnote">
      <p>I have, in fact, started and abandoned writing a shogi program a really long time ago. I am a little sad that plan never really came to fruition, so I might try again someday. <a href="#fnref:shogi" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:better" role="doc-endnote">
      <p>All of whom are by now far better players than I could hope to be. <a href="#fnref:better" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:obligatory_xkcd" role="doc-endnote">
      <p>Here is <a href="https://xkcd.com/1838/">the obligatory xkcd comic making my point</a>. <a href="#fnref:obligatory_xkcd" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:hand" role="doc-endnote">
      <p>The hand on his shoulder and the hair on the side are mine, in case you are wondering. <a href="#fnref:hand" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2dpixx" role="doc-endnote">
      <p>This brilliant logo was graciously provided by <a href="http://www.2dpixx.de/">the wonderful Jana Ochse</a>. <a href="#fnref:2dpixx" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:source_incomplete" role="doc-endnote">
      <p>You might, upon perusing the source code, realize that a large part of the evaluation function consists of huge, arbitrary looking tables with numbers lacking any explanation. Those have, of course, been arrived by automatic tuning, but the code responsible for this optimization (as well as a huge number of tests) is not included in the published repository yet. The reason is trivial, as this code suffers one major flaw: It is embarrassingly ugly. I shall eventually publish it, in conjunction with articles explaining its working, once I found the time to clean it up a little. <a href="#fnref:source_incomplete" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:favor" role="doc-endnote">
      <p>So, if you wish to do me a favor, dear friend, I would be much obliged if you could quickly jump up <a href="#introducing-">just one section</a>. <a href="#fnref:favor" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:future" role="doc-endnote">
      <p>which they will get ;-) <a href="#fnref:future" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:movegen" role="doc-endnote">
      <p>Interestingly, move generation was glossed over completely in the Turing paper. I presume this was because it is so well defined a problem to seem trivial in theory. Legal moves follow directly from the games rules, which are unambiguous and almost boring. In practice, however, this is one of the much harder things to get completely right. Even Deep Blue seems to have had some bugs in that regard. <a href="#fnref:movegen" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:cars_again" role="doc-endnote">
      <p>Most of the difficulties with self driving cars stem from this. If we had specially built roads and no signs desiged for the human eye, I dare say it wouldn’t even pose much of a challenge. <a href="#fnref:cars_again" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:register" role="doc-endnote">
      <p>The most astute of you might have realized, that one of those is not like the other. All but one of the member functions are named exactly like to command they represent. <em>register</em> had to deviate from that rule, as <a href="https://en.cppreference.com/w/cpp/keyword/register">it is a keyword</a>. <a href="#fnref:register" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:past_turo" role="doc-endnote">
      <p>Oh wait, that already happened… <a href="#fnref:past_turo" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:facade" role="doc-endnote">
      <p>Which is basically <a href="https://en.wikipedia.org/wiki/Facade_pattern">the facade pattern</a>. <a href="#fnref:facade" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:bool_return" role="doc-endnote">
      <p>In retrospect, I have to admit this is a little unclear. The interpretation of boolean return values is not always obvious and it might be better to return some simple enum class value and check for something like <em>task_queue::end_processing</em>. <a href="#fnref:bool_return" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Hannah Lenk</name><email>hannah.lenk@codemetas.de</email></author><category term="c++" /><category term="chess" /><category term="paulchen332" /><summary type="html"><![CDATA[Welcome back - or so I hope - for yet another exciting installment of the grand, illustrious and ultimately pointless epic of “What have I wasted my freetime on in recent years”. This time around, I shall tell you about the royal game, i.e. chess, or rather of my humble attempts at contributing to its rich ecosystem of non-human players.]]></summary></entry><entry><title type="html">A plea for order</title><link href="http://localhost:4000/2020/07/15/A-plea-for-order.html" rel="alternate" type="text/html" title="A plea for order" /><published>2020-07-15T01:24:23+02:00</published><updated>2020-07-15T01:24:23+02:00</updated><id>http://localhost:4000/2020/07/15/A%20plea%20for%20order</id><content type="html" xml:base="http://localhost:4000/2020/07/15/A-plea-for-order.html"><![CDATA[<p><em>I know I promised to talk more about emulation, about chess and operating systems, but I have to get something off of my chest first. This is not going to be one of my would-be grand and elongated epics trying to cover far too much in far too many words. Instead, I shall focus on one very small, very self contained thing: the order of #include directives in C++ source code<sup id="fnref:easy" role="doc-noteref"><a href="#fn:easy" class="footnote" rel="footnote">1</a></sup></em></p>

<p>If you know me or happen to have read <a href="/about.html">my about page</a> or <a href="/2020/05/16/why.html">the beautifully self-centered explanation of why this blog exists</a>, you might know that I tend to think what is great for me is also beneficial for others. As such, I <del>force</del> strongly encourage my friends to regularly engage in recreational programming. A few days ago, one particularly ambitious <del>victim</del> student of mine asked for assistance in tracking down a bug. Upon perusing the file sent to me, I was treated to this gem of questionable beauty:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">&lt;sys/types.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;sys/socket.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;netinet/in.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;arpa/inet.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;unistd.h&gt;</span><span class="cp">
</span>
<span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;fstream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;array&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;thread&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;atomic&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;mutex&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;queue&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;chrono&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;ctime&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;unistd.h&gt;</span><span class="cp">
</span>
<span class="cp">#include</span> <span class="cpf">"mySocket.hpp"</span><span class="cp">
#include</span> <span class="cpf">"user.hpp"</span><span class="cp">
#include</span> <span class="cpf">"messages_tools.hpp"</span><span class="cp">
</span><span class="c1">//[...]</span></code></pre>
</figure>

<p>The <em>real</em> code was alright and the bug source located easily enough, but this minor abomination painfully reminded me of an irksome issue too rarely addressed.<br />
It is not an isolated incident either, but rather somewhat of a pet peeve of mine I am confronted with quite frequently. Here is an excerpt of some code I had to work on as part of my last project as a TA at university:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">&lt;cmath&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;assert.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;chrono&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;fstream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;chrono&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;math.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
</span>
<span class="cp">#include</span> <span class="cpf">&lt;scai/dmemo/Distribution.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;scai/dmemo/HaloExchangePlan.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;scai/dmemo/Distribution.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;scai/dmemo/BlockDistribution.hpp&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;scai/dmemo/GenBlockDistribution.hpp&gt;</span><span class="cp">
</span>
<span class="cp">#include</span> <span class="cpf">"PrioQueue.h"</span><span class="cp">
#include</span> <span class="cpf">"MultiLevel.h"</span><span class="cp">
#include</span> <span class="cpf">"Settings.h"</span><span class="cp">
</span><span class="c1">//[...]</span></code></pre>
</figure>

<p>Having read this far<sup id="fnref:thanks" role="doc-noteref"><a href="#fn:thanks" class="footnote" rel="footnote">2</a></sup>, you might be wondering, what it is I am so agitated about? Where and what exactly is my problem? Is there a bug in this simple list of includes? Can there be?<br />
Well, the fact that you are even considering the option kind of makes my point for me. Nonetheless, the answer is no. There is no clear “bug” here. Both examples compiled fine and showed no problems directly related to the fragments shown. What I am so concerned about is largely stylistic, cosmetic even. It is not about correctness. Not immediately so.</p>

<p>In case I wasn’t exactly clear about it, allow me to spell it out explicitly. I am thoroughly annoyed by the lack of any discernible structure. The order the directives appear in is a jumbled mess so incoherent to leave any viewer confused as to what is actually used by the code and at a complete loss when trying to determine if a required header for potentially new additions is already included. The authors themselves fell prey to that already: My friend included <em>unistd.h</em> twice, whilst the university code contains a duplicate directive for <em>chrono</em> and conflicting variations of <em>math.h</em> and <em>cmath</em>.</p>

<p>I think we can all agree that the situation described above could be improved. The two pressing questions remaining are: should it be and if so, how exactly can we go about doing so? Is it worth whatever minuscule amount of extra effort some order would require? Judging by the title of this article and the ever so slightly strong language used to express my grievance you might have guessed my personal opinion on the matter, but even I admit there are at least two reasonable objections:</p>

<ol>
  <li>
    <p>Why are you even talking about #include in 2020? This is the decade of modules and modules instantaneously solve all problems simple headers ever caused.</p>
  </li>
  <li>
    <p>Stop being such a petty killjoy! What does it matter if some files are included twice? Just let every developer add the headers they need once a compiler complains, be done with it and spend your precious time on the <em>real</em> problems, writing <em>real</em> code, not insignificant include directives…</p>
  </li>
</ol>

<p>At least they seem reasonable on a surface level. Please allow me to dismantle and destroy them.<sup id="fnref:strawman" role="doc-noteref"><a href="#fn:strawman" class="footnote" rel="footnote">3</a></sup></p>

<h1 id="modules-cant-save-us">Modules can’t save us</h1>

<p>Let’s address modules first. <a href="https://en.cppreference.com/w/cpp/language/modules">Modules</a> are one of the 4 really <em>big</em> and greatly anticipated features we finally got with the new C++20 standard.<sup id="fnref:features" role="doc-noteref"><a href="#fn:features" class="footnote" rel="footnote">4</a></sup> 
They promise to at long last get us a little bit further out of the macro infested mess C originally got us in. Don’t get me wrong, I love the C programming language. Its simplicity, elegance and practicality are unmatched, and were even more so at the time of its inception. In <a href="https://en.wikiquote.org/wiki/Bjarne_Stroustrup">Stroustrups grand taxonomy of programming languages</a> of those everyone complains about and those no one uses, C clearly falls within the former category.<sup id="fnref:cvscpp" role="doc-noteref"><a href="#fn:cvscpp" class="footnote" rel="footnote">5</a></sup> Nonetheless, existing and striving for backwards compatibility for so long - <a href="https://en.wikipedia.org/wiki/The_C_Programming_Language">the famous K&amp;R book</a> was published in 78, 42 years ago - is bound to accrue some <a href="https://en.wikipedia.org/wiki/Technical_debt">technical debt</a>.</p>

<p>I believe its somewhat simplistic model of separate compilation and the dumb, mindless textural substitution used to stitch together translation units from various source and header files can be considered such debt and its about time we payed up and moved on. It was perfectly sufficient at the time, but in modern environments and at modern scale, we can and should be doing better. The high level design goals of modules include better isolation, better encapsulation and better interfaces and I’d like to think the design converged on after more than 15 years managed to achieve them. I wont be going into any detail how they work and can be used for three simple reasons: It is not exactly on topic, as is usual, others have done an <a href="https://stackoverflow.com/questions/22693950/what-exactly-are-c-modules">amazing job</a> <a href="https://vector-of-bool.github.io/2019/03/10/modules-1.html">explaining this</a> already, both <a href="http://www.modernescpp.com/index.php/cpp20-modules">in writing</a> and in <a href="https://www.youtube.com/watch?v=Kqo-jIq4V3I">great</a> <a href="https://www.youtube.com/watch?v=yee9i2rUF3s">talks</a>, and my own knowledge and experience is cursory at best.</p>

<p>I further believe I am not entirely alone in not being an expert on the topic. The design was <a href="https://vector-of-bool.github.io/2019/01/27/modules-doa.html">somewhat contentious</a> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1103r3.pdf">not entirely insignificant changes</a> were made in the later phases of its standardization. As such, experimentation and general adoption is hindered by one more minor issue. Have a look at this <a href="https://en.cppreference.com/w/cpp/compiler_support">great overview of compiler and library support for all the myriad C++ features of newer standard revisions.</a> At the time of writing it contains the following relevant column:</p>

<p><img src="/images/cpp20_module_support.png" alt="Modules implementations are not shipped with gcc at all and only partial in clang and msvc" title="Quite amazing how much is implemented and available so" class="centered-image" width="80%" /></p>

<p>Apparently none of the big three compilers - gcc, clang and msvc - ship with complete modules support yet. The speed of adoption has significantly grown since C++11, but even with near perfect implementations, newer standards are not as prevalent as some fanatics like me would like them to be. Judging by some <a href="https://www.youtube.com/watch?v=ZckduPcuvDs">interesting survey results</a> it does not seem to be an exaggeration to claim that approximately half of all C++ developers do not even use C++17 yet. Baselessly extrapolating from that data, it might well be another 5 - 10 years until a majority of programmers and companies use <em>some</em> C++20 in all of their codebases. It will most certainly take even longer to completely transition away from headers and transform or replace all legacy code. And even if this happens - which is somewhat doubtful - we are still left with C compatibility. Their importance may be reduced significantly, but headers are here to stay.</p>

<p>So no, whilst modules are generally great, solve many a problem and were desperately needed, they do not save us here. All of my concerns will remain valid for some time to come and some - like readability and clarity of intention - would matter even in a hypothetical and really really far away modules-only world.</p>

<h1 id="style-matters">Style matters</h1>

<p>In the meantime, we have to deal with includes and might as well do it with some structure. Or should we not care, do just what we absolutely must and be done with it? This second objection I promised to address can actually be construed as two different views of differing extremes: Should we not care about style in general or is this one specific instance just too insignificant? The first is trivially easy to debunk, the second one might prove a little more involved. As such, lets jump right in so I won’t lose your precious attention before my actual call to action.</p>

<p>There is <a href="https://stackoverflow.com/questions/876089/who-wrote-this-programing-saying-always-code-as-if-the-guy-who-ends-up-maintai">this famous saying in programming circles</a>, that one should always write code as if the person who has to maintain it in the future is a violent psychopath who knows where you live. Considering I tend to maintain my own code, at least one part is true and my sense of orientation is notoriously lacking.</p>

<p>Yet, why should we fear this person? Which properties in our code could trigger their rage and for what possible reasons? Well, another adage that complements the previous perfectly states the important fact, that code is far more frequently read than written. If you don’t finish your project in one sitting - and its a rare one that can be finished in so short a time - or if you happen to collaborate with someone else, whatever you wrote has to be parsed and understood, its intentions, methodology and implications gleaned as quick and frictionless as possible. You don’t just write for a compiler, you write for humans.</p>

<p>This can’t be stressed enough. We tend to eschew goto, for example, not because it itself is fundamentally flawed, but because we are. It inhibits our ability to reason about control flow, to be certain about which pieces of code are executed in which sequence and which might be skipped entirely.<sup id="fnref:goto" role="doc-noteref"><a href="#fn:goto" class="footnote" rel="footnote">6</a></sup> The compiler has no such issue. It doesn’t care. We do.<br />
In the same vein, we preach to carefully choose self-explanatory identifiers not because it is necessary, but because it aids readability and serves as a design aid. When we can’t clearly name a thing, we might have to rethink what and if it should be. Again: The compiler doesn’t care, it might even throw away the result of our hard work. Yet, I challenge you to try and guess what the following function does and should do:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">int</span> <span class="nf">z</span><span class="p">(</span><span class="kt">int</span> <span class="n">_</span><span class="p">){</span><span class="k">return</span> <span class="n">_</span><span class="o">&lt;</span><span class="mi">2</span><span class="o">?</span><span class="mi">1</span><span class="o">:</span><span class="p">(</span><span class="n">z</span><span class="p">(</span><span class="n">_</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">z</span><span class="p">(</span><span class="n">_</span><span class="o">-</span><span class="mi">2</span><span class="p">));}</span></code></pre>
</figure>

<p>I trust all of my dear readers can figure that one out eventually. Nonetheless, you have to admit it was not exactly self evident and you had to actively engage in dissecting and thinking about it. Contrast that experience with the following, absolutely identical fragment:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="kt">int</span> <span class="nf">fibonacci</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">n</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">)</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
	<span class="k">return</span> <span class="n">fibonacci</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">fibonacci</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">);</span>
<span class="p">}</span></code></pre>
</figure>

<p>At but one glance, without even reading the second line, you are aware of what it <em>should</em> do. As the intent is clear, subsequently your attention will not be spent on guessing and mechanics, but checking <em>how</em> the task is accomplished. With a tiny bit of domain knowledge, you might even spot the error. <a href="https://www.youtube.com/watch?v=hErD6WGqPlA">Or know a multitude of better solutions.</a></p>

<p>And that, my friends, is the crux of the matter. Lack of stylistic concern is not itself a bug, but the cause of many. Style is never about just being - for some nebulous definition - pleasant to look at, but about being clear, reducing cognitive load and allowing the reader to focus on what is essential, making every character count. Code is written for humans and <a href="https://medium.com/@egonelbre/psychology-of-code-readability-d23b1ff1258a">humans have limitations</a>. Taking this into account leads to clear, readable expression of ideas. Neglecting it leads to misunderstandings and confusion. Good style fosters elegant, correct and efficient code. Bad style facilitates errors. 
Pasta is tasty, but I much prefer penne to <a href="https://en.wikipedia.org/wiki/Spaghetti_code">spaghetti</a>.</p>

<h1 id="include-matters">#include matters<sup id="fnref:hashinclude" role="doc-noteref"><a href="#fn:hashinclude" class="footnote" rel="footnote">7</a></sup></h1>

<p>The generalized argument is quite obvious and I believe few would dare to disagree. I might, however, be in the minority in caring so deeply about this one specific issue.
As a community, we routinely teach the importance of naming, <a href="https://howardhinnant.github.io/classdecl.html">worry about whether private or public parts should appear first in a class declaration</a> and debate the merits of east const and <a href="https://www.youtube.com/watch?v=_27NHB1OlNI">the correct one</a>, yet when it comes to include directives, order is often sorely neglected.</p>

<p>Whilst <a href="https://blog.kowalczyk.info/article/qg/order-of-include-headers-in-cc.html">some</a> <a href="https://www.ostricher.com/2014/11/sort-your-include-files/">articles</a> <a href="https://blog.knatten.org/2010/07/01/the-order-of-include-directives-matter/">about</a> <a href="https://medium.com/software-design/rules-for-managing-header-file-includes-in-c-d7bbc7f500ee">the topic</a> seem to have been written over the years, those are few and far between. The newest I could find is from 2017 and none of them explain their motivation and reasoning in as much excessive detail as I’d deem adequate.<sup id="fnref:missed" role="doc-noteref"><a href="#fn:missed" class="footnote" rel="footnote">8</a></sup></p>

<p>The wonderful and official <a href="https://isocpp.github.io/CppCoreGuidelines/">C++ Core Guidelines</a> have some rules for how to deal with header files and set some goals to strive after I completely agree with, but readability and ease of getting an overview of what is or isn’t used are notably absent. They even contain - at the time of writing - <a href="https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rs-include-order">the following example</a> as a <em>good</em> one:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;algorithm&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="c1">// ... my code here ...</span></code></pre>
</figure>

<p>Granted, the point illustrated here is a different one, but what thought process has gone into including vector before algorithm before string? I suspect none at all. With those three and in a simple self contained example that is perfectly fine, but just as C++ developers as a group seem to have converged on using pre-increment whenever there is no reason to use the somewhat more powerful post-increment and consider it premature pessimization to do otherwise, I believe not structuring includes from the get go should be considered a premature pessimization for readability. It really doesn’t take much effort and prevents problems down the line.</p>

<p>I absolutely mean what I wrote there, it can cause real problems. As stated in the previous section when advocating for style in general, everything that might confuse is already detrimental, but it is more serious than that. 
The problem here lies not simply in what is, but what could be and the fear and uncertainty this instills in collaborators.<sup id="fnref:self" role="doc-noteref"><a href="#fn:self" class="footnote" rel="footnote">9</a></sup> It is not entirely unheard of that <a href="https://www.glfw.org/docs/3.3/quick.html#quick_include">some libraries require a certain order</a>. Reasons can vary.</p>

<p>Some - like the linked - simply have to deal with <a href="https://www.reddit.com/r/opengl/comments/1sumg2/why_does_the_order_of_my_opengl_includes_matter/">a configuration macro infested mess</a>.</p>

<p>Sometimes and even more insidious, the meaning of code can subtly and silently change based on what is declared first. Have a look at this simplified example:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="kt">void</span> <span class="nf">gun</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"double</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">gun</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"int</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">fun</span><span class="p">()</span>
<span class="p">{</span>
	<span class="n">gun</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
	<span class="n">fun</span><span class="p">();</span>
	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>
<div style="display:flex; justify-content:space-between; align-items:center; border-bottom: 1px solid black">
<a href="/code/decl_order0.cpp">Simple?</a> <a href="https://godbolt.org/clientstate/CnsKICAic2Vzc2lvbnMiOiBbCiAgICB7CiAgICAgICJpZCI6IDEsCiAgICAg ICJsYW5ndWFnZSI6ICJjKysiLAogICAgICAic291cmNlIjogIiNpbmNsdWRl IDxpb3N0cmVhbT5cblxudm9pZCBndW4oZG91YmxlKVxue1xuXHRzdGQ6OmNv dXQ8PFwiZG91YmxlXFxuXCI7XG59XG5cbnZvaWQgZ3VuKGludClcbntcblx0 c3RkOjpjb3V0PDxcImludFxcblwiO1xufVxuXG52b2lkIGZ1bigpXG57XG5c dGd1big0Mik7XG59XG5cbmludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2 W10pXG57XG5cdGZ1bigpO1xuXHRyZXR1cm4gMDtcbn1cbiIsCiAgICAgICJj b21waWxlcnMiOiBbCiAgICAgICAgewogICAgICAgICAgImlkIjogImNsYW5n X3RydW5rIiwKICAgICAgICAgICJvcHRpb25zIjogIi1PMyIKICAgICAgICB9 CiAgICAgIF0sCiAgICAgICJleGVjdXRvcnMiOiBbCiAgICAgICAgewogICAg ICAgICAgImFyZ3VtZW50cyI6ICIiLAogICAgICAgICAgImNvbXBpbGVyIjog ewogICAgICAgICAgICAgICJpZCI6ICJjbGFuZ190cnVuayIsCiAgICAgICAg ICAgICAgImxpYnMiOiBbXSwKICAgICAgICAgICAgICAib3B0aW9ucyI6ICIt TzMiCiAgICAgICAgICB9LAogICAgICAgICAgInN0ZGluIjogIiIKICAgICAg ICB9CiAgICAgIF0KICAgIH0KICBdCn0K "><img class="svg-logo-link" src="/assets/compiler_explorer_logo.svg" /></a>
</div>
</p>

<p>Let’s ignore for a moment that I exemplified precisely the horrid naming I criticized before and analyze what exactly is happening here. In main we simply call a function appropriately named <em>fun</em>. This in turn calls a function even more appropriately named <em>gun</em>, passes the value 42 and this is where things get interesting. <a href="https://en.cppreference.com/w/cpp/language/lookup">Name lookup</a> is performed to get a set of candidate functions, which yields - in our case - the two variations of <em>gun</em>, one expecting a double, the other one an int. After this, <a href="https://en.cppreference.com/w/cpp/language/overload_resolution">overload resolution</a> kicks in, selects the int version as a better candidate and our program dutifully prints “int”. Pretty simple, right?<sup id="fnref:ct" role="doc-noteref"><a href="#fn:ct" class="footnote" rel="footnote">10</a></sup> Too simple even, so let’s switch things up a little:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span>
<span class="kt">void</span> <span class="nf">gun</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"double</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">fun</span><span class="p">()</span>
<span class="p">{</span>
	<span class="n">gun</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">gun</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="o">&lt;&lt;</span><span class="s">"int</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
	<span class="n">fun</span><span class="p">();</span>
	<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>
<div style="display:flex; justify-content:space-between; align-items:center; border-bottom: 1px solid black">
<a href="/code/decl_order1.cpp">Still?</a> <a href="https://godbolt.org/clientstate/CnsKICAic2Vzc2lvbnMiOiBbCiAgICB7CiAgICAgICJpZCI6IDEsCiAgICAg ICJsYW5ndWFnZSI6ICJjKysiLAogICAgICAic291cmNlIjogIiNpbmNsdWRl IDxpb3N0cmVhbT5cblxudm9pZCBndW4oZG91YmxlKVxue1xuXHRzdGQ6OmNv dXQ8PFwiZG91YmxlXFxuXCI7XG59XG5cbnZvaWQgZnVuKClcbntcblx0Z3Vu KDQyKTtcbn1cblxudm9pZCBndW4oaW50KVxue1xuXHRzdGQ6OmNvdXQ8PFwi aW50XFxuXCI7XG59XG5cbmludCBtYWluKGludCBhcmdjLCBjaGFyKiBhcmd2 W10pXG57XG5cdGZ1bigpO1xuXHRyZXR1cm4gMDtcbn1cbiIsCiAgICAgICJj b21waWxlcnMiOiBbCiAgICAgICAgewogICAgICAgICAgImlkIjogImNsYW5n X3RydW5rIiwKICAgICAgICAgICJvcHRpb25zIjogIi1PMyIKICAgICAgICB9 CiAgICAgIF0sCiAgICAgICJleGVjdXRvcnMiOiBbCiAgICAgICAgewogICAg ICAgICAgImFyZ3VtZW50cyI6ICIiLAogICAgICAgICAgImNvbXBpbGVyIjog ewogICAgICAgICAgICAgICJpZCI6ICJjbGFuZ190cnVuayIsCiAgICAgICAg ICAgICAgImxpYnMiOiBbXSwKICAgICAgICAgICAgICAib3B0aW9ucyI6ICIt TzMiCiAgICAgICAgICB9LAogICAgICAgICAgInN0ZGluIjogIiIKICAgICAg ICB9CiAgICAgIF0KICAgIH0KICBdCn0K "><img class="svg-logo-link" src="/assets/compiler_explorer_logo.svg" /></a>
</div>
</p>

<p>All I did was swap the positions of fun and the second version of gun. Which is exactly the same as would happen if both were defined inline inside different header files and we swapped the include order. This might seem harmless, but the meaning of our program just changed. When executed, it will - somewhat surprisingly - output “double”. When collecting candidate functions for firing the gun, the second, better fitting version is not yet known and <a href="https://en.cppreference.com/w/cpp/language/implicit_conversion">due to dreaded implicit conversions</a> no problem is detected with using the first.</p>

<p>I admit, this concrete example is unlikely to occur in practice. Nonetheless, it showcases a type of problem that can realistically happen and causes me to feel queasy whenever I see an ordering I fail to understand. Just as you, dear reader, when I suggested in strong words that there might be a problem in the introductory examples, I am left to guess the authors intentions. Was there willful negligence or a brilliant scheme beyond my comprehension?</p>

<p>The most frequent “errors” I observed, however, are simple hidden dependencies which just so happen to be satisfied transitively. Once more, allow me to demonstrate:</p>

<p>A.hpp:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#ifndef A_H
#define A_H
</span>
<span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="nf">meaningless</span><span class="p">();</span>

<span class="cp">#endif</span></code></pre>
</figure>

<p>A.cpp:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">"A.hpp"</span><span class="cp">
</span>
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">str</span><span class="o">=</span><span class="s">"Hi"</span><span class="p">;</span>

<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="nf">meaningless</span><span class="p">()</span>
<span class="p">{</span>
	<span class="k">return</span> <span class="n">str</span><span class="p">.</span><span class="n">c_str</span><span class="p">();</span>
<span class="p">}</span></code></pre>
</figure>

<p>B.hpp:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#ifndef B_H
#define B_H
</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="nf">example</span><span class="p">();</span>

<span class="cp">#endif</span></code></pre>
</figure>

<p>B.cpp:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">"A.hpp"</span><span class="cp">
#include</span> <span class="cpf">"B.hpp"</span><span class="cp">
</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="nf">example</span><span class="p">()</span>
<span class="p">{</span>
	<span class="k">return</span> <span class="n">meaningless</span><span class="p">()</span><span class="o">+</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">{</span><span class="s">" dear reader!"</span><span class="p">};</span>
<span class="p">}</span></code></pre>
</figure>

<p>Again, not the most realistic of examples, but brief and illustrative of a larger issue. What happens if, say, the author of A realizes the ridiculousness of the <em>meaningless</em> implementation and changes it to no longer unnecessarily construct a std::string:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include</span> <span class="cpf">"A.hpp"</span><span class="cp">
</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="nf">meaningless</span><span class="p">()</span>
<span class="p">{</span>
	<span class="k">return</span> <span class="s">"Hi"</span><span class="p">;</span>
<span class="p">}</span></code></pre>
</figure>

<p>Diligently, the header is also changed to no longer include &lt;string&gt;.<br />
<strong>B breaks!</strong><br />
B.cpp will now fail to compile not because anything it did changed, not because anything it directly used changed, but because one of its dependencies changed its implementation. Not its interface, just the implementation. Needless to say, this is very bad. Among all the dangers listed above, it is luckily also the one most easily avoided. Whilst we cannot guarantee no third party code ever falls into this trap, some simple rules can reduce the risk of suffering from it and prevent us from imposing such burden on our own users. To understand how, let’s first reiterate what exactly went wrong:</p>

<ul>
  <li>The author of A exposed an implementation detail - its use of std::string - in the corresponding header file.</li>
  <li>The author of B fell into <a href="https://www.hyrumslaw.com/">Hyrum’s Law</a> and unwittingly relied on this private detail.</li>
</ul>

<p>Both parties could have done better.</p>

<ul>
  <li>The author of A could have prevented the issue appearing at all by being explicit and distinguishing between which dependencies are required to use the provided functionality and which are simply implementation details and might change. As such, the include directive should have been in the A.cpp file, not the header.</li>
  <li>The author of B could have detected the issue earlier by including its own header first. This would have triggered a compiler error, as B.hpp is not self-sufficient and does not include everything it uses. Subsequently changing B.hpp to ensure B.cpp compiles breaks the implicit dependency.</li>
</ul>

<p>In conclusion: I think I have shown that even if there were no technical downsides at all, a lack of order does still cause some cognitive overhead. It either gives your reader something to think about that might be of no consequence and simply distracting or it encourages them to completely skip over a section of your file, causing you to convey less useful information than you could have. You squandered an opportunity to be explicit about what your dependencies are, obscured your intent and failed to ensure that whoever works with your files next can feel confident in any modifications and additions.</p>

<h1 id="so-what">So what?</h1>

<p>With all this I hopefully managed to convince you that some rudimentary rules can be beneficial. Which is, once again, where we arrive at an impasse.
Just as with project organization in general - so there have recently been some <a href="https://api.csswg.org/bikeshed/?force=1&amp;url=https://raw.githubusercontent.com/vector-of-bool/pitchfork/develop/data/spec.bs">commendable and valiant efforts</a> - there is no one, official, all encompassing standard way to handle this ordering. Regardless, we don’t have to be entirely subjective and can be informed by the concerns addressed above. As such, I would like to outline which guidelines I have adopted in my own personal projects as well as the underlying reasoning, in the hope that proves of some use and inspiration for my dear readers.</p>

<p>In order to identify what is good or bad and construct a generally useful and coherent ruleset we must first agree on some goals to strife after. On a high level, I trust the following two will not be controversial:</p>

<ul>
  <li>Minimize errors</li>
  <li>Maximize clarity</li>
</ul>

<p>From the possible problems described combined with these criteria, we can deduce the following instructions:</p>

<ol start="0">
  <li>Be self sufficient, include everything you rely on.</li>
  <li>Be minimal, include only what is required.</li>
  <li>In a cpp file, first include the corresponding header.</li>
  <li>After this, organize headers in interrelated groups - based on projects or libraries - and list those in reverse order of potential dependencies. E.g. first list everything belonging to the same project, followed by other libraries used, followed by almost-standard libraries like boost, followed by the C++ standard library, followed by the C standard library.</li>
  <li>Order the group members themselves alphabetically.</li>
</ol>

<p>I’d be remiss to omit, that whilst I do like to think I came up with those rules on my own, they turn out to be not entirely original. Far more experienced and knowledgeable people <a href="https://stackoverflow.com/questions/614302/c-header-order">seem to have arrived</a> at <a href="https://stackoverflow.com/questions/2762568/c-c-include-header-file-order">pretty much the same set</a>. I don’t think that is a downside but rather consider it a confirmation of my reasoning. The result appears to follow logically from the stated criteria.</p>

<p>I already kind of touched on it in the previous section, but the one possible error we can deal with is hidden dependencies. Rules 0 and 1 should help us eliminate them and rules 2 and 3 serve as a sort of sanity check to ensure we detect violations quickly.</p>

<p>To maximize clarity, we want to enable a human to quickly discover what is needed and glean as much useful information as possible with a cursory glance. Rule 0 forces us to be explicit about our dependencies instead of relying on implicit support and expectations. Rule 1 guarantees that whatever is mentioned is relevant. The grouping allows a quick scan to reveal which larger sets of libraries are depended on and the alphabetical order helps to quickly determine the presence or absence of any particular include.</p>

<h1 id="a-plea">A plea</h1>

<p>With this, I shall finally come to an end and fear I might owe you an apology. I promised this would be short and as the more perceptive of you might have noticed I failed to keep that promise. Let’s just claim <a href="https://en.wikiquote.org/wiki/Blaise_Pascal">I lacked the time</a>, thank you for sticking with me.</p>

<p>I do hope it has been useful. As I repeatedly elaborated on those points in excruciating detail in private conversation and was at one point so annoyed by the frequent inconsistencies to force it on my university students via an exercise<sup id="fnref:force" role="doc-noteref"><a href="#fn:force" class="footnote" rel="footnote">11</a></sup>, I believed my thoughts might be more generally interesting. At least I now have an article to point to whenever it does come up. I am very much interested in your thoughts. Am I misguided and obsessive? Am I just plain wrong? Feel free to enlighten me in the comments below!</p>

<p>In closing, allow me to implore you one last time: We might not agree on which exact order to follow, but I hope you now concur some is needed. So please, I beg of you: Adopt “my” rules. Adopt some other rules. I really don’t care about which, just adopt <em>some</em>.<sup id="fnref:lie" role="doc-noteref"><a href="#fn:lie" class="footnote" rel="footnote">12</a></sup><br />
<a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/ChekhovsGun">If you say in the first chapter that there is a rifle hanging on the wall, in the second or third chapter it absolutely must go off.</a>. If you include a file, it better have a purpose for being where it is.</p>

<hr />

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:easy" role="doc-endnote">
      <p>Conveniently, this is also a much easier article to write. And a bit of an unbridled rant, so please excuse some foul language ;-) <a href="#fnref:easy" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:thanks" role="doc-endnote">
      <p>thank you for that. <a href="#fnref:thanks" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:strawman" role="doc-endnote">
      <p>Of course, what I am doing here is not exactly fair. All I do is construct a strawman to beat it up and tear it back down again. That is for the very simple reason that I am not aware of any better arguments against my position. If you do know any and are convinced I am delusional, I would be most grateful to be enlightened by your wisdom. Feel free to use the comments below or contact me via email. <a href="#fnref:strawman" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:features" role="doc-endnote">
      <p>The others, in order of my personal preference, are: <a href="https://en.cppreference.com/w/cpp/language/constraints">concepts</a>, <a href="https://en.cppreference.com/w/cpp/language/coroutines">coroutines</a> and <a href="https://en.cppreference.com/w/cpp/ranges">ranges</a>. <a href="https://www.youtube.com/watch?v=Be47dtmj8EE">Here is a great talk quickly illustrating what else C++20 has to offer.</a> <a href="#fnref:features" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:cvscpp" role="doc-endnote">
      <p>So I personally see few reasons to choose it over C++, except maybe availability and simplicity of implementation. <a href="#fnref:cvscpp" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:goto" role="doc-endnote">
      <p>I’m not trying to unduly diss goto here. There are valid reasons for its use. <a href="https://www.youtube.com/watch?v=lW51OrNJAn8">It is also pretty interesting what is defined in terms of it.</a> <a href="#fnref:goto" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:hashinclude" role="doc-endnote">
      <p>It is absolutely not the topic of this post, but considering I used this headline, I feel compelled to mention that another thing that matters is, of course, diversity and inclusion. <a href="https://www.includecpp.org/">Have a look at the #include&lt;c++&gt; community.</a> <a href="#fnref:hashinclude" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:missed" role="doc-endnote">
      <p>Depending on how condensed and pithy you prefer to consume technical opinions, that might of course be a good thing and better suited for you than my own writing. Additionally, I might have missed some articles. If so, feel free to point that out in the comments and I will gladly read them, give proper credit where it is due and link them here. <a href="#fnref:missed" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:self" role="doc-endnote">
      <p>which could very well be future versions of yourself. <a href="#fnref:self" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:ct" role="doc-endnote">
      <p>This is simplified of course and the way I described the order things happen in could be misleading. Of course, the decision which gun to call happens at compile time and not <em>after</em> fun is called at runtime. <a href="#fnref:ct" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:force" role="doc-endnote">
      <p>Well, it wasn’t exactly forced. It was an optional exercise for additional points in which I requested them to create a clang based tool enforcing the ordering, which was nothing more than a thinly veiled attempt to prompt them to at least think about the matter. No one took me up on it, but it was end of term and exams were coming up, so I can’t begrudge them that. <a href="#fnref:force" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:lie" role="doc-endnote">
      <p>That is, of course, a lie. I want you to follow my example. To cite the great Walter E. Brown: <a href="https://www.youtube.com/watch?v=OAmWHmwlMwI">I know that all these opinions are not yet shared by all programmers - but they should be</a> <a href="#fnref:lie" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Hannah Lenk</name><email>hannah.lenk@codemetas.de</email></author><category term="c++" /><summary type="html"><![CDATA[I know I promised to talk more about emulation, about chess and operating systems, but I have to get something off of my chest first. This is not going to be one of my would-be grand and elongated epics trying to cover far too much in far too many words. Instead, I shall focus on one very small, very self contained thing: the order of #include directives in C++ source code1 Conveniently, this is also a much easier article to write. And a bit of an unbridled rant, so please excuse some foul language ;-) &#8617;]]></summary></entry><entry><title type="html">KlobiGB - Overview</title><link href="http://localhost:4000/2020/06/22/klobigb_overview.html" rel="alternate" type="text/html" title="KlobiGB - Overview" /><published>2020-06-22T04:41:39+02:00</published><updated>2020-06-22T04:41:39+02:00</updated><id>http://localhost:4000/2020/06/22/klobigb_overview</id><content type="html" xml:base="http://localhost:4000/2020/06/22/klobigb_overview.html"><![CDATA[<p><em>Some of you might have read my rather grandiose and ever so slightly over-dramatic announcement of things to come. Among other writings I promised to share my insignificant little Game Boy emulator and today I shall finally make good on that promise. Or at least begin to do so. Or tell you about intending to begin doing so at some later date, maybe. We’ll see.</em></p>

<p>What I definitely will do in this article, however, is explain why I deemed it an interesting side project to pursue and believe emulator development in general is awesome.
Not only is the process fun and rewarding in and of itself and the product generally useful but the required study of intricate and obscure details deepens ones understanding and appreciation of hardware, abstraction and the conveniences of more common environments. Everyone should have written at least one emulator in their life.
Furthermore I will give a brief overview of the device in question and break down which corresponding pieces the emulator consists of, details of all of which I shall elaborate on in future articles.
Finally, in a short preview - not to leave you hanging without showing any code at all - I shall discuss how I represent the CPUs state, in particular its registers, and why I chose to do it the way I did.</p>

<div class="post_toc">
  <h4>Contents</h4>
  <blockquote>
<ul id="markdown-toc">
  <li><a href="#emulation-and-why-emulate" id="markdown-toc-emulation-and-why-emulate">Emulation and why emulate?</a></li>
  <li><a href="#the-game-boy-and-why-the-game-boy" id="markdown-toc-the-game-boy-and-why-the-game-boy">The Game Boy and why the Game Boy?</a></li>
  <li><a href="#how" id="markdown-toc-how">How?</a></li>
  <li><a href="#sharp-lr35902" id="markdown-toc-sharp-lr35902">Sharp LR35902</a></li>
  <li><a href="#outlook" id="markdown-toc-outlook">Outlook</a></li>
</ul>

  </blockquote>
</div>

<h1 id="emulation-and-why-emulate">Emulation and why emulate?</h1>

<p>To many of my dear readers<sup id="fnref:readers" role="doc-noteref"><a href="#fn:readers" class="footnote" rel="footnote">1</a></sup> the topic of emulation is most likely an intimately familiar one, at least from a users perspective. Nonetheless, just to ensure we are all one the same page here, allow me to clarify and explain ever so briefly what we mean when we use the term and why it is both useful for consumers and culturally significant.<sup id="fnref:skip" role="doc-noteref"><a href="#fn:skip" class="footnote" rel="footnote">2</a></sup></p>

<p>There are many ways we could define what an emulator is, but essentially it all boils down to one computer system acting as if it were a different one. We know this is possible, as we know a great deal of computer science, thanks to <a href="https://en.wikipedia.org/wiki/Alan_Turing">the great Alan Turing</a> and <a href="https://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis">work he and others did in the 1930s</a>. In particular he developed a seemingly simple model of computation now known as a <a href="https://en.wikipedia.org/wiki/Turing_machine">Turing Machine</a> that is nonetheless powerful enough to compute everything every modern and real machine can.<sup id="fnref:turing_machine" role="doc-noteref"><a href="#fn:turing_machine" class="footnote" rel="footnote">3</a></sup> All our real computational systems and most languages used to program them could be simulated on a Turing machine and can - to some extent - simulate a Turing machine. As such, they are <a href="https://en.wikipedia.org/wiki/Turing_completeness">essentially equivalent</a>, except for such minor and entirely insignificant inconveniences as speed and memory.<br />
So <a href="https://en.wikipedia.org/wiki/Analytical_Engine">Babbage’s Analytical Engine</a> could in theory compute the beautiful transformation from markdown to html necessary for this post which my brand new Thinkpad T590 is constantly repeating live as I am typing. I just should have finished writing at the time of its inception, i.e. about 200 years ago, if I intend to publish anytime soon.</p>

<p>More relevant than this grand exercise in futility and the area you, dear reader, are most likely to come in contact with such technology is in the realm of consumer electronics. If you played a game on <a href="https://en.wikipedia.org/wiki/Virtual_Console">Nintendo’s Virtual Console</a>, you ran an emulator. If you own any of the recent fad of mini-consoles, like the <a href="https://en.wikipedia.org/wiki/NES_Classic_Edition">NES Classic</a>, <a href="https://en.wikipedia.org/wiki/Sega_Genesis_Mini">Mega Drive Mini</a> or <a href="https://en.wikipedia.org/wiki/PlayStation_Classic">PlayStation Classic</a>, you ran an emulator.<sup id="fnref:bleem" role="doc-noteref"><a href="#fn:bleem" class="footnote" rel="footnote">4</a></sup> If you typed a command in a typical linux or mac terminal window, <a href="https://en.wikipedia.org/wiki/Terminal_emulator">you ran an emulator</a>.</p>

<p>You may have noticed that this last example is not quite like the others. Not only are we not talking about a game console, it is quite likely you have not even seen the original hardware emulated. I know I personally have never seen a <a href="https://en.wikipedia.org/wiki/VT100">VT100</a>, for example<sup id="fnref:vt" role="doc-noteref"><a href="#fn:vt" class="footnote" rel="footnote">5</a></sup>, and nonetheless many of the programs I use daily issue <a href="https://en.wikipedia.org/wiki/ANSI_escape_code">escape sequences originally supported by it</a> and expect them to be interpreted correctly.<sup id="fnref:linux_term" role="doc-noteref"><a href="#fn:linux_term" class="footnote" rel="footnote">6</a></sup><br />
Which brings me closer to the point I am trying to make here. A multitude of reasons exist which go beyond the obvious circumvention of pesky copy protection and hardware vendor lock in and I would like to quickly address just one I consider among the most pressing: hardware dies.<br />
I know, it’s something I am struggling to come to terms with, too.<sup id="fnref:hardware_death" role="doc-noteref"><a href="#fn:hardware_death" class="footnote" rel="footnote">7</a></sup> I’ll give you a moment to get over the initial shock before I drop the next bomb and tell you that some even stops being produced. And it just gets worse: Tragically, not all software is open source, code can get lost too. Simply adjusting, rewriting and recompiling is not usually an option for proprietary products. I think we can all agree that most software, especially video games, should be considered a work of art and is worth preserving just as much as paintings, movies, television shows and music are. Future generations should be enabled to enjoy an authentic experience of what it was like to consume these products of creative endeavor. <a href="https://en.wikipedia.org/wiki/Digital_preservation#Emulation">Emulating the devices they ran on</a> is the most sustainable way to do so.</p>

<p>So as you can see, it is kind of essential for preserving our cultural inheritance that someone engages in emulator development. Yet why should that someone be me or even you, dear reader? Why can’t it be <em>someone else</em>?<br />
Whilst asking that question is not, in general, a good idea and all of us are <a href="https://en.wikipedia.org/wiki/Diffusion_of_responsibility">all too prone to do so</a>, let’s engage with it for just another minute.<sup id="fnref:reading_speed" role="doc-noteref"><a href="#fn:reading_speed" class="footnote" rel="footnote">8</a></sup></p>

<p>Naturally, random people on the internet, <a href="https://www.reddit.com/r/EmuDev/comments/gteo6h/is_learning_emudev_useful_in_general/">specifically on reddit</a>, have much better answers than I myself could provide alone. Specifically, they mentioned:</p>
<ul>
  <li>All programming is practice and improves ones ability to program</li>
  <li>An emulator is a rather big project and as such teaches you about code management and systems design</li>
  <li>The skill set acquired is especially helpful when dealing with embedded systems, as you have to deal with many low-level details rarely encountered in other types of projects</li>
  <li>Even if direct exposure to those details is rare, the additional knowledge of internal workings of hardware can help make you a more careful and better programmer</li>
</ul>

<p>Those are great arguments, yet are they sufficient? I don’t know. As so frequently, I offered up a long, somewhat plausible and elaborate explanation and justification that at best tells only half the story. It seems far more like a rationalization I constructed after the fact than a candid reflection of my motivations at the start of this project. My thoughts at the time can simply be summarized as “This is fun!” and I belief that alone is enough.<br />
<a href="https://en.wikipedia.org/wiki/Brian_Kernighan">Brian Kernighan</a><sup id="fnref:brian" role="doc-noteref"><a href="#fn:brian" class="footnote" rel="footnote">9</a></sup> once so eloquently suggested:</p>

<blockquote>
  <p>“Do what you think is interesting, do something that you think is fun and worthwhile, because otherwise you won’t do it well anyway.”</p>
</blockquote>

<p>I am trying to follow his advice.</p>

<h1 id="the-game-boy-and-why-the-game-boy">The Game Boy and why the Game Boy?</h1>

<p>If you have never heard of the Game Boy, I assume you must either be very very young - good for you then - or have been living under a rock for a few decades.<sup id="fnref:rock" role="doc-noteref"><a href="#fn:rock" class="footnote" rel="footnote">10</a></sup> It must have been a particularly remote and secluded rock so, considering this thing has been continuously produced for 14 years until 2003, is still among <a href="https://en.wikipedia.org/wiki/List_of_best-selling_game_consoles">the three most sold video game consoles of all time</a> even now and has been to wars and survived:<sup id="fnref:credit_gulfgb" role="doc-noteref"><a href="#fn:credit_gulfgb" class="footnote" rel="footnote">11</a></sup></p>

<p><img src="/images/Game_boy_damaged_in_the_gulf_war.JPG" alt="A Game Boy damaged in the gulf war and still capable of playing Tetris" title="A Game Boy damaged in the gulf war and still capable of playing Tetris ;-)" class="centered-image" width="40%" /></p>

<p>Many <a href="https://en.wikipedia.org/wiki/Kirby_(character)">iconic</a> <a href="https://en.wikipedia.org/wiki/Wario">characters</a> and incomparably successful <a href="https://en.wikipedia.org/wiki/Pok%C3%A9mon">franchises</a> still very much alive today, about three decades later, got their debut on this incredible little device.</p>

<p>All of this undoubtedly makes the Game Boy historically significant and a really great device to own and use, yet does it also imply it’s a great choice to develop an emulator for?</p>

<p>As with many interesting questions, there is no simple binary answer. Rather, it depends. More concretely, it depends on your goals. If you desire to produce an unrivaled product that delivers unique benefits to its users and will set you apart from the crowd, it might not be the best of choices. At the time of writing <a href="https://github.com/topics/gameboy-emulator">github lists 184 repositories under the topic gameboy-emulator</a>.<br />
If you desire a really difficult, nigh-insurmountable challenge with little help along the way and are already quite well versed and experienced, it might not be the most ideal choice either. The internet offers a ton of <a href="https://github.com/Gekkio/gb-ctr">excellent</a> <a href="https://gbdev.io/pandocs/">documentation</a> about almost all relevant details gathered and published by wonderful people over the course of many years, the <a href="https://www.reddit.com/r/EmuDev/">emudev reddit</a> is filled with myriad questions and answers about details and frequent errors and a number of excellent <a href="https://github.com/retrio/gb-test-roms">test roms</a> are available.</p>

<p>If conversely - like me - you are just starting out in this direction, the situation could hardly be more ideal. The Game Boy is a reasonably simple device whilst not being entirely trivial. It is easy enough to get <em>something</em> on the screen and even quickly get the satisfaction of some playable games. Nonetheless there are some almost inevitable pitfalls ensuring you learn something new on the way. If one gets bored and ambitious, the number of hours one can sink into getting the details exactly right, supporting more games and peripherals and improving performance is limited by life, not problems to solve. <sup id="fnref:chip8" role="doc-noteref"><a href="#fn:chip8" class="footnote" rel="footnote">12</a></sup></p>

<p>And - of course - I have an unhealthy obsession with Tetris and the early Pokemon games. Developing an emulator proves a most convenient excuse to play them and consider it work ;-). It is simply immensely satisfying to see this displayed in a program of my own:</p>

<p><img src="/images/klobigb_pokemon_title.gif" alt="Pokemon Menu Screen in KlobiGB" title="Isn't it lovely?" class="centered-image" width="40%" /></p>

<h1 id="how">How?</h1>

<p>With this grand prelude out of the way we finally know <em>what</em> it is we want to do and <em>why</em> we want to do it<sup id="fnref:assumption" role="doc-noteref"><a href="#fn:assumption" class="footnote" rel="footnote">13</a></sup>, so we can at long last get started on <em>how</em> to go about it.</p>

<p>As I most likely have already bored you out of your mind with all my meaningless introductory babble, lets not dwell on abstract matters much longer and get down into the weeds and details of our concrete example. There is just one relevant fact you have to understand before we get started. Allow me to put it in the words of one of the greater tv shows of recent memory at a time when it was still good:<sup id="fnref:as_if" role="doc-noteref"><a href="#fn:as_if" class="footnote" rel="footnote">14</a></sup></p>

<p><img src="/images/if_you_cant_tell.jpg" alt="If you can't tell, does it matter?" title="The &quot;as-if rule&quot; of real life" class="centered-image" width="50%" /></p>

<p>What our emulator has to mimic is only the outwardly observable behavior of the original system, not its exact internal workings. So we can save ourselves the trouble of getting down to the level of individual logic gates, transistors or even the underlying physics. That is essentially the <a href="https://stackoverflow.com/questions/1584617/simulator-or-emulator-what-is-the-difference">difference between emulation and simulation</a>.<sup id="fnref:simulation" role="doc-noteref"><a href="#fn:simulation" class="footnote" rel="footnote">15</a></sup></p>

<p>In order to determine which parts of the original hardware’s behavior we should deem relevant and observable, we ought to consider what it is our program eventually does: It takes as input a digital copy of any given real game and presents to the user an approximation of the visuals and sound this program would have shown and played were it executed on a real Game Boy. Button presses in some form are forwarded to the emulator and the program responds by changing what it presents in approximately the same way it would have had the physical buttons been pressed. As such we have to be somewhat accurate with everything that is shown directly to the user(humans don’t necessarily notice or care about every pixel and millisecond) and <em>really</em> accurate with everything that can be seen by a program, i.e. everything an arbitrary instruction in a program can use to change its behavior. If one instruction stores the value 42 and another reads the stored value, it does not matter how this happens, but it had better read 42, not 41 or 43.</p>

<p>It might seem patently obvious, but this trivial observation can guide us when deciding what is relevant and what is not. 
Take, for instance, the PPU(Picture Processing Unit), which is responsible for drawing graphics onto the screen. It is a really strange little beast and I will go into much more detail about it in a dedicated article. For now, suffice it to say that despite using an LCD, it acts as if the image was drawn by a CRT, that is gradually in <a href="https://en.wikipedia.org/wiki/Scan_line">scanlines</a>. Cycle accurately emulating this behavior can be quite expensive and it might be reasonable to ignore that detail and instead draw the whole screen at once at the same time the last scanline would have finished. This acceleration would, however, yield erroneous results. A program can set a specific register and thereby request an interrupt when the drawing reaches a specified line. It can then react to this and change parameters of the drawing mid-screen. Many if not most games <a href="https://kemenaran.winosx.com/posts/links-awakening-rendering-the-opening-cutscene/">utilize this to great effect</a>. As such, we have to at least do our drawing line by line.<br />
On the other hand, doing it pixel by pixel is not strictly necessary. Whilst some nasty(or ingenious) games even modify settings during the drawing of a single line, there is - to my knowledge - no way for a program itself to detect its effect and the damage done by getting it wrong is rare and mostly limited to some minor visual artifacts, which is a trade-off I am willing to make.</p>

<p>However, instead of getting ahead of and losing ourselves in the details of any one part, we should first of all get an overview of what parts there are and what their respective job is. I already mentioned the PPU above. Including it, there are a bunch of systems running in parallel:</p>

<ul>
  <li><em>CPU</em>: The “central processing unit”, or processor. This is what is responsible for executing instructions.</li>
  <li><em>PPU</em>: The “picture processing unit”, basically the systems graphics card. This is responsible for drawing pictures on the screen, hence the name.</li>
  <li><em>APU</em>: The “audio processing unit”. You might have guessed it from its name, but the beautiful music of our games is played with this piece of hardware.</li>
  <li><em>DMA Controller</em>: DMA stands for “direct memory access”. This controller can be used by programs to quickly transfer some memory without involving the CPU in the copying process.</li>
  <li><em>Timer</em>: A timer counting up a register that can be configured to interrupt the CPU.</li>
</ul>

<p>These pieces communicate via memory mapped registers. Aside from those, the 64 KB address space also contains ROM, RAM and potentially other things from the currently inserted cartridge, so we have to somehow emulate this memory mapping as well and route reads and writes to the correct subsystems.</p>

<p>That much information should be sufficient to begin working. Better and more detailed writing as well as great videos can - of course - be found online. I wholeheartedly recommend watching <a href="https://media.ccc.de/v/33c3-8029-the_ultimate_game_boy_talk">The Ultimate Game Boy Talk</a>, it has been an invaluable resource for me.</p>

<h1 id="sharp-lr35902">Sharp LR35902</h1>

<p>The first and central piece we shall take a closer look at and attempt implementing is the CPU. In the talk I mentioned above, Michael Steil utilized this beautiful visualization on his <a href="https://www.pagetable.com/?p=1099">slides</a> to describe it:</p>

<p><img src="/images/sharp_lr.png" alt="The Sharp LR35902 has instructions from both the Zilog Z80 and the Intel 8080(but not all of them) and some more" title="Why?" class="centered-image" width="50%" /></p>

<p>As you can see, it is somewhat of a mix between the more well known and frequently used <a href="https://en.wikipedia.org/wiki/Zilog_Z80">Zilog Z80</a> and <a href="https://en.wikipedia.org/wiki/Intel_8080">Intel 8080</a> processors with some slices cut away and some additional sugar sprinkled on top. It is an 8-bit processor, but uses a 16-bit address bus which grants it access to a 64KB big linear address space. As one would expect, it also has some quickly accessible storage in the form of registers. It sports the same set as the 8080. Here is an <a href="https://github.com/gbdev/pandocs/blob/develop/content/CPU_Registers_and_Flags.md">excerpt of the pandocs</a>, describing them and their use:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 16bit Hi   Lo   Name/Function
 AF    A    -    Accumulator &amp; Flags
 BC    B    C    BC
 DE    D    E    DE
 HL    H    L    HL
 SP    -    -    Stack Pointer
 PC    -    -    Program Counter/Pointer
</code></pre></div></div>

<p>Let’s ignore the Stack Pointer, Program Counter and Flags for now and focus on the stuff in between, i.e. BC, DE and HL. Or should I rather say B, C, D, E, H, and L? Despite being mainly an 8-bit processor, the Sharp LR35902 supports some instructions working with 16 bit wide operands and for that purpose registers can be paired up and treated as one larger value. So B can be either a simple 8-bit value of itself or the <a href="https://en.wikipedia.org/wiki/Bit_numbering#Most_significant_byte">most significant byte</a> of the 16-bit register BC.</p>

<p>How exactly should such a construct be represented in code. This is, of course, language dependent, which is why at least a fleeting familiarity with my language of choice, C++, may be required to fully comprehend what is discussed below.<sup id="fnref:language" role="doc-noteref"><a href="#fn:language" class="footnote" rel="footnote">16</a></sup></p>

<p>As writes to a partial register have to modify the value of the combined one and vice-versa, we have to get slightly more sophisticated than separate variables of the appropriate bit width. Many, if not most, emulators chose to do something different for reasons I am going to outline in a moment, but with a cursory search, I found at least 7 that use something akin to the following:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">union</span> <span class="n">register16</span>
<span class="p">{</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">combined</span><span class="p">;</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">uint8_t</span> <span class="n">parts</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="p">};</span></code></pre>
</figure>

<p>This seems, at first glance, like the simplest and most obvious solution. After all, multiple variables of different type sharing the same region of memory is exactly what <a href="https://en.cppreference.com/w/cpp/language/union">unions</a> are made for, isn’t it? Well, not exactly. This approach has two very significant drawbacks:</p>

<ol>
  <li>It is <a href="https://en.cppreference.com/w/cpp/language/ub">undefined behavior</a>.</li>
  <li>Even on compilers that specifically allow it, the exact behavior is machine dependent.</li>
</ol>

<p>To understand the first point, the description above has to be amended by a few meaningful words: Multiple variables of different type sharing the same region of memory, <strong>only one of which is active at any given time</strong>, is what unions are made for. Whilst the members of a <em>normal</em> <a href="https://en.cppreference.com/w/cpp/language/class">class type</a> share (almost) the same lifetime, but live in different, non-overlapping (but adjacent) memory, the members of a union share the same memory, but use it at different, non-overlapping times. Writing to any member is ok and simply switches which is active, <a href="https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior">reading from an inactive member, however, is undefined behavior.</a><sup id="fnref:variant" role="doc-noteref"><a href="#fn:variant" class="footnote" rel="footnote">17</a></sup></p>

<p>We clearly cannot guarantee that whatever Game Boy code we execute happens to adhere to those rules. In fact, we can pretty much guarantee it does not, as building up the larger values by its parts is kind of how things were and frequently had to be handled on the device.</p>

<p>But what does that mean? What even is “undefined behavior”? I keep throwing this phrase around without any clarification. Well, dear reader, undefined behavior is exactly what it says on the tin. There are things with behavior not defined by the <a href="https://www.youtube.com/watch?v=ZLNq-4IiNTY">holy</a> <a href="https://github.com/cplusplus/draft">standard</a>. Famous examples are dereferencing nullptr or accessing arrays out of bounds. The standard imposes no restrictions on what a compliant compiler is free to do if it encounters code committing such atrocities. It may set your computer on fire, <a href="https://feross.org/gcc-ownage/">launch nethack</a> or - worst of all - do exactly what you expected it to. Until one day it doesn’t. It is clearly something any C++ programmer should avoid at all costs.<sup id="fnref:ubsan" role="doc-noteref"><a href="#fn:ubsan" class="footnote" rel="footnote">18</a></sup></p>

<p>“But wait”, I hear you say. “That is all fine and dandy for purists in a language lawyering class held in your cute little ivory tower, but out here, in <em>the real world</em>, we couldn’t care less about your theory. Compilers disagree. Look here, <a href="https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Type%2Dpunning">gcc specifically allows accessing inactive members</a>, so why should I care?”</p>

<p>Fine. Point taken. If you know about the issue, know your compiler and know what you are doing, you can get away with it. Go ahead. This still leaves problem number 2 so: The exact results are machine dependent.</p>

<p>What do I mean by that? Quite simple: <a href="https://en.wikipedia.org/wiki/Endianness">Endianness</a>. Endianness is the ordering used to store multi-byte values in memory. Earlier, I described that B is the most significant byte in the 2-byte BC register. Whether this corresponds to parts[0] or parts[1] in the declaration above depends on the system we run on. On a big-endian system, which stores higher valued bytes at lower addresses, B is parts[0] and C is parts[1]. Little-endian systems, on the other hand, store lower value bytes at lower addresses and the parts would be reversed, B being parts[1] and C being parts[0].</p>

<p>If you know about the issue, know your compiler and your target architecture and know what you are doing, you can still get away with it, but the picture starts to look a little bleak by now. It might be worth considering alternatives.</p>

<p>What could be done instead? Specifics can vary and concrete solutions abound, but all of them basically fall into one of two categories: keep separate 8 bit values and combine them when needed or keep one 16 bit value and split it when needed. Specialize access to the whole or specialize access to the parts. My choice at the time was the latter, so in retrospect I have to admit it was rather arbitrary.<sup id="fnref:blanket" role="doc-noteref"><a href="#fn:blanket" class="footnote" rel="footnote">19</a></sup></p>

<p>In a solution not entirely unlike the <a href="https://en.cppreference.com/w/cpp/container/vector_bool/reference">proxy type used by std::vector’s bool specialization</a> to reference individual bits and with all the same drawbacks making this so contentious, I decided to build a reference-like type to a single byte within a larger value:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">class</span> <span class="nc">byte_proxy</span>
<span class="p">{</span>
	<span class="nl">public:</span>
	<span class="k">constexpr</span> <span class="n">byte_proxy</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&amp;</span> <span class="n">target</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">shift</span><span class="p">)</span> <span class="k">noexcept</span><span class="o">:</span>
		<span class="n">target_</span><span class="p">{</span><span class="n">target</span><span class="p">},</span>
		<span class="n">shift_</span><span class="p">{</span><span class="n">shift</span><span class="p">}</span>
	<span class="p">{}</span>
	
	<span class="k">constexpr</span> <span class="k">operator</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint8_t</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span>
	<span class="p">{</span>
		<span class="k">return</span> <span class="p">(</span><span class="n">target_</span><span class="o">&gt;&gt;</span><span class="n">shift_</span><span class="p">)</span><span class="o">&amp;</span><span class="mh">0xff</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="k">constexpr</span> <span class="n">byte_proxy</span><span class="o">&amp;</span> <span class="k">operator</span><span class="o">=</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">uint8_t</span> <span class="n">val</span><span class="p">)</span> <span class="k">noexcept</span>
	<span class="p">{</span>
		<span class="n">target_</span><span class="o">&amp;=~</span><span class="p">((</span><span class="mh">0xff</span><span class="p">)</span><span class="o">&lt;&lt;</span><span class="n">shift_</span><span class="p">);</span>
		<span class="n">target_</span><span class="o">|=</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="p">{</span><span class="n">val</span><span class="p">}</span><span class="o">&lt;&lt;</span><span class="n">shift_</span><span class="p">);</span>
		<span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="k">private</span><span class="o">:</span>
	<span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&amp;</span> <span class="n">target_</span><span class="p">;</span>
	<span class="kt">unsigned</span> <span class="n">shift_</span><span class="p">;</span>
<span class="p">};</span></code></pre>
</figure>

<p>This code is a bit simplified. The real one is a template to be more generic in its source and target type, contains some more casts to ensure we get the right types and values without any narrowing, integral promotions or sign extension getting in our way and overloads some more special members, like assignment from another byte_proxy and the compound assignments(i.e. +=, -= etc.). I deemed such details unimportant and distracting, so I decided on omitting them in service of accessibility.</p>

<p>The basic idea is rather trivial:</p>
<ul>
  <li>It is constructed with a reference to a larger value and a starting position inside this value. A shift of 0 addresses the first, lowest valued byte, a shift of 8 addresses the next higher valued one and so on. Values in between would also be possible, but are not useful in our case.</li>
  <li>It can be converted to a simple 8-bit value by shifting the relevant bits to the front and masking off the others.</li>
  <li>If it is assigned to, it first sets the relevant bits to 0, thereby erasing whatever was stored before, shifts the replacement into position and uses bitwise or to insert it.</li>
</ul>

<p>Shifting bits in an unsigned value <a href="https://en.cppreference.com/w/cpp/language/operator_arithmetic">is clearly defined</a> to be equivalent to multiplying with 2 raised to the power of the shift amount (modulo 2<sup>number_of_result_bits</sup>). It is as such machine independent and guaranteed to give the same and desired result on any platform it is compiled for. All our problems are solved.</p>

<p>Well… the most astute and well-read of my readers are likely to interrupt at this point and call me out for some minor hypocrisy. When presenting the union solution I held it to the highest standard and demanded compliance, but my own solution is not guaranteed to work either. The <a href="https://en.cppreference.com/w/cpp/header/cstdint">fixed-width integer types are optional</a>, an implementation may chose to simply not provide them at all. I still maintain that it is better. If it compiles we can be absolutely sure it works as advertised, if it cannot work, it will fail to compile. I’d take that over undefined or unspecified behavior any day.</p>

<p>Alright, with that out of the way, how do I actually use this? Do I keep additional members in my state class for all the partial registers? I could do that, but it has some downsides:</p>
<ul>
  <li>It makes programmatically selecting a register at runtime a little annoying (basically using a big switch and there are really enough of those in an emulator xD)</li>
  <li>It kind of wastes memory (a really, really insignificant amount in the grand scheme of things and if this were the only reason it would clearly be premature optimization without any benefit. But why pessimize unnecessarily?)</li>
  <li>It makes copying or storing and restoring the state more difficult and error prone. This one is really problematic. As the state would contain references to part of itself, simply copying it normally does not work or might allow the copy to modify the original. Even worse, those references could be left dangling and - once again - throw us right back into undefined behavior land.</li>
</ul>

<p>As such, I store the 16-bit registers as an array and create the partial proxies on the fly whenever required. But wait, isn’t that ugly? Will I have to write registers_[0] to get at A and lose all the beautiful mnemonics? Not really, that is what <a href="https://en.cppreference.com/w/cpp/language/enum">enums</a> are for:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">enum</span> <span class="n">register16</span>
<span class="p">{</span>
	<span class="n">BC</span><span class="p">,</span> <span class="n">DE</span><span class="p">,</span> <span class="n">HL</span><span class="p">,</span> <span class="n">AF</span><span class="p">,</span> <span class="n">SP</span><span class="p">,</span> <span class="n">PC</span>
<span class="p">};</span></code></pre>
</figure>

<p>Each enumerator can now be used to index into our array. state[registers16::AF] for instance would provide us with the 4th entry. But wait, isn’t that in itself ugly and dangerous? Doesn’t it pollute the global namespace and allow far more operations than we actually want? Of course, that is <a href="http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Renum-class">what strongly typed</a> <a href="https://stackoverflow.com/questions/18335861/why-is-enum-class-preferred-over-plain-enum">enums are for</a>:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">enum</span> <span class="k">class</span> <span class="nc">register16</span>
<span class="p">{</span>
	<span class="n">BC</span><span class="p">,</span> <span class="n">DE</span><span class="p">,</span> <span class="n">HL</span><span class="p">,</span> <span class="n">AF</span><span class="p">,</span> <span class="n">SP</span><span class="p">,</span> <span class="n">PC</span>
<span class="p">};</span></code></pre>
</figure>

<p>But wait, doesn’t that prevent our original use-case? Without the implicit conversion to int we can’t use the enumerators to index into an array now, can we? That is correct. Enter: the worlds simplest container that is not a plain array:</p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="k">typename</span> <span class="nc">enum_type</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">number_of_values</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">enum_map</span> 
<span class="p">{</span>
	<span class="nl">public:</span>
	<span class="k">using</span> <span class="n">underlying</span><span class="o">=</span><span class="n">std</span><span class="o">::</span><span class="n">underlying_type_t</span><span class="o">&lt;</span><span class="n">enum_type</span><span class="o">&gt;</span><span class="p">;</span>
	
	<span class="k">constexpr</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="k">operator</span><span class="p">[](</span><span class="n">enum_type</span> <span class="n">v</span><span class="p">)</span> <span class="k">noexcept</span>
	<span class="p">{</span>
		<span class="k">return</span> <span class="n">data</span><span class="p">[</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="n">underlying</span><span class="o">&gt;</span><span class="p">(</span><span class="n">v</span><span class="p">)];</span>
	<span class="p">}</span>
	
	<span class="k">constexpr</span> <span class="k">const</span> <span class="k">auto</span><span class="o">&amp;</span> <span class="k">operator</span><span class="p">[](</span><span class="n">enum_type</span> <span class="n">v</span><span class="p">)</span> <span class="k">const</span> <span class="k">noexcept</span>
	<span class="p">{</span>
		<span class="k">return</span> <span class="n">data</span><span class="p">[</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="n">underlying</span><span class="o">&gt;</span><span class="p">(</span><span class="n">v</span><span class="p">)];</span>
	<span class="p">}</span>
	
	<span class="k">constexpr</span> <span class="k">auto</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">number_of_values</span><span class="p">;</span> <span class="p">}</span>
	
	<span class="k">private</span><span class="o">:</span>
	<span class="n">std</span><span class="o">::</span><span class="n">array</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span><span class="n">number_of_values</span><span class="o">&gt;</span> <span class="n">data</span><span class="p">{};</span>
<span class="p">};</span></code></pre>
</figure>

<p>Again, the real code contains some more members to be a proper container, but it’s unimportant to get the idea. All it does is forward operations to an underlying <a href="https://en.cppreference.com/w/cpp/container/array">std::array</a>, explicitly casting away the enum where required. We are back to what we had with a plain array and plain unscoped enums, with some additional safety, as it can only be accessed by valid enum values. One could still work around this of course, yet trying to prevent it is no longer fighting against Murphy, but Machiavelli.<sup id="fnref:murphy" role="doc-noteref"><a href="#fn:murphy" class="footnote" rel="footnote">20</a></sup></p>

<p>Great. Combining those parts nets us a working and at least somewhat elegant solution, but at what cost? It seems like quite a lot of machinery and abstraction just to get around issues likely never to appear on any system this emulator is ever going to be compiled for. Is it worth it? Is it expensive?</p>

<p>I planned to present a small benchmark here to prove my point, but it turns out I can do one better than that. Have look at this simple test:<sup id="fnref:excerpt" role="doc-noteref"><a href="#fn:excerpt" class="footnote" rel="footnote">21</a></sup></p>

<figure class="highlight">
  <pre><code class="language-cpp" data-lang="cpp"><span class="c1">//[...]</span>
<span class="k">class</span> <span class="nc">simple_cpustate_enum_proxy</span>
<span class="p">{</span>
	<span class="nl">public:</span>
	<span class="k">constexpr</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="o">&amp;</span> <span class="k">operator</span><span class="p">[](</span><span class="n">register16</span> <span class="n">id</span><span class="p">)</span> <span class="k">noexcept</span>
	<span class="p">{</span>
		<span class="k">return</span> <span class="n">registers_</span><span class="p">[</span><span class="n">id</span><span class="p">];</span>
	<span class="p">}</span>

	<span class="k">constexpr</span> <span class="n">byte_proxy</span> <span class="k">operator</span><span class="p">[](</span><span class="n">register8</span> <span class="n">id</span><span class="p">)</span> <span class="k">noexcept</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="k">auto</span> <span class="n">idx</span><span class="o">=</span><span class="k">static_cast</span><span class="o">&lt;::</span><span class="n">std</span><span class="o">::</span><span class="n">underlying_type_t</span><span class="o">&lt;</span><span class="n">register8</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">id</span><span class="p">);</span>
		<span class="k">return</span> <span class="p">{</span><span class="n">registers_</span><span class="p">[</span><span class="n">register16</span><span class="p">{</span><span class="n">idx</span><span class="o">/</span><span class="mi">2</span><span class="p">}],(</span><span class="n">idx</span><span class="o">%</span><span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="mi">8u</span><span class="p">};</span>
	<span class="p">}</span>
	
	<span class="k">private</span><span class="o">:</span>
	<span class="n">enum_map_with_num</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span><span class="p">,</span> <span class="n">register16</span><span class="o">&gt;</span> <span class="n">registers_</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">union</span> <span class="n">register_union</span>
<span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="kt">uint16_t</span> <span class="n">combined</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="kt">uint8_t</span> <span class="n">parts</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="p">};</span>

<span class="k">struct</span> <span class="nc">simple_cpustate_union</span>
<span class="p">{</span>
    <span class="n">register_union</span> <span class="n">BC</span><span class="p">,</span> <span class="n">DE</span><span class="p">,</span> <span class="n">HL</span><span class="p">,</span> <span class="n">AF</span><span class="p">,</span> <span class="n">SP</span><span class="p">,</span> <span class="n">PC</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">simple_cpustate_enum_proxy</span> <span class="nf">magic_enum</span><span class="p">();</span>
<span class="n">simple_cpustate_union</span> <span class="nf">magic_union</span><span class="p">();</span>

<span class="kt">int</span> <span class="nf">test_enum</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="n">state</span><span class="o">=</span><span class="n">magic_enum</span><span class="p">();</span>
    <span class="k">return</span> <span class="n">state</span><span class="p">[</span><span class="n">register8</span><span class="o">::</span><span class="n">A</span><span class="p">]</span><span class="o">+</span><span class="n">state</span><span class="p">[</span><span class="n">register16</span><span class="o">::</span><span class="n">SP</span><span class="p">];</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">test_union</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="n">state</span><span class="o">=</span><span class="n">magic_union</span><span class="p">();</span>
    <span class="k">return</span> <span class="n">state</span><span class="p">.</span><span class="n">AF</span><span class="p">.</span><span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">+</span><span class="n">state</span><span class="p">.</span><span class="n">SP</span><span class="p">.</span><span class="n">combined</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">//[...]</span></code></pre>
</figure>

<p>
<div style="display:flex; justify-content:space-between; align-items:center; border-bottom: 1px solid black">
<a href="/code/enum_proxy_vs_union.cpp">A simple comparison</a> <a href="https://godbolt.org/clientstate/CnsKICAic2Vzc2lvbnMiOiBbCiAgICB7CiAgICAgICJpZCI6IDEsCiAgICAg ICJsYW5ndWFnZSI6ICJjKysiLAogICAgICAic291cmNlIjogIiNpbmNsdWRl IDxhcnJheT5cbiNpbmNsdWRlIDx0eXBlX3RyYWl0cz5cblxuI2luY2x1ZGUg PGNzdGRkZWY+XG4jaW5jbHVkZSA8Y3N0ZGludD5cblxuY2xhc3MgYnl0ZV9w cm94eVxue1xuXHRwdWJsaWM6XG5cdGNvbnN0ZXhwciBieXRlX3Byb3h5KHN0 ZDo6dWludDE2X3QmIHRhcmdldCwgdW5zaWduZWQgc2hpZnQpIG5vZXhjZXB0 OlxuXHRcdHRhcmdldF97dGFyZ2V0fSxcblx0XHRzaGlmdF97c2hpZnR9XG5c dHt9XG5cdFxuXHRjb25zdGV4cHIgb3BlcmF0b3Igc3RkOjp1aW50OF90KCkg Y29uc3Qgbm9leGNlcHQgeyByZXR1cm4gKHRhcmdldF8+PnNoaWZ0XykmMHhm ZjsgfVxuXHRcblx0Y29uc3RleHByIGJ5dGVfcHJveHkmIG9wZXJhdG9yPShz dGQ6OnVpbnQ4X3QgdmFsKSBub2V4Y2VwdFxuXHR7XG5cdFx0dGFyZ2V0XyY9 figoMHhmZik8PHNoaWZ0Xyk7XG5cdFx0dGFyZ2V0X3w9KHN0ZDo6dWludDE2 X3R7dmFsfTw8c2hpZnRfKTtcblx0XHRyZXR1cm4gKnRoaXM7XG5cdH1cblx0 XG5cdHByaXZhdGU6XG5cdHN0ZDo6dWludDE2X3QmIHRhcmdldF87XG5cdHVu c2lnbmVkIHNoaWZ0Xztcbn07XG5cbnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0 eXBlbmFtZSBlbnVtX3R5cGUsIDo6c3RkOjpzaXplX3QgbnVtYmVyX29mX3Zh bHVlcz5cbmNsYXNzIGVudW1fbWFwIFxue1xuICAgIHB1YmxpYzpcblx0dXNp bmcgdW5kZXJseWluZz1zdGQ6OnVuZGVybHlpbmdfdHlwZV90PGVudW1fdHlw ZT47XG5cdFxuXHRjb25zdGV4cHIgYXV0byYgb3BlcmF0b3JbXShlbnVtX3R5 cGUgdikgbm9leGNlcHRcblx0e1xuXHRcdHJldHVybiBkYXRhW3N0YXRpY19j YXN0PHVuZGVybHlpbmc+KHYpXTtcblx0fVxuXHRcblx0Y29uc3RleHByIGNv bnN0IGF1dG8mIG9wZXJhdG9yW10oZW51bV90eXBlIHYpIGNvbnN0IG5vZXhj ZXB0XG5cdHtcblx0XHRyZXR1cm4gZGF0YVtzdGF0aWNfY2FzdDx1bmRlcmx5 aW5nPih2KV07XG5cdH1cblx0XG5cdGNvbnN0ZXhwciBhdXRvIHNpemUoKSBj b25zdCB7IHJldHVybiBudW1iZXJfb2ZfdmFsdWVzOyB9XG5cdFxuICAgIHBy aXZhdGU6XG5cdHN0ZDo6YXJyYXk8VCxudW1iZXJfb2ZfdmFsdWVzPiBkYXRh e307XG59O1xuXG50ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgZW51 bV90eXBlPlxudXNpbmcgZW51bV9tYXBfd2l0aF9udW09ZW51bV9tYXA8VCxl bnVtX3R5cGUsc3RhdGljX2Nhc3Q8c3RkOjp1bmRlcmx5aW5nX3R5cGVfdDxl bnVtX3R5cGU+PihlbnVtX3R5cGU6Om51bSk+O1xuXG5lbnVtIGNsYXNzIHJl Z2lzdGVyOFxue1xuXHRDLEIsRSxELEwsSCxGLEEsIG51bVxufTtcblx0XG5l bnVtIGNsYXNzIHJlZ2lzdGVyMTZcbntcblx0QkMsIERFLCBITCwgQUYsIFNQ LCBQQywgbnVtXG59O1xuXG5jbGFzcyBzaW1wbGVfY3B1c3RhdGVfZW51bV9w cm94eVxue1xuXHRwdWJsaWM6XG5cdGNvbnN0ZXhwciBzdGQ6OnVpbnQxNl90 JiBvcGVyYXRvcltdKHJlZ2lzdGVyMTYgaWQpIG5vZXhjZXB0XG5cdHtcblx0 XHRyZXR1cm4gcmVnaXN0ZXJzX1tpZF07XG5cdH1cblxuXHRjb25zdGV4cHIg Ynl0ZV9wcm94eSBvcGVyYXRvcltdKHJlZ2lzdGVyOCBpZCkgbm9leGNlcHRc blx0e1xuXHRcdGNvbnN0IGF1dG8gaWR4PXN0YXRpY19jYXN0PDo6c3RkOjp1 bmRlcmx5aW5nX3R5cGVfdDxyZWdpc3Rlcjg+PihpZCk7XG5cdFx0cmV0dXJu IHtyZWdpc3RlcnNfW3JlZ2lzdGVyMTZ7aWR4LzJ9XSwoaWR4JTIpKjh1fTtc blx0fVxuXHRcblx0cHJpdmF0ZTpcblx0ZW51bV9tYXBfd2l0aF9udW08c3Rk Ojp1aW50MTZfdCwgcmVnaXN0ZXIxNj4gcmVnaXN0ZXJzXztcbn07XG5cbnVu aW9uIHJlZ2lzdGVyX3VuaW9uXG57XG4gICAgc3RkOjp1aW50MTZfdCBjb21i aW5lZDsgc3RkOjp1aW50OF90IHBhcnRzWzJdO1xufTtcblxuc3RydWN0IHNp bXBsZV9jcHVzdGF0ZV91bmlvblxue1xuICAgIHJlZ2lzdGVyX3VuaW9uIEJD LCBERSwgSEwsIEFGLCBTUCwgUEM7XG59O1xuXG5zaW1wbGVfY3B1c3RhdGVf ZW51bV9wcm94eSBtYWdpY19lbnVtKCk7XG5zaW1wbGVfY3B1c3RhdGVfdW5p b24gbWFnaWNfdW5pb24oKTtcblxuaW50IHRlc3RfZW51bSgpXG57XG4gICAg YXV0byBzdGF0ZT1tYWdpY19lbnVtKCk7XG4gICAgcmV0dXJuIHN0YXRlW3Jl Z2lzdGVyODo6QV0rc3RhdGVbcmVnaXN0ZXIxNjo6U1BdO1xufVxuXG5pbnQg dGVzdF91bmlvbigpXG57XG4gICAgYXV0byBzdGF0ZT1tYWdpY191bmlvbigp O1xuICAgIHJldHVybiBzdGF0ZS5BRi5wYXJ0c1sxXStzdGF0ZS5TUC5jb21i aW5lZDtcbn1cblxuaW50IHRlc3RfZW51bTIoKVxue1xuICAgIGF1dG8gc3Rh dGU9bWFnaWNfZW51bSgpO1xuICAgIHJldHVybiBzdGF0ZVtyZWdpc3Rlcjg6 OkZdK3N0YXRlW3JlZ2lzdGVyMTY6OlNQXTtcbn1cblxuaW50IHRlc3RfdW5p b24yKClcbntcbiAgICBhdXRvIHN0YXRlPW1hZ2ljX3VuaW9uKCk7XG4gICAg cmV0dXJuIHN0YXRlLkFGLnBhcnRzWzBdK3N0YXRlLlNQLmNvbWJpbmVkO1xu fVxuXG5zaW1wbGVfY3B1c3RhdGVfZW51bV9wcm94eSYgbWFnaWNfZW51bV9y ZWYoKTtcbnNpbXBsZV9jcHVzdGF0ZV91bmlvbiYgbWFnaWNfdW5pb25fcmVm KCk7XG5cbnZvaWQgdGVzdF9lbnVtMyhpbnQgdilcbntcbiAgICBhdXRvJiBz dGF0ZT1tYWdpY19lbnVtX3JlZigpO1xuICAgIHN0YXRlW3JlZ2lzdGVyODo6 Rl09djtcbn1cblxudm9pZCB0ZXN0X3VuaW9uMyhpbnQgdilcbntcbiAgICBh dXRvJiBzdGF0ZT1tYWdpY191bmlvbl9yZWYoKTtcbiAgICBzdGF0ZS5BRi5w YXJ0c1swXT12O1xufVxuXG52b2lkIHRlc3RfZW51bTQoaW50IHYpXG57XG4g ICAgYXV0byYgc3RhdGU9bWFnaWNfZW51bV9yZWYoKTtcbiAgICBzdGF0ZVty ZWdpc3Rlcjg6OkFdPXY7XG59XG5cbnZvaWQgdGVzdF91bmlvbjQoaW50IHYp XG57XG4gICAgYXV0byYgc3RhdGU9bWFnaWNfdW5pb25fcmVmKCk7XG4gICAg c3RhdGUuQUYucGFydHNbMV09djtcbn1cbiIsCiAgICAgICJjb21waWxlcnMi OiBbCiAgICAgICAgewogICAgICAgICAgImlkIjogImNsYW5nX3RydW5rIiwK ICAgICAgICAgICJvcHRpb25zIjogIi1PMiAtc3RkPWMrKzE3IgogICAgICAg IH0KICAgICAgXSwKICAgICAgImV4ZWN1dG9ycyI6IFtdCiAgICB9CiAgXQp9 Cg== "><img class="svg-logo-link" src="/assets/compiler_explorer_logo.svg" /></a>
</div>
</p>

<p>In it I compare and contrast two simplified versions of the cpu state. One - <em>simple_cpustate_enum_proxy</em> - using the constructs described above and another one - <em>simple_cpustate_union</em> - using a simple union. I introduce, without defining, two functions to conjure up instances of those types. This is done to prevent the compiler from optimizing everything away. As it cannot “see through” those calls it has to actually generate code to extract the values we are interested in. If you have a look at the compiler explorer link, you will however discover it manages to see through everything else I have done. The assembly generated for both cases is completely identical. <a href="https://www.youtube.com/watch?v=bSkpMdDe4g4">Compilers really are amazing!</a></p>

<p>Yes, <a href="https://www.youtube.com/watch?v=rHIkrotSwcc">there are no zero cost abstractions</a>, but the cost here is purely on the developer side and its a cost payed for a clear benefit of well defined and clear code. The issues one had to think about when constructing it were issues that ought to be thought about anyway and the resulting constructs are more generally useful. I consider this a net win.</p>

<h1 id="outlook">Outlook</h1>

<p>Let’s recap: I’ve argued that emulation is important, developing an emulator is fun and educational and the Game Boy is a great device to get started. I briefly explained why and how emulation works and elaborated on a small, but important, implementation detail. I believe this is enough for one article. In my next post on the topic, I shall dive deeper into the exact workings of the CPU, how to implement the various supported instructions and how to efficiently integrate all of that into a larger, exchangeable and as such easily testable system. It will be more technical and I promise to cut down on the long introductions.<br />
Thank you very much for reading. I am eagerly awaiting your constructive feedback, destructive feedback, insults and threats of violence.</p>

<hr />

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:readers" role="doc-endnote">
      <p>whom am I kidding here? It’s not like I have “many readers” yet xD <a href="#fnref:readers" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:skip" role="doc-endnote">
      <p>Feel free to skip this section or any of the following if all the generic talk and ruminations about motivations are not to your liking. Until I get started with <a href="#how">“How?”</a> none of the sections really depend on previous ones. <a href="#fnref:skip" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:turing_machine" role="doc-endnote">
      <p>In some respects it is even more powerful, as it is defined to have an infinitely long tape(i.e. infinite memory). Modern machines using finite memory can only be in a limited amount of states and could as such even be modeled as a “simple” <a href="https://en.wikipedia.org/wiki/Finite-state_machine">Finite State Machine</a> <a href="#fnref:turing_machine" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:bleem" role="doc-endnote">
      <p>In Sonys case it is simply <a href="https://en.wikipedia.org/wiki/PCSX-Reloaded">a well known open source emulator</a>, which is kind of interesting, given their <a href="https://en.wikipedia.org/wiki/Bleem!">controversial history with third-party emulator development</a>. <a href="#fnref:bleem" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:vt" role="doc-endnote">
      <p>it was before my time, but I would love to own one. <a href="#fnref:vt" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:linux_term" role="doc-endnote">
      <p>It is also fascinating to note that Linux was originally created because Linus Torvalds was unhappy with what Minix provided and decided to write a terminal emulator to connect to his universities computer. I’d recommend a reading of <a href="https://www.goodreads.com/book/show/160171.Just_for_Fun">his autobiography</a>, it is quite interesting. <a href="#fnref:linux_term" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:hardware_death" role="doc-endnote">
      <p>I have some unnatural and unhealthy attachment to all my devices, even to the point of naming them. Whenever any of them breaks down beyond repair I run through the usual stages of grief but somehow - just as in real life - I never quite manage to get to the acceptance part. <a href="#fnref:hardware_death" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:reading_speed" role="doc-endnote">
      <p>Assuming I judge your reading speed correctly. If not, I apologize. <a href="#fnref:reading_speed" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:brian" role="doc-endnote">
      <p>of awk and C and unix and… fame. Really, if you don’t know who he is read up on him and all the phenomenal work he produced. Computer science and computing would not be the same without him. <a href="#fnref:brian" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:rock" role="doc-endnote">
      <p>I really don’t mean to be offensive here. I have no problem with living under a rock. Live wherever you feel comfortable. I can quite understand a desire to get away from humanities mad inhuman noise. <a href="#fnref:rock" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:credit_gulfgb" role="doc-endnote">
      <p>Image taken with gratitude from <a href="https://commons.wikimedia.org/wiki/File:Game_boy_damaged_in_the_gulf_war.JPG">here</a> <a href="#fnref:credit_gulfgb" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:chip8" role="doc-endnote">
      <p>Why not start with something even more simple then. Why not choose the ubiquitously mentioned <a href="https://en.wikipedia.org/wiki/CHIP-8">Chip8</a> for instance? Well, the truth is, I did. A few years ago on a particularly uneventful weekend that was my first emulator. If you feel overwhelmed by complexity I suggest taking a look at it. With its 35 opcodes and very simple display it can really help getting started and developing a general feel for how to structure an emulator. <a href="#fnref:chip8" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:assumption" role="doc-endnote">
      <p>Technically, that phrasing is wrong of course, as “we” don’t “want to do” anything really and I describe what it is I already did. Nonetheless, to simply my writing and make it more directly relevant to you, I shall, from this point on, simply assume you wish to do something similar to what I did. <a href="#fnref:assumption" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:as_if" role="doc-endnote">
      <p>That is very similar to a rule in the C++ Standard. The <a href="https://en.cppreference.com/w/cpp/language/as_if">as-if rule</a> is essentially what allows the compiler to optimize the horrendous code we present it with. It is allowed to transform what we have written in absolutely any way, provided we cannot observe it and the perceived result is the same, except for performance. In the case of emulators, of course, performance is correctness and can be observed. <a href="#fnref:as_if" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:simulation" role="doc-endnote">
      <p>A short time ago, Matt Godbolt(of <a href="https://godbolt.org/">Compiler Explorer</a> fame) and Jason Turner(best known for <a href="https://www.youtube.com/playlist?list=PLs3KjaCtOwSZ2tbuV1hx8Xz-rFZTan2J1">C++ Weekly</a> and <a href="https://cppcast.com/">CppCast</a>), both of which are far more knowledgeable and much better versed in all this than I could hope to be, did <a href="https://www.youtube.com/watch?v=DbSRetQP-Xg">an interesting livestream</a> where they discussed this(among a lot of other things). They also showcased <a href="http://www.visual6502.org/">this awesome project.</a> <a href="#fnref:simulation" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:language" role="doc-endnote">
      <p>Those who know me and those who skimmed over the tags assigned to this post might have guessed already ;-) <a href="#fnref:language" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:variant" role="doc-endnote">
      <p>This source of hard to predict errors is the reason unions are usually paired with a tag/discriminator to remember which part is currently active. Even that is still quite error prone as it relies on programmer discipline to check the tag and act accordingly, which is why safer alternatives, like <a href="https://en.cppreference.com/w/cpp/utility/variant">std::variant</a>, exist. <a href="#fnref:variant" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:ubsan" role="doc-endnote">
      <p>There are <a href="https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html">great tools</a> out there to help you catch such code before the damage is done. <a href="#fnref:ubsan" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:blanket" role="doc-endnote">
      <p>It should not make too much of a difference, but blanket statements like that without any evidence are rarely a good idea. It would have been better to do some measurements or at least count which kind of access is more frequent. <a href="#fnref:blanket" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:murphy" role="doc-endnote">
      <p>This is a <a href="https://comp.lang.cpp.moderated.narkive.com/nWMq40v6/murphy-vs-machiavelli-who-coined-it">common expression</a> used to describe that C++ does not try to fight intentional, malicious attempts to subvert its rules, only accidental ones. <a href="#fnref:murphy" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:excerpt" role="doc-endnote">
      <p>The part displayed here is only an excerpt, you can click on the description to download the complete file or on the compiler explorer link to view it on there. <a href="#fnref:excerpt" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Hannah Lenk</name><email>hannah.lenk@codemetas.de</email></author><category term="c++" /><category term="klobigb" /><category term="gb" /><category term="emulation" /><summary type="html"><![CDATA[Some of you might have read my rather grandiose and ever so slightly over-dramatic announcement of things to come. Among other writings I promised to share my insignificant little Game Boy emulator and today I shall finally make good on that promise. Or at least begin to do so. Or tell you about intending to begin doing so at some later date, maybe. We’ll see.]]></summary></entry><entry><title type="html">Why?</title><link href="http://localhost:4000/2020/05/16/why.html" rel="alternate" type="text/html" title="Why?" /><published>2020-05-16T00:09:49+02:00</published><updated>2020-05-16T00:09:49+02:00</updated><id>http://localhost:4000/2020/05/16/why</id><content type="html" xml:base="http://localhost:4000/2020/05/16/why.html"><![CDATA[<p><em>So I finally did it! Like thousands<sup id="fnref:blog_number" role="doc-noteref"><a href="#fn:blog_number" class="footnote" rel="footnote">1</a></sup> before me I started a blog. I deemed my opinion relevant enough to throw it out into the world. I finally mustered the courage to let it be consumed, criticized, dissected and regurgitated. Which leaves but one question: Why? And why should you care? And how come I am off by one?<sup id="fnref:off_by" role="doc-noteref"><a href="#fn:off_by" class="footnote" rel="footnote">2</a></sup></em></p>

<p>It might not be immediately apparent, but what you are looking at right now is, at least for me, a major achievement. I am not talking about the site itself, not the style and presentation. That consisted of merely some minor adjustments to html and css liquid templates plus a really small amount of ruby code, whilst most of the real work is gracefully handled by jekyll in the background. Not even the server setup was done by me, as this page is gratefully handled by the free github pages service. I am not even talking about the grandiose content presented here, as - a keen reader might have realized already - at the time of writing content is pretty much inexistent. No, what it is I am talking about is this blogs very existence. The fact that some stranger on the internet is currently reading those lines I have so carelessly written is testament to my success, irrefutable proof that I have actually managed to - in ever so small a way - overcome my insecurities, have convinced myself that it is ok to present something to the world, to show part of me and my work and be judged for it.</p>

<p>Somehow this feels simultaneously like one of the most frightening and least significant things I have ever done. This dichotomy deserves to be explored. Maybe if I share and analyze my thoughts on the matter it will motivate and encourage someone just like similar posts have motivated and encouraged me.</p>

<p>“Similar posts?” I hear you utter in disbelief. “Aren’t you a very special and unique snowflake without equal”? Maybe I am. Maybe we all are. Nonetheless, I am most certainly not the first person struggling with this particular dilemma and I will clearly not be the last.<sup id="fnref:redundancy" role="doc-noteref"><a href="#fn:redundancy" class="footnote" rel="footnote">3</a></sup> A simple search query of “blog why” returns a literal cornucopia of results<sup id="fnref:literal" role="doc-noteref"><a href="#fn:literal" class="footnote" rel="footnote">4</a></sup>, all telling you in detail how blogging is a wonderful investment of any developers time and energy and can greatly advance ones skillset and career.</p>

<p>Alright. I guess that is it then. I am done. Others have made my point for me and better than I possibly could. Google to learn more…</p>

<p>Yet… that’s not true, is it? At least it can’t be all there is to my story. All those excellent reasons so eloquently expressed in others posts existed for all my life, I have been acutely aware of them for at least a decade, but I decided to spam the world now, not before. Why? It has to be a little more intricate, more personal than this…</p>

<p><em>So join me - if you dare - on a grand journey of self-reflection, of dissecting why I do the things I do.<sup id="fnref:writing_practice" role="doc-noteref"><a href="#fn:writing_practice" class="footnote" rel="footnote">5</a></sup> A deep dive into my feelings and motivations that will leave you with a better understanding of what to expect from future posts and wondering: “How on earth did I manage to read all that”.</em></p>

<h1 id="teaching">Teaching</h1>

<p>At this point, you know what you are in for. This is personal. This is about me. As such, you will indulge me some unabashed and shameless self-promotion.</p>

<p>I fancy myself as a teacher, and a good one at that. If I wouldn’t mind being arrogant and believed the concept had any merit, I might go so far as to claim a certain talent for it, but I prefer to say it is a passion.
School itself might not always have been my most favorite thing in the world, but I can’t remember a time at which I did not enjoy learning new things. What I seem to enjoy even more so is telling others about it. For as far back as I can remember I had a certain penchant for pestering people with everything I learned or liked, trying to share both enthusiasm and knowledge whenever the opportunity presented itself<sup id="fnref:annoy_opportunity" role="doc-noteref"><a href="#fn:annoy_opportunity" class="footnote" rel="footnote">6</a></sup>, relishing at every chance to discuss and debate, quite to the annoyance of many a peer.</p>

<p>What really made me aware of just how important this is for me and that I could - even should - teach at a larger and more professional scale was taking on a job as a TA at university. A job I first took on reluctantly.<br />
In the early days of my studies I was in desperate need of money to ensure I could continue. I quite liked academia, so I specifically searched for jobs my university had to offer. There were two which piqued my interest: One was only about grading homework for a beginners programming course, the other also involved grading, but in addition one was expected to instruct what was called a “Praktikum”. That meant being present in a room full of students working on their homework, answering all questions and assisting with all problems they might encounter. This did have some appeal to me but, as I am a really shy person, I dared not apply and chose the first.</p>

<p>My interviewer wasn’t having any of that insecurity nonsense so. Not only did he tell me right from the start that he loved my application and thought I was perfect for the job I applied for, he went one further and told me he was responsible for the aforementioned “Praktikum” and asked if I would be interested in getting that job instead. This was the first job interview I cared about and I was so relieved it went well and felt so flattered that I simply agreed outright, ignoring for a brief moment the debilitating terror I felt at the scary prospect of standing and talking in front of a crowd of strangers. Strangers who had expectations of me and potentially needed my help. Once the initial enthusiasm waned I was certain to have spelled my own doom. Rarely have I been so wrong.</p>

<p>For almost 7 years I was employed by Humboldt University. I had the honor of not only grading homework and exams, supervising tutorials and lecturing classes but even designing courses. Name pretty much any compulsory undergraduate course for computer science taught there and chances are I have been involved in its teaching. 
What I originally thought to be a bother turned out to bring me more joy and fulfillment than I could have ever anticipated. I learned far more from teaching than I did from attending classes. It brought me respect, friendships and did more for my feelings of self worth and relevance than pretty much anything else I have ever done. I was certain of being a positive influence on the lives of others and it would not be far fetched to claim it gave some meaning to my own.</p>

<p>Alas, this has now come to an end. I left university early this year and already miss it. Whilst I am now attempting to earn a living as a freelancer and am available to being hired not only for software development, but also for training/teaching by individuals and companies alike, this has not happened yet.<sup id="fnref:corona" role="doc-noteref"><a href="#fn:corona" class="footnote" rel="footnote">7</a></sup> As such I am deprived of this joy and in desperate need of some outlet to convey what little knowledge I have and engage with others who share my interests. I hope a blog can serve that purpose.</p>

<h1 id="learning">Learning</h1>

<p>In addition to helping others improve, I also wish to improve myself, which in turn will hopefully transform me into a better educator. Once again, allow me to elaborate why I think blogging helps with this by sharing unnecessary and embarrassing details about myself.</p>

<p>When I received my first computer I was fascinated by what it could do. But I also wanted it to do more. I wanted to play, but without any games and my parents displaying - much to my chagrin - quite an aversion to buying me any I had no choice. I did what anyone in my position would have done and set out to build my own. How hard could it possibly be? I opened a texteditor and typed “bild.bmp bewegbar”<sup id="fnref:move" role="doc-noteref"><a href="#fn:move" class="footnote" rel="footnote">8</a></sup>, saved it with an “.exe” extension and was completely dumbfounded when nothing at all happened on a double click. It was completely non-obvious to my childish mind that what I had described was completely non-obvious and far too inaccurate for my dear computer to understand.</p>

<p>Unfortunately I do not remember exactly when this was, I think it must have been at the tender age of about 10, but from that point on I was hooked. I had to understand how that stuff worked. It still took some more time until I arrived at actually writing something that could be called code. For a short while I was content with creating stupid quiz games by hyperlinking excel sheets, but once I discovered a book about <a href="https://en.wikipedia.org/wiki/Blitz_BASIC">BlitzBasic</a> in my local library the damage was really done.</p>

<p>As you can see, I originally got into programming because - like any reasonable child and adult should - I wanted to create games. But I stayed with it for so much more. What I discovered was not merely a tool to create worlds following my rules, but a tool to understand the one around me. Programming really taught me, more than anything else ever did, how to go about comprehending things and how to structure my thoughts. The need to accurately describe what it is we want our code to do forces us to dissect and refine our own understanding and mental models, to be precise about what our words mean, to peel back layers of abstraction. The desire to build systems that exceed what we can keep in mind at any one time forces us to categorize, to generalize, to build abstractions. Being confronted with compilers telling us we are wrong and more often than not being right about it teaches us to accept errors, to embrace and learn from them and to adjust our beliefs to conform to the evidence of reality. I believe learning to code improves more than just coding, it shapes ones mind.</p>

<p>Teaching shares many of the same qualities. In having to break a topic down and extract the essence to provide a reasonably structured explanation, I am bound to increase the depth of my own knowledge. Interacting with students and being confronted with questions that do not even appear in my own mind, I will naturally acquire a better understanding of the depth of my own ignorance.</p>

<p>I believe writing, too, does have that quality. Being forced to organize ones thoughts in order to put them into words others can understand and follow, to phrase them for easy consumption, exposes flaws in our thinking, necessitates a deeper understanding.<br />
I recently came across a quote summing this up perfectly<sup id="fnref:quote_origin" role="doc-noteref"><a href="#fn:quote_origin" class="footnote" rel="footnote">9</a></sup>:</p>

<blockquote>
  <p>Writing is nature’s way of showing us how sloppy our thinking is.</p>
</blockquote>

<h1 id="sharing">Sharing</h1>

<p>I have an annoying tendency to encourage others to put themselves out there, to show their work - however imperfect -  to not be afraid of criticism but embrace it and follow the maxim that if we are to be condemned, we should at least be condemned for what we really are. Yet, I never really swallowed my own medicine, I failed to heed my own advice and it is about time I changed that.</p>

<p>One of the many reasons I failed to do so before now is my belief that the final product of whatever endeavor I set out to complete itself does not adequately reflect the work put in. I strongly belief that it is more important <em>how</em> one thinks and arrives at a conclusion than <em>what</em> the conclusion turns out to be.
Consequently in my case, I always felt very very afraid of releasing code into wild, fearing something in there - taken in isolation - could reflect badly on me as a developer.<br />
Don’t get me wrong, I am convinced well written code can and should stand largely on its own and littering with comments is horrible practice. If there is something relevant the code does not express on its own this more often than not implies it ought to be rewritten, not commented.</p>

<p>What I am not as convinced of is that all of my code is well written<sup id="fnref:code_quality" role="doc-noteref"><a href="#fn:code_quality" class="footnote" rel="footnote">10</a></sup>. Furthermore, there are many considerations that go into writing code that - whilst not directly relevant when working with it - are highly interesting when trying to learn from it. Thinking about the overall design process, alternatives considered, reasons for choosing specific trade-offs over others and so on can be quite illuminating and educational.</p>

<p>Therefore, instead of just throwing the result out there, I feel much more comfortable sitting down with someone and explaining my process. Blog posts doing the same thing seem like a reasonable middle ground. They allow me to share so others can profit whilst simultaneously satisfying my delusions of grandeur and desperate need to justify my decisions.</p>

<h1 id="bragging">Bragging?</h1>

<p>And then there is my vanity. I have always been simultaneously desperate for attention and horrifyingly scared of it. Always wanted to be adored but never wanted to be seen. I have decided to change the latter.</p>

<p>A recent personal incident quite uncomfortably forced me once again to confront my own mortality. Whilst I fully support the efforts of anti-deathists like famously <a href="https://en.wikipedia.org/wiki/Aubrey_de_Grey">Aubrey de Gray</a><sup id="fnref:aubrey" role="doc-noteref"><a href="#fn:aubrey" class="footnote" rel="footnote">11</a></sup> and believe vastly prolonged healthy lifespans are worth striving after and all counterarguments I ever heard or read are essentially either ageist or <a href="https://en.wikipedia.org/wiki/Stockholm_syndrome">stockholming</a> death<sup id="fnref:stockholming" role="doc-noteref"><a href="#fn:stockholming" class="footnote" rel="footnote">12</a></sup>, I realize that reaching this goal is at least somewhat uncertain and reaching mortality escape velocity within my ‘natural’ time is reasonably unlikely. <a href="https://en.wikipedia.org/wiki/Simulation_hypothesis">Simulation hypothesis</a>, the nigh inevitable emulation of all our minds in some coming supercomputer, parallel universes and similar arguments aside<sup id="fnref:simulation" role="doc-noteref"><a href="#fn:simulation" class="footnote" rel="footnote">13</a></sup> as well as the logically sound presumption that all religions promising some form of afterlife are various degrees of bullshit, I have no choice but to come to terms with meeting our omnipresently lurking bearer of the scythe. I should not fall in love with him<sup id="fnref:cape" role="doc-noteref"><a href="#fn:cape" class="footnote" rel="footnote">14</a></sup> or believe death to be the best thing since sliced bread<sup id="fnref:bread" role="doc-noteref"><a href="#fn:bread" class="footnote" rel="footnote">15</a></sup>, yet if I am to be a hostage anyway, I might as well enjoy it and try to reach an arrangement we both can - ironically - live with. At least for the time being.</p>

<p>Quite morbid, but how is this even remotely related to a puny blog like this?<br />
In the 2004 movie Troy there is one scene in particular which managed to leave a lasting impression on me<sup id="fnref:troy" role="doc-noteref"><a href="#fn:troy" class="footnote" rel="footnote">16</a></sup>. Before deciding whether or not to join the war effort, Achilles mother explained what she foresaw the choices would entail. Were he to stay at home he would live a peaceful and happy life, be loved by his wife and children who would remember him fondly as long as they lived. Yet in time he will be forgotten. Should he, in turn, decide to fight, his life will be short and painful for both him and his loved ones, but it will become legend, his legacy will last for thousands of years.</p>

<p>I always fancied, when faced with the choice Achilles was presented, I would immediately choose glory and remembrance over the pleasant, but ultimately forgettable life<sup id="fnref:choice" role="doc-noteref"><a href="#fn:choice" class="footnote" rel="footnote">17</a></sup>. Yet the harsh reality of the matter begs to differ. Thus far, I tumbled along in silence and solitude, gathering all my thoughts, ideas and actual products in the comfortable and criticism free dark recesses of my mind and hard drive. If I were to perish today, all that’s left of me is but a few memories, a bunch of junk and maybe some lingering resentment. Within a few years or decades at best no one will remember I was even here. I left no footprint on this world and what little marks I produced are centralized and like prints on sand in the desert, inevitably blown away, leaving no indication anyone ever tread that path.</p>

<p>If my ultimate demise is bound to be inevitable, then I want to at least make it noticed. Produce work that endures beyond me, that reflects and preserves what little it can of my person and personality. Which is why I have to change my behavior. Why I have to publish and showcase as much of my work as possible. Which is why I need to start building a legacy, no matter how insignificant.<sup id="fnref:significance" role="doc-noteref"><a href="#fn:significance" class="footnote" rel="footnote">18</a></sup></p>

<p>I have been accused of being a blind idealist before, but this last argument does not quite fit the character. It betrays a certain hypocrisy. Whilst I would love to pretend that this is all about helping and educating people, about sharing thoughts to benefit others I cannot honestly claim to be quite as selfless.<br />
All of the reasons outlined above might be good and honest ones I really do care about. But what - in turn - is my reason for caring about them? Do I teach because I want people to be educated? Or because I want it to be me they are educated by? Do I share ideas because they are beneficial? Or do I share ideas because I want it to be my ideas that are spread? Does it matter?</p>

<h1 id="do-intentions-matter">Do intentions matter?</h1>

<p>So my intentions are impure. Apparently, whilst I do wish to educate and help people, some non-negligible amount of my motivation is more self-serving. I want to improve. I want to advertise myself. I want to be known, admired and remembered.<br />
A commonly shared tip for writing articles online is to use the word “you” frequently. I am supposed to talk to you, dear reader, to address you personally, to make you feel valuable and relevant. I should ask not what my readers can do for me, but what I can do for my readers. It is about you. It is not about me. Except it really, really is.</p>

<p>Yet: Do my intentions even matter? It is not entirely self-evident that they do. I may be pretentious. But if I pretend to be good, aren’t my actions bound to be as well?</p>

<p>If a rich politician gives to a specific charity because he or she hopes to sway voters of a specific kind, to leave a specific impression on some specific segment of the population, why does it matter? Doesn’t the charity get money either way? Could this not save lives?<br />
Of course it can, yet nonetheless I proclaim there is an effective difference. I am clearly oversimplifying a bit, but I believe intentions matter partly because they are predictors of future behavior. The aforementioned politician will likely cease their donations once elected and nearing retirement or if public sentiment changes. Someone truly believing in a cause might not sway their opinions and actions quite so easily.<br />
If I start a blog because it might increase my visibility and hiring prospects, will I stop once hired or sufficiently well known? If I start a blog due to a passion for sharing and educating, I clearly won’t.</p>

<p>Yet none of this actually matters. I can truly care about others and myself simultaneously. Human beings are weird like that. There is no real conflict here. If I am unsure if my real motivations could be predominately selfish, but I don’t want them to be, all I can do is continue. Keep doing what I am doing to prove to others - and to myself - that what I claim are my motivations actually are and in so doing turn my words into truth either way.<br />
Some lies can become truth if enough people believe in them. For some its sufficient to believe strongly enough oneself and act accordingly.<sup id="fnref:fake_it" role="doc-noteref"><a href="#fn:fake_it" class="footnote" rel="footnote">19</a></sup></p>

<h1 id="so-what">So what?</h1>

<p>So here we are. I believe my voice is one that deserves to be heard. One that can be of some benefit to a non-empty subset of the population. And I shall prove it to myself and the world.</p>

<p>I am going to write about my personal projects, explaining my design and choices in detail, in the hope that it will be useful. I will gradually share my code and finally publish some of the things I have been holding back for far too long!<br />
I think I will start by writing about emulating the original GameBoy, as that is a more recently started and quite inconsequential project of mine which has been done to death by far more experienced developers than me. So if my writeup happens to be unclear but still manages to ignite some curiosity, there are myriad other sources to consult.
After that I will probably publish and detail my chess engine, my forays into hobbyist operating system development and a scripting language I designed for use with my retro game engine.<br />
Whenever I encounter or learn of anything new and interesting, I shall consider writing about it. Whenever I repeatedly explain something in private, I shall assume it could be of general interest and try to put my explanations in accessible writing for a broader, public audience.<br />
If mood strikes, I might even write some generic articles delineating my thoughts and feelings on topics far removed from software development.<br />
I am also open to suggestions:</p>

<blockquote>
  <p>If there is something particular you, dear reader, would like to learn about and it happens to be within my area of expertise I will gladly be of service and try to write about that.</p>
</blockquote>

<p>I hope someone out there enjoys part of it. If so, even if I stop and fail, it has been well worth it.</p>

<p>Thank you for staying with me till the very end. As compensation, you shall receive a cookie 🍪 and my eternal gratitude. How on earth did you manage to read all that?</p>

<hr />

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:blog_number" role="doc-endnote">
      <p><a href="https://hostingtribunal.com/blog/how-many-blogs/">nay, millions</a> <a href="#fnref:blog_number" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:off_by" role="doc-endnote">
      <p>well, technically that is off by two now… <a href="#fnref:off_by" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:redundancy" role="doc-endnote">
      <p>if I were this post would be even more redundant, wouldn’t it? <a href="#fnref:redundancy" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:literal" role="doc-endnote">
      <p>by literal I obviously mean figurative and just chose the word to annoy purists. I have no clue what a cornucopia of search results could possibly look like… <a href="#fnref:literal" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:writing_practice" role="doc-endnote">
      <p>and in so doing getting some much needed writing practice <a href="#fnref:writing_practice" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:annoy_opportunity" role="doc-endnote">
      <p>and often when it did not <a href="#fnref:annoy_opportunity" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:corona" role="doc-endnote">
      <p>and <a href="https://en.wikipedia.org/wiki/COVID-19_pandemic">the current corona pandemic</a> might put a certain dent in that particular industry <a href="#fnref:corona" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:move" role="doc-endnote">
      <p>“bewegbar” is german for “movable” <a href="#fnref:move" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:quote_origin" role="doc-endnote">
      <p>In <a href="https://www.youtube.com/watch?v=WxbrhruIAa8">a youtube video of a talk about operating system development using Rust</a>, where Leslie Lamport was cited as citing Dick Guindon with putting the statement into a comic strip. Well, extra levels of indirection are a good thing, right? I’d also like to add that whilst I enjoyed the talk, I disagree with part of it. I believe <a href="https://wiki.osdev.org/Main_Page">the osdev wiki</a> is an amazing resource. <a href="#fnref:quote_origin" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:code_quality" role="doc-endnote">
      <p>so I do try. Perfection is something I strife after, alas it remains elusive and unattainable <a href="#fnref:code_quality" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:aubrey" role="doc-endnote">
      <p>I hope by applying this term I did not misrepresent his position, which I believe is more nuanced than it would suggest. If so, I apologize <a href="#fnref:aubrey" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:stockholming" role="doc-endnote">
      <p>more often than not both <a href="#fnref:stockholming" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:simulation" role="doc-endnote">
      <p>which all also raise quite interesting questions of identity <a href="#fnref:simulation" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:cape" role="doc-endnote">
      <p>so one has to admit that cape does look rather awesome <a href="#fnref:cape" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:bread" role="doc-endnote">
      <p>which incidentally does a pretty good job of delaying it <a href="#fnref:bread" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:troy" role="doc-endnote">
      <p>it being the only scene I really remember might reflect somewhat on the overall quality of the movie, but lets leave that aside for now. I also don’t know if the original Illiad contained an equivalent, as to my great shame, I have never read it <a href="#fnref:troy" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:choice" role="doc-endnote">
      <p>ok, i don’t think id be down for all the fighting and killing bits involved as i am a rather anxious and fearful person, but you get the general idea… <a href="#fnref:choice" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:significance" role="doc-endnote">
      <p>and it does seem quite insignificant <a href="#fnref:significance" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:fake_it" role="doc-endnote">
      <p>I know, I could have simply written “Fake it till you make it” and be done with it, but that is getting kind of old now, isn’t it? <a href="#fnref:fake_it" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Hannah Lenk</name><email>hannah.lenk@codemetas.de</email></author><category term="blogging" /><category term="meta" /><summary type="html"><![CDATA[So I finally did it! Like thousands1 before me I started a blog. I deemed my opinion relevant enough to throw it out into the world. I finally mustered the courage to let it be consumed, criticized, dissected and regurgitated. Which leaves but one question: Why? And why should you care? And how come I am off by one?2 nay, millions &#8617; well, technically that is off by two now… &#8617;]]></summary></entry></feed>