<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>samgeo.codes</title>
    <subtitle>Sam Eisenhandler&#x27;s personal blog containing ramblings about a variety of software-related topics.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://samgeo.codes/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://samgeo.codes"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-07-14T00:00:00+00:00</updated>
    <id>https://samgeo.codes/atom.xml</id>
    <entry xml:lang="en">
        <title>Resource management and generators in Python</title>
        <published>2024-07-14T00:00:00+00:00</published>
        <updated>2024-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/python-generator-cleanup/"/>
        <id>https://samgeo.codes/python-generator-cleanup/</id>
        
        <content type="html" xml:base="https://samgeo.codes/python-generator-cleanup/">&lt;p&gt;I was pairing with a colleague on some asynchronous streaming abstractions&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; implemented in Python.
I realized that there are some pretty significant footguns with predictable cleanup in async generators.&lt;&#x2F;p&gt;
&lt;p&gt;In fact, the same footguns are present in &lt;em&gt;normal&lt;&#x2F;em&gt; generators, but don&#x27;t cause quite as many issues as in async generators. Crucially, we can observe unexpected cleanup behavior when we don&#x27;t fully consume a generator.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take a look!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;__future__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;annotations
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;itertools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;time
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;collections.abc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Generator
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; Generator[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Contrived example wrapping an infinite iterator in some cleanup code.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;yield from &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;itertools.count(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;cleaned up&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    generator &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;gen()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# We break out of this loop early, meaning we have not fully consumed `generator`.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;generator:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(elem)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;break
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;finished iterating&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Perform some expensive operation.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;main()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;python-generator-cleanup&#x2F;0.html&quot;&gt;Run with PyScript&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When running this, the output looks something like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fcf0ca;color:#282828aa;&quot;&gt;&lt;code&gt;&lt;span&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;3
&lt;&#x2F;span&gt;&lt;span&gt;4
&lt;&#x2F;span&gt;&lt;span&gt;finished iterating
&lt;&#x2F;span&gt;&lt;span&gt;cleaned up
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The order of these print statements suggests that the cleanup code only gets executed at the exit of the function (e.g. when the reference count of the generator object is decremented to &lt;code&gt;0&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;We can do a &lt;em&gt;little&lt;&#x2F;em&gt; bit better by inlining the call to &lt;code&gt;gen&lt;&#x2F;code&gt; &lt;em&gt;or&lt;&#x2F;em&gt; explicitly using the &lt;code&gt;del&lt;&#x2F;code&gt; statement to ensure that the generator is cleaned up &lt;em&gt;before&lt;&#x2F;em&gt; we start some expensive operation. In this contrived example, it doesn&#x27;t seem like that big of a deal, but it can often be desirable to relinquish resources (such as open file descriptors or database connections) as soon as we&#x27;re finished with them.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;__future__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;annotations
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;itertools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;time
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;collections.abc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Generator
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; Generator[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;yield from &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;itertools.count(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;cleaned up&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;gen()&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(elem)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;break
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;finished iterating&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Perform some expensive operation.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;main()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;python-generator-cleanup&#x2F;1.html&quot;&gt;Run with PyScript&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The output this time:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fcf0ca;color:#282828aa;&quot;&gt;&lt;code&gt;&lt;span&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;3
&lt;&#x2F;span&gt;&lt;span&gt;4
&lt;&#x2F;span&gt;&lt;span&gt;cleaned up
&lt;&#x2F;span&gt;&lt;span&gt;finished iterating
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So we clean up first! However, this relies pretty heavily on some implementation details of CPython. In fact, when I run this same code with &lt;code&gt;pypy&lt;&#x2F;code&gt;, the cleanup never gets run&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;! So what options do we have?&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take a look at some of the code in the standard library; specifically, let&#x27;s look at &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;python&#x2F;cpython&#x2F;blob&#x2F;3.12&#x2F;Lib&#x2F;_collections_abc.py&quot;&gt;&lt;code&gt;Lib&#x2F;_collections_abc.py&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; to get a better sense of what operations may be available on generators.&lt;&#x2F;p&gt;
&lt;p&gt;This snippet seems promising:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;class &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Generator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Iterator&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__slots__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__next__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return the next item from the generator.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;        When exhausted, raise StopIteration.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self.send(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;abstractmethod
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;send&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Send a value into the generator.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;        Return next yielded value or raise StopIteration.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;StopIteration
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;abstractmethod
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;throw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;typ&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;val&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;tb&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Raise an exception in the generator.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;        Return next yielded value or raise StopIteration.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;val &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;tb &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span&gt;typ
&lt;&#x2F;span&gt;&lt;span&gt;            val &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;typ()
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;tb &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;is not &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            val &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;val.with_traceback(tb)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span&gt;val
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;close&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Raise GeneratorExit inside generator.
&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self.throw(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;GeneratorExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;except &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;GeneratorExit&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;StopIteration&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pass
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;RuntimeError&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;generator ignored GeneratorExit&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    @&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;classmethod
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;__subclasshook__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;cls&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;cls &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;is &lt;&#x2F;span&gt;&lt;span&gt;Generator:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;_check_methods(C, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;__iter__&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;__next__&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;                                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;send&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;throw&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;close&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;NotImplemented
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In particular, this suggests that generators have a &lt;code&gt;close&lt;&#x2F;code&gt; method!&lt;&#x2F;p&gt;
&lt;p&gt;So what happens if we explicitly invoke &lt;code&gt;close&lt;&#x2F;code&gt; on our generator after we&#x27;ve finished iteration?&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;__future__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;annotations
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;itertools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;time
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;collections.abc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Generator
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; Generator[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;yield from &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;itertools.count(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;cleaned up&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    generator &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;gen()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;generator:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(elem)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;break
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;generator.close()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;finished iterating&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Perform some expensive operation.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;main()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;python-generator-cleanup&#x2F;2.html&quot;&gt;Run with PyScript&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Running with both CPython and &lt;code&gt;pypy&lt;&#x2F;code&gt; seems to work as desired! But we can even do a little bit better using the &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;contextlib.html#contextlib.closing&quot;&gt;&lt;code&gt;closing&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; context manager from &lt;code&gt;contextlib&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;__future__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;annotations
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;itertools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;time
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;collections.abc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Generator
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;contextlib &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;closing
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; Generator[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;yield from &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;itertools.count(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;cleaned up&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;closing(gen()) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;generator:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;generator:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(elem)
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;break
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;finished iterating&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Perform some expensive operation.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;main()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;python-generator-cleanup&#x2F;3.html&quot;&gt;Run with PyScript&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Even when an exception is raised out of the body of the &lt;code&gt;for&lt;&#x2F;code&gt; loop, we&#x27;ll still invoke the generator cleanup.&lt;&#x2F;p&gt;
&lt;p&gt;Cool, so we have finally arrived at a sensible idiom for ensuring that we invoke cleanup code with reasonable confidence (as much confidence as the chosen Python runtime can provide, at least).&lt;&#x2F;p&gt;
&lt;p&gt;In practice, very few people write code like this; CPython cleanup behavior is fairly predictable. But what happens when we venture into &amp;quot;asyncland&amp;quot;? Here&#x27;s a similar example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;__future__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;annotations
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;asyncio
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;itertools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;collections.abc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;AsyncGenerator
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; AsyncGenerator[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# `yield from` is not supported in async generators
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;itertools.count(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;yield &lt;&#x2F;span&gt;&lt;span&gt;x
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Required to enable &amp;quot;cancellation&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Clean up&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    generator &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;gen()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async for &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;generator:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(elem)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;break
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;finished iterating&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Perform some expensive operation.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.run(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;python-generator-cleanup&#x2F;4.html&quot;&gt;Run with PyScript&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Running this with CPython demonstrates an issue very similar to what we observed when running the normal generator examples with &lt;code&gt;pypy&lt;&#x2F;code&gt;: the cleanup code is simply never run! But wait, when we run this using &lt;code&gt;pypy&lt;&#x2F;code&gt;, the cleanup code gets run?!&lt;&#x2F;p&gt;
&lt;p&gt;This is related to how async generator cleanup is managed: the event loop is required to register async generator hooks so that the language runtime can communicate with the event loop when an async generator object gets &amp;quot;finalized&amp;quot; (the work associated with cleaning up an unused object during garbage collection).&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re curious why the &lt;code&gt;await asyncio.sleep(0)&lt;&#x2F;code&gt; is there: &lt;code&gt;asyncio.run&lt;&#x2F;code&gt; will invoke &lt;code&gt;cancel&lt;&#x2F;code&gt; on outstanding tasks once the provided coroutine has finished execution. The async generator cleanup task is one such task. When omitting the &lt;code&gt;asyncio.sleep(0)&lt;&#x2F;code&gt;, the print statement is executed.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s make the similar adjustment of inlining the &lt;code&gt;gen&lt;&#x2F;code&gt; call into the &lt;code&gt;async for&lt;&#x2F;code&gt; loop and see what happens:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;__future__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;annotations
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;asyncio
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;itertools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;collections.abc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;AsyncGenerator
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; AsyncGenerator[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;itertools.count(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;yield &lt;&#x2F;span&gt;&lt;span&gt;x
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Required for &amp;quot;reasons&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Clean up&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async for &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;gen()&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(elem)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;break
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;finished iterating&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Perform some expensive operation.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.run(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;python-generator-cleanup&#x2F;5.html&quot;&gt;Run with PyScript&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With CPython, the cleanup is now executed. This is because the generator is finalized as we exit the &lt;code&gt;async for&lt;&#x2F;code&gt; loop, so the cleanup task is scheduled &lt;em&gt;before&lt;&#x2F;em&gt; the &lt;code&gt;await syncio.sleep(1)&lt;&#x2F;code&gt; which allows the event loop to &amp;quot;work on&amp;quot; the cleanup task prior to the completion of the coroutine. With &lt;code&gt;pypy&lt;&#x2F;code&gt;, the cleanup is still executed, but due to the differences in garbage collection behavior, only after the &lt;code&gt;await asyncio.sleep(1)&lt;&#x2F;code&gt; completes.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, let&#x27;s take a look at using a similar explicit cleanup idiom with async code. The &lt;code&gt;contextlib&lt;&#x2F;code&gt; library provides an asynchronous variant of the &lt;code&gt;closing&lt;&#x2F;code&gt; context manager called &lt;code&gt;aclosing&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;__future__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;annotations
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;asyncio
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;itertools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;collections.abc &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;AsyncGenerator
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;contextlib &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;aclosing
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; AsyncGenerator[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;itertools.count(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;yield &lt;&#x2F;span&gt;&lt;span&gt;x
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Required for &amp;quot;reasons&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Clean up&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;aclosing(gen()) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;generator:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async for &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span&gt;generator:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(elem)
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span&gt;elem &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;break
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;finished iterating&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# Perform some expensive operation.
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.run(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;python-generator-cleanup&#x2F;6.html&quot;&gt;Run with PyScript&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This code has consistent, reliable behavior across both CPython and &lt;code&gt;pypy&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;There are some extra reasons why explicit cleanup code is &lt;em&gt;especially&lt;&#x2F;em&gt; important in async code:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;different event loop implementations may implement async generator hooks differently; so there is more surface area for weird behavior (see some of the linked PyScript examples which use Pyodide&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;pyodide.org&#x2F;en&#x2F;stable&#x2F;usage&#x2F;api&#x2F;python-api&#x2F;webloop.html&quot;&gt;webloop&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;cleanup code that uses runtime context (e.g. inspects the currently running async task) will observe the runtime context of the tasks started by the event loop&#x27;s async generator hooks&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s probably a reasonably good practice to follow predictable cleanup idioms when using generators (async or not). Practically, it seems unlikely that most folks will use these idioms with normal generators, but you should really consider applying these idioms when interacting with async generators.&lt;&#x2F;p&gt;
&lt;p&gt;I learned a &lt;em&gt;ton&lt;&#x2F;em&gt; while researching this post. Async generators are an interesting example of a language feature that requires the language runtime to work in tandem with an async event loop. Async generator cleanup used to be magic but now I think I have a reasonable mental model of what is going on and have a better sense of the idioms that might help to ensure predictable behavior.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;additional-reading&quot;&gt;Additional reading&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0525&#x2F;&quot;&gt;PEP 525&lt;&#x2F;a&gt;: The PEP that describes async generators and their implementation. Includes details about async generator hooks.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0533&#x2F;&quot;&gt;PEP 533&lt;&#x2F;a&gt;: A &amp;quot;deferred&amp;quot; PEP that proposes extensions to synchronous and asynchronous iterator protocols to support deterministic cleanup in for loops.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;contextlib.html#contextlib.aclosing&quot;&gt;contextlib documentation&lt;&#x2F;a&gt;: The first place that I noticed the &lt;code&gt;async with aclosing(gen()) as generator:&lt;&#x2F;code&gt; idiom.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;Lots of &amp;quot;streaming&amp;quot; when working with language models to improve UX of high-latency completions.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;2&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;2&lt;&#x2F;sup&gt;
&lt;p&gt;CPython leverages reference counting with a generation garbage collector only for dealing with cyclic references. PyPy uses its own incremental garbage collector (and no reference counting). &lt;a href=&quot;https:&#x2F;&#x2F;doc.pypy.org&#x2F;en&#x2F;latest&#x2F;cpython_differences.html#differences-related-to-garbage-collection-strategies&quot;&gt;PyPy&#x27;s docs&lt;&#x2F;a&gt; provide a reasonable discussion of some of the differences.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Return Statement</title>
        <published>2023-07-15T00:00:00+00:00</published>
        <updated>2023-07-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/recurse-return/"/>
        <id>https://samgeo.codes/recurse-return/</id>
        
        <content type="html" xml:base="https://samgeo.codes/recurse-return/">&lt;p&gt;Long story short, my batch at the &lt;a href=&quot;https:&#x2F;&#x2F;www.recurse.com&#x2F;&quot;&gt;Recurse Center&lt;&#x2F;a&gt; at the beginning of
this year constituted the best 3 months of my life.&lt;&#x2F;p&gt;
&lt;p&gt;For the first 20-some years of my life, there was always a logical next step, something to work toward.
There were activities that I enjoyed, but ultimately my day to day was structured around reaching the next milestone.&lt;&#x2F;p&gt;
&lt;p&gt;My time at RC has helped me embrace the day-to-day and find joy in creating software.
Instead of using my career as a means to an end, my new high-level goal is to use my career as a means to learn, grow and
build valuable tools for myself and others.&lt;&#x2F;p&gt;
&lt;p&gt;RC encourages you to introspect and find intrinsic motivation, while fostering an inquisitive, supportive community.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s so much more I could write; and I plan to include much of that in future posts. But I&#x27;ve procrastinated long enough writing this post. RC was a life-changing experience and I would recommend it to anyone who can find the time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Understanding the costs of our abstractions</title>
        <published>2023-02-21T00:00:00+00:00</published>
        <updated>2023-02-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/layers-of-abstraction/"/>
        <id>https://samgeo.codes/layers-of-abstraction/</id>
        
        <content type="html" xml:base="https://samgeo.codes/layers-of-abstraction/">&lt;p&gt;Since the beginning of February, there has been a big conversation about
client-side JavaScript in the web development community.&lt;&#x2F;p&gt;
&lt;p&gt;There has been a salvo of blog posts discussing the performance implications of
single page applications:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Alex Russell&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;infrequently.org&#x2F;2023&#x2F;02&#x2F;the-market-for-lemons&#x2F;&quot;&gt;The Market for Lemons&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Eric Bailey&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;ericwbailey.website&#x2F;published&#x2F;modern-health-frameworks-performance-and-harm&#x2F;&quot;&gt;Modern Health, frameworks, performance, and harm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Laurie Voss&#x27; &lt;a href=&quot;https:&#x2F;&#x2F;seldo.com&#x2F;posts&#x2F;the_case_for_frameworks&#x2F;&quot;&gt;The case for frameworks&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These posts and the resources linked within are worth reading. I think this
is an interesting conversation, and I think the ideas extend far beyond
front end web development. I spent a lot of time listening to podcasts in the
car this past week, and there has been a common thread in many of the discussions
that I&#x27;ve listened to: abstractions have (sometimes hidden) costs.&lt;&#x2F;p&gt;
&lt;p&gt;How can we do a better job of choosing the right abstractions as an industry?&lt;&#x2F;p&gt;
&lt;p&gt;I could try to write a bunch about incentive structures, scope creep and
rising complexity. But I think most of what I have to say boils down to this:
we should aspire to understand the benefits and costs of the abstractions that we build on top of.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;understanding-abstractions&quot;&gt;Understanding abstractions&lt;&#x2F;h2&gt;
&lt;p&gt;Most software projects are built atop a perilously tall stack of abstractions.&lt;&#x2F;p&gt;
&lt;p&gt;Joel Spolsky wrote a post entitled &lt;a href=&quot;https:&#x2F;&#x2F;www.joelonsoftware.com&#x2F;2002&#x2F;11&#x2F;11&#x2F;the-law-of-leaky-abstractions&#x2F;&quot;&gt;The Law of Leaky Abstractions&lt;&#x2F;a&gt;
in 2002 claiming:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;All non-trivial abstractions, to some degree, are leaky.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;To build context for this claim, Joel uses TCP as an example noting that
under certain circumstances, the unreliable nature of the network will leak
through the reliability guarantees that TCP provides. Unfortunately, Joel
omits an important detail: TCP is not free, it comes with a &lt;em&gt;lot&lt;&#x2F;em&gt; of overhead.&lt;&#x2F;p&gt;
&lt;p&gt;TCP provides a variety of features including packet ordering: for the code that
uses TCP, packets &lt;em&gt;appear&lt;&#x2F;em&gt; to arrive in the order they were sent. Many applications
don&#x27;t require all of the features that TCP provides, but many of those applications
still use TCP (or even HTTP) under the hood. Check out these resources for more
information about the tradeoffs that TCP makes in a couple of different applications:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;913260&#x2F;&quot;&gt;Moving past TCP in the data center&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;signalsandthreads.com&#x2F;multicast-and-the-markets&#x2F;&quot;&gt;Multicast and the Markets&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;react&quot;&gt;React&lt;&#x2F;h3&gt;
&lt;p&gt;We can apply the same thought process to React and similar client-side JavaScript
abstractions. My oversimplified perspective: React aims to provide a declarative
alternative to imperative web APIs for providing real-time interactivity.&lt;&#x2F;p&gt;
&lt;p&gt;The web API provides methods like &lt;code&gt;Element.append()&lt;&#x2F;code&gt; or enables mutation of
&lt;code&gt;innerHTML&lt;&#x2F;code&gt; to directly modify the text contents of a document element.
React enables programmers to specify the desired state of a document fragment
and promises to make the necessary adjustments to the document. In many ways
React with JSX imitates the style of many popular backend web frameworks
(look at Rails, Django or almost any PHP application). There are several benefits
to the declarative interface but I think the most important benefit is
composability. Since React components behave like pure functions, they can be
reused in myriad ways. But those benefits are not free, React can balloon bundle sizes and increase
the time it takes for an application to become interactive.&lt;&#x2F;p&gt;
&lt;p&gt;If your application does not need real-time interactivity, the benefits of
declarative components are low or your application does not leverage many of the
features that React provides, you should probably seek a simpler alternative.&lt;&#x2F;p&gt;
&lt;p&gt;Eric Bailey describes their experience using a mental health portal that has
an endless spinner due to a deadlock in client-side JavaScript.
Can most users of a mental health portal wait for the latency of an HTTP request
when they interact with the page? Probably. Maybe there is a chat feature in the
portal where a client-side component library is valuable; but even still, it
doesn&#x27;t seem like a use case that necessitates React.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;python-and-high-level-scripting-languages&quot;&gt;Python and high-level scripting languages&lt;&#x2F;h3&gt;
&lt;p&gt;There are a few technologists that have derided the overuse of high-level
scripting languages like Python and Ruby. Many of these folks come from the
game development space where performance is paramount. Two of the loudest voices
in the room are Jonathan Blow (see &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=pW-SOdj4Kkk&quot;&gt;Preventing the Collapse of Civilization&lt;&#x2F;a&gt;)
and Casey Muratori (see &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=hxM8QmyZXtg&quot;&gt;How fast should an unoptimized terminal run?&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Casey recently started a &amp;quot;Performance-Aware Programming&amp;quot; series. So far,
Casey has published a prologue that compares the performance of
naiively adding two integers in Python with a variety of implementations in C,
ultimately getting close to optimal with the use of SIMD instructions and
multi-threading. Casey achieves a staggering ~8,000x speedup over the Python implementation.
Casey wraps up the prologue by demonstrating and benchmarking alternative
summation implementations in Python.&lt;&#x2F;p&gt;
&lt;p&gt;During these videos, Casey describes the interpreter overhead of Python
as &amp;quot;waste&amp;quot;. I think this discounts the value that high-level interpreted
programming languages provide. As a self-described static
typing fanatic, I still find Python to be significantly easier to use for creating
rapid prototypes than languages like Rust, C++ or C. For getting up and running,
Python and similar languages enable you to focus more on the problem that you&#x27;re
trying to solve and less on the mechanics of the language that you&#x27;re using
to solve that problem. Not to mention, Python has a huge batteries-included
standard library and an enormous ecosystem of third-party libraries to lean on.&lt;&#x2F;p&gt;
&lt;p&gt;I believe that scripting languages are a good choice as long as you acknowledge
the performance and maintainability tradeoffs that you are making. Often,
this explicit acknowledgement or context is missing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;leaving-a-paper-trail&quot;&gt;Leaving a paper trail&lt;&#x2F;h2&gt;
&lt;p&gt;When we make decisions about the tools and technologies that we use to build
applications in a professional setting, we should aim to leave a paper trail.
Even if the rationale for using a particular technology is &amp;quot;we needed to get
started and this was the most popular option,&amp;quot; that is valuable context!&lt;&#x2F;p&gt;
&lt;p&gt;When we have that context, we can make informed decisions about how to move
forward, whether that means forging ahead with the existing choices or making
adjustments to set ourselves up for the future.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, outside of a professional setting or when writing software for yourself,
use whatever you want! If you want to experiment with React, experiment with React.
If you want to &lt;a href=&quot;https:&#x2F;&#x2F;oxide.computer&#x2F;podcasts&#x2F;oxide-and-friends&#x2F;1208089&quot;&gt;write C++ in the comfort of your own home&lt;&#x2F;a&gt;, do it!
But when writing software professionally or for a larger audience, it&#x27;s significantly
more important to think about the implications of the decisions we make. When
that consideration is missing, we&#x27;re doing a disservice to our colleagues and our users.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Day 1</title>
        <published>2023-01-23T00:00:00+00:00</published>
        <updated>2023-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/series/aoc2022/day01/"/>
        <id>https://samgeo.codes/series/aoc2022/day01/</id>
        
        <content type="html" xml:base="https://samgeo.codes/series/aoc2022/day01/">&lt;p&gt;Day 1! A great place to start.&lt;&#x2F;p&gt;
&lt;p&gt;I previously wrote a &lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;aoc-template&#x2F;&quot;&gt;post&lt;&#x2F;a&gt; discussing some basic templates for getting started
with Advent of Code in Python and JavaScript. I think that&#x27;s a solid place to
start, but I like to use something a little bit different for Python.&lt;&#x2F;p&gt;
&lt;p&gt;In particular, &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;fileinput.html&quot;&gt;fileinput&lt;&#x2F;a&gt;
reads input files line-by-line which can occasionally make it awkward to parse
certain inputs. You know what? Let&#x27;s try day 1 using the template I suggest and
then see if we can make some basic improvements.&lt;&#x2F;p&gt;
&lt;p&gt;In case you forgot, the template looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;fileinput
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;lines &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fileinput.input()&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To store my solutions, I use a directory named &lt;code&gt;2022&lt;&#x2F;code&gt;. Since I am going to
produce solutions using both Python and Rust, I have the subdirectories &lt;code&gt;py&lt;&#x2F;code&gt;,
&lt;code&gt;rust&lt;&#x2F;code&gt; and &lt;code&gt;input&lt;&#x2F;code&gt;. To get started, I&#x27;m going to save my Python template under &lt;code&gt;2022&#x2F;py&#x2F;day01&#x2F;sol.py&lt;&#x2F;code&gt;
and my input under &lt;code&gt;2022&#x2F;input&#x2F;01&#x2F;input.txt&lt;&#x2F;code&gt;. I am also going to save the example input
under &lt;code&gt;2022&#x2F;input&#x2F;01&#x2F;example.txt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So far, my directory structure looks like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fcf0ca;color:#282828aa;&quot;&gt;&lt;code&gt;&lt;span&gt;.
&lt;&#x2F;span&gt;&lt;span&gt;└── 2022&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    ├── input&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │   └── 01&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │       ├── input.txt
&lt;&#x2F;span&gt;&lt;span&gt;    │       └── example.txt
&lt;&#x2F;span&gt;&lt;span&gt;    ├── py&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │   └── day01&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │       └── sol.py
&lt;&#x2F;span&gt;&lt;span&gt;    └── rust
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;problem-statement&quot;&gt;Problem statement&lt;&#x2F;h2&gt;
&lt;p&gt;The example input looks like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fcf0ca;color:#282828aa;&quot;&gt;&lt;code&gt;&lt;span&gt;1000
&lt;&#x2F;span&gt;&lt;span&gt;2000
&lt;&#x2F;span&gt;&lt;span&gt;3000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;4000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;5000
&lt;&#x2F;span&gt;&lt;span&gt;6000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;7000
&lt;&#x2F;span&gt;&lt;span&gt;8000
&lt;&#x2F;span&gt;&lt;span&gt;9000
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;10000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each contiguous group of lines represents the food carried by a single elf.
Each line within each group represents the calories contained within a single
food item.&lt;&#x2F;p&gt;
&lt;p&gt;For part one, we want to find the elf carrying the most total calories.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;2022&#x2F;day&#x2F;1&quot;&gt;Link&lt;&#x2F;a&gt; to the prompt if you want some
festive winteriness.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;let-s-go&quot;&gt;Let&#x27;s go!&lt;&#x2F;h2&gt;
&lt;p&gt;If we go ahead and print out our lines:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;fileinput
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;lines &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fileinput.input()&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(lines)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When we run our solution against the example, this is what we get:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python py&#x2F;day01&#x2F;sol.py input&#x2F;01&#x2F;example.txt
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;1000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;2000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;3000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;4000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;5000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;6000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;7000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;8000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;9000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;#39;10000&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It might be easier to rebuild the input and then re-split to divide our input into
one section per elf, then we can process each of those sections. We&#x27;ll define
a helper function to determine the total calories that a single elf is carrying.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;generator-expressions&quot;&gt;Generator Expressions&lt;&#x2F;h3&gt;
&lt;p&gt;Many people are familiar with
&lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;tutorial&#x2F;datastructures.html#list-comprehensions&quot;&gt;list comprehensions&lt;&#x2F;a&gt;.
&lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0289&#x2F;&quot;&gt;Generator expressions&lt;&#x2F;a&gt; behave very similarly
to list comprehensions but have lazy semantics: they don&#x27;t compute elements
until they are asked for. We will see some great parallels with Rust&#x27;s iterators
later in the post. Unlike iterators in Rust, generator expressions have some
runtime overhead because Python is an interpreted language.&lt;&#x2F;p&gt;
&lt;p&gt;In general, I like to use generator expressions instead of list comprehensions
when feasible. For most applications, list comprehensions
are just fine (and might even be faster), but when working with potentially large collections, it can be
prohibitively expensive to materialize the entire collection in-memory.&lt;&#x2F;p&gt;
&lt;p&gt;Some may see this as an unnecessary optimization, but I like to get into habits
that lead to reasonably fast code.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ll use a few Python built-ins for our solution:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;functions.html#int&quot;&gt;&lt;code&gt;int&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: constructs an integer from a number or a string&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;functions.html#sum&quot;&gt;&lt;code&gt;sum&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: sums the items of an &lt;em&gt;iterable&lt;&#x2F;em&gt;, note that generator expressions produce iterables&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;functions.html#max&quot;&gt;&lt;code&gt;max&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;: finds the largest item in an &lt;em&gt;iterable&lt;&#x2F;em&gt;; again note that generator expressions produce iterables&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With that all in mind, let&#x27;s see what our solution to part one looks like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;fileinput
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;total_calories&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(item) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;item &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;lines &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fileinput.input()&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;puzzle_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.join(lines)
&lt;&#x2F;span&gt;&lt;span&gt;sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s run it against the example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python py&#x2F;day01&#x2F;sol.py input&#x2F;01&#x2F;example.txt
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 24000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s what we wanted! Let&#x27;s see if we can run it against our input:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python py&#x2F;day01&#x2F;sol.py input&#x2F;01&#x2F;input.txt
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 70509
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We enter that into the website and hooray! One star! Off to a great
start.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;part-two&quot;&gt;Part Two&lt;&#x2F;h2&gt;
&lt;p&gt;Now we want the total of the top 3 elves!&lt;&#x2F;p&gt;
&lt;p&gt;We can use &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;functions.html#sorted&quot;&gt;&lt;code&gt;sorted&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
(which also accepts an iterable, noticing a trend?)
to make a sorted list of all of the elves, then take the top 3:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;fileinput
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;total_calories&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(item) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;item &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;lines &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fileinput.input()&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;puzzle_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.join(lines)
&lt;&#x2F;span&gt;&lt;span&gt;sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;top_three &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sorted&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:]
&lt;&#x2F;span&gt;&lt;span&gt;solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(top_three)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s run it against the example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python py&#x2F;day01&#x2F;sol.py input&#x2F;01&#x2F;example.txt
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 24000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part two: 45000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Neato! We&#x27;re on a roll.&lt;&#x2F;p&gt;
&lt;p&gt;Now on our input:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python py&#x2F;day01&#x2F;sol.py input&#x2F;01&#x2F;input.txt
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 70509
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part two: 208567
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;improvements&quot;&gt;Improvements&lt;&#x2F;h2&gt;
&lt;p&gt;Maybe we can do a little bit better, while also learning a bit more about the
(unnecessarily enormous) Python standard library!&lt;&#x2F;p&gt;
&lt;p&gt;First, let&#x27;s try to pull our solution into function scope. We&#x27;ll check to see
if our solution module should be run by comparing the global value &lt;code&gt;__name__&lt;&#x2F;code&gt;
against the string &lt;code&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;code&gt;. Check out the &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;tutorial&#x2F;modules.html#tut-modules&quot;&gt;Modules&lt;&#x2F;a&gt;
section of the Python tutorial for more details.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;fileinput
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;total_calories&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(item) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;item &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;():
&lt;&#x2F;span&gt;&lt;span&gt;    lines &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fileinput.input()&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    puzzle_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.join(lines)
&lt;&#x2F;span&gt;&lt;span&gt;    sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    top_three &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sorted&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:]
&lt;&#x2F;span&gt;&lt;span&gt;    solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(top_three)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;main()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As mentioned above, using &lt;code&gt;fileinput&lt;&#x2F;code&gt; is pretty awkward since we are basically
reconstructing our input from the file contents, anyway. Let&#x27;s define a helper
module to make reading input a little bit nicer. We&#x27;ll put this module in the file
&lt;code&gt;2022&#x2F;py&#x2F;read_input.py&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;argparse
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;pathlib &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Path
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;read_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;day&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    parser &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;argparse.ArgumentParser()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;parser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;input&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, nargs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;?&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, default&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;input.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    args &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;parser.parse_args()
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    padded_day &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(day).rjust(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;0&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    filename &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Path(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;input&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;padded_day &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&#x2F; &lt;&#x2F;span&gt;&lt;span&gt;args.input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;with &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;open&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(filename) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;as &lt;&#x2F;span&gt;&lt;span&gt;f:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;f.read()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I guess there&#x27;s a few things to mention, here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What&#x27;s that &lt;code&gt; -&amp;gt; str&lt;&#x2F;code&gt; nonsense?&lt;&#x2F;strong&gt;: That&#x27;s a return value type hint.
Check out the &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;typing.html&quot;&gt;&lt;code&gt;typing&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; module documentation for more information.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;argparse&lt;&#x2F;code&gt; standard library module allows you to write simple CLI scripts. There are a lot of
great argument parsing libraries available on &lt;a href=&quot;https:&#x2F;&#x2F;pypi.org&quot;&gt;PyPI&lt;&#x2F;a&gt;, but we don&#x27;t need to pull in any
external dependencies for &lt;code&gt;argparse&lt;&#x2F;code&gt; and it suits our needs just fine.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;code&gt;pathlib&lt;&#x2F;code&gt; standard library module makes it easy to build up file paths in a
platform-independent way.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now, to use this new module, we also need to add a blank &lt;code&gt;__init__.py&lt;&#x2F;code&gt; file to
our &lt;code&gt;2022&#x2F;py&lt;&#x2F;code&gt; directory; and while we&#x27;re at it, let&#x27;s add one to our &lt;code&gt;2022&#x2F;py&#x2F;day01&lt;&#x2F;code&gt; directory, as well:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ touch 2022&#x2F;py&#x2F;__init__.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ touch 2022&#x2F;py&#x2F;day01&#x2F;__init__.py
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This might all seem like a lot of boilerplate, but we won&#x27;t really touch any of
this after day 1!&lt;&#x2F;p&gt;
&lt;p&gt;Finally, we can use the new module in our solution:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;py.read_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;read_input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;total_calories&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(item) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;item &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;():
&lt;&#x2F;span&gt;&lt;span&gt;    puzzle_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;read_input(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    top_three &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sorted&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:]
&lt;&#x2F;span&gt;&lt;span&gt;    solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(top_three)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;main()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To avoid Python path nonsense we need to change our command line invocation
slightly:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python -m py.day01.sol
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 70509
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part two: 208567
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Still works! And now we don&#x27;t even need to enter the filename if we just want
to run against our input. Nice.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;type-hints&quot;&gt;Type Hints&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;m a bit of a type hinting fanatic: type hints help me avoid making careless
mistakes and force me to refine the flow of information around my programs.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s add them to what we have so far and we can try to keep everything working
as we restructure our program.&lt;&#x2F;p&gt;
&lt;p&gt;First, let&#x27;s set up a &lt;code&gt;venv&lt;&#x2F;code&gt; within our &lt;code&gt;py&lt;&#x2F;code&gt; subdirectory. I&#x27;m using
the &lt;code&gt;python3.11&lt;&#x2F;code&gt; binary installed on my machine, so that looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3.11 -m venv py&#x2F;.venv
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ source py&#x2F;.venv&#x2F;bin&#x2F;activate
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I personally like to use the &lt;code&gt;pyright&lt;&#x2F;code&gt; LSP, so I&#x27;ll go ahead and install the
dev tools that I typically use. If you want to follow along, at least install
&lt;code&gt;mypy&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ pip install pyright flake8 black mypy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s run &lt;code&gt;mypy&lt;&#x2F;code&gt; in strict mode:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;py&#x2F;day01&#x2F;sol.py:6: error: Function is missing a type annotation  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;no&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;untyped&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;py&#x2F;day01&#x2F;sol.py:10: error: Function is missing a return type annotation  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;no&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;untyped&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;py&#x2F;day01&#x2F;sol.py:10: note: Use &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;-&amp;gt; None&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; if function does not return a value
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;py&#x2F;day01&#x2F;sol.py:13: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;total_calories&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;no&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;untyped&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;py&#x2F;day01&#x2F;sol.py:15: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;total_calories&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;no&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;untyped&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;py&#x2F;day01&#x2F;sol.py:21: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;main&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;no&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;untyped&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;call&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 5 errors in 1 file (checked 4 source files&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Paydirt! Let&#x27;s go ahead and fix all of those. While we are at it, we will also
make &lt;code&gt;main&lt;&#x2F;code&gt; return an integer value so we can be a good command line citizen.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;py.read_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;read_input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;total_calories&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(item) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;item &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    puzzle_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;read_input(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;max&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    top_three &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sorted&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:]
&lt;&#x2F;span&gt;&lt;span&gt;    solution &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(top_three)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{solution}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we run &lt;code&gt;mypy&lt;&#x2F;code&gt; again:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Success: no issues found in 4 source files
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Huzzah!&lt;&#x2F;p&gt;
&lt;p&gt;Now, let&#x27;s see if we can identify some common ground between parts 1 and 2 and maybe
improve our runtime performance.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s consider the runtime complexity of the solution that we currently have. We&#x27;ll
say that \(I\) is the length of our input and \(N\) is the number of elves in the input.&lt;&#x2F;p&gt;
&lt;p&gt;Our part 1 boils down to a linear scan over our input, so it runs in \(O(I + N)\)
time (and \(N\) is bounded by \(I\), so it&#x27;s really \(O(I)\)). Our part 2 sorts the collection of elves, so it runs in \(O(I + N \log N)\) time.&lt;&#x2F;p&gt;
&lt;p&gt;Can we do better? Well, when we fetch the top 3 elves, we are discarding a bunch of
information that we spent time assembling when we sorted the entire collection of elves.
Maybe we can avoid doing all that work when we only really care about the top 3
elves. Heaps are a wonderful data structure that work perfectly for this kind of
operation (and they&#x27;re great to be aware of for all sorts of interview problems).
In particular, we can heapify a list of \(N\) elements in \(O(N)\) time. And then fetching
\(K\) elements from that heap takes \(O(K \log N)\) time. Since we want to fetch a constant number of
elements (\(3\)), the cost of fetching becomes \(O(\log N)\).&lt;&#x2F;p&gt;
&lt;p&gt;So if we can leverage a heap to solve the problem, we will have an \(O(I)\) solution!&lt;&#x2F;p&gt;
&lt;p&gt;There is a very handy module in the standard library called &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;heapq.html&quot;&gt;&lt;code&gt;heapq&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.
This library maintains the heap invariant (for a min-heap) atop a vanilla
Python list. It also has a couple of very handy functions: &lt;code&gt;nlargest&lt;&#x2F;code&gt; and &lt;code&gt;nsmallest&lt;&#x2F;code&gt;
for generating lists of the &lt;code&gt;n&lt;&#x2F;code&gt; largest or smallest elements, respectively.
And they do indeed first heapify the input collection and then fetch the first &lt;code&gt;n&lt;&#x2F;code&gt; elements.&lt;&#x2F;p&gt;
&lt;p&gt;And if we look at the documentation, it looks like the result is returned in
reverse sorted order, so we can also use the result for part 1!&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s see how we can use that and set up a bit of infrastructure for comparing
the new implementation with our original sort-based approach. I&#x27;ve adjusted
our original solution slightly to avoid some duplicate work.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;heapq &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;nlargest
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;time &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;perf_counter
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;typing &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Callable
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;py.read_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;read_input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;total_calories&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(item) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;item &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    top_three &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sorted&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections)&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;:]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;top_three[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(top_three)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;heap_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    top_three &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;nlargest(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, (total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections))
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;top_three[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(top_three)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    puzzle_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;read_input(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    expected_output &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sort_sol(puzzle_input)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{expected_output[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;]}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{expected_output[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;]}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;benchmark&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;solution&lt;&#x2F;span&gt;&lt;span&gt;: Callable[[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        start &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;perf_counter()
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;_ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;range&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;assert &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;solution(puzzle_input) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span&gt;expected_output
&lt;&#x2F;span&gt;&lt;span&gt;        end &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;perf_counter()
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;end &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;start
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Sort solution takes &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{benchmark(sort_sol)}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;s&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Heap solution takes &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{benchmark(heap_sol)}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;s&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s run it and see how much improvement we get!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python -m py.day01.sol example.txt
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 24000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part two: 45000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Sort solution takes 0.0033642500020505395s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Heap solution takes 0.0045546660003310535s
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you might be saying, &amp;quot;hey Sam, I thought using a heap would make things
&lt;em&gt;faster&lt;&#x2F;em&gt;, what gives?&amp;quot;&lt;&#x2F;p&gt;
&lt;p&gt;Well, unfortunately big-O analysis throws away a bunch of constants and it turns
out that in the real world, constants matter. &lt;code&gt;sorted&lt;&#x2F;code&gt; is very well optimized since
it is one of the most commonly used built-ins in Python.&lt;&#x2F;p&gt;
&lt;p&gt;This was just our example input, let&#x27;s try our real input:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python -m py.day01.sol
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 70509
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part two: 208567
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Sort solution takes 0.24173837499984074s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Heap solution takes 0.23308020799959195s
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Faster, but not by much.&lt;&#x2F;p&gt;
&lt;p&gt;Our puzzle input still only consists of 2237 elves. What if we crank that up
a little bit?&lt;&#x2F;p&gt;
&lt;p&gt;We replace our line &lt;code&gt;puzzle_input = read_input(1)&lt;&#x2F;code&gt; with
&lt;code&gt;puzzle_input = &amp;quot;\n\n&amp;quot;.join([read_input(1).strip()] * 1000)&lt;&#x2F;code&gt; and reduce
the number of benchmark iterations down to 10:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python -m py.day01.sol
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 70509
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part two: 211527
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Sort solution takes 2.4853763329992944s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Heap solution takes 2.3238277089985786s
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Better, but still not that satisfying of an improvement. I guess the two
lessons are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;constants matter&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;log&lt;&#x2F;code&gt; grows &lt;em&gt;very&lt;&#x2F;em&gt; slowly&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Let&#x27;s put our heap-based solution in place without all of the benchmarking
boilerplate:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;heapq &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;nlargest
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;py.read_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;read_input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;total_calories&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(item) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;item &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    puzzle_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;read_input(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    sections &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;puzzle_input.split(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    top_three &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;nlargest(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, (total_calories(section) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;section &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sections))
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{top_three[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;]}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(top_three)}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So now our directory structure looks like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fcf0ca;color:#282828aa;&quot;&gt;&lt;code&gt;&lt;span&gt;.
&lt;&#x2F;span&gt;&lt;span&gt;└── 2022&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    ├── input&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │   └── 01&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │       ├── input.txt
&lt;&#x2F;span&gt;&lt;span&gt;    │       └── example.txt
&lt;&#x2F;span&gt;&lt;span&gt;    ├── py&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │   ├── __init__.py
&lt;&#x2F;span&gt;&lt;span&gt;    │   ├── read_input.py
&lt;&#x2F;span&gt;&lt;span&gt;    │   └── 01&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    │       ├── __init__.py
&lt;&#x2F;span&gt;&lt;span&gt;    │       └── sol.py
&lt;&#x2F;span&gt;&lt;span&gt;    └── rust
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s enough Python for now, let&#x27;s see what this looks like in Rust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust&quot;&gt;Rust&lt;&#x2F;h2&gt;
&lt;p&gt;In Rust, I like to use a new crate for each day. I also like to use
the nightly toolchain so that I can play around with unstable features.&lt;&#x2F;p&gt;
&lt;p&gt;To get started, check out &lt;a href=&quot;https:&#x2F;&#x2F;rustup.rs&#x2F;&quot;&gt;&lt;code&gt;rustup&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For now, here is what my active toolchain looks like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ rustup show
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;active toolchain
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;----------------
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;nightly-aarch64-apple-darwin (default&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;rustc 1.69.0-nightly (5e37043d6 2023-01-22&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Alright, let&#x27;s get this show on the road!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo new rust&#x2F;day01 --vcs none --lib
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cd rust&#x2F;day01
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This creates a new binary crate without version control (hopefully you have
version control on your solutions). Your working directory should now look
something like this:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fcf0ca;color:#282828aa;&quot;&gt;&lt;code&gt;&lt;span&gt;.
&lt;&#x2F;span&gt;&lt;span&gt;└── day01&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;    ├── Cargo.toml
&lt;&#x2F;span&gt;&lt;span&gt;    └── src&#x2F;
&lt;&#x2F;span&gt;&lt;span&gt;        └── lib.rs
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And you&#x27;ll have the default &lt;code&gt;lib.rs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;left&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;right&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;usize &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    left &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span&gt; right
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span&gt;(test)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;mod &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;tests &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use super&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;it_works&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(result, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s try a similar comparison in Rust between a sort-based and heap-based
solution.&lt;&#x2F;p&gt;
&lt;p&gt;First, let&#x27;s define a function for the sort-based approach:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::error::Error;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; elves &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; input
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;            elf.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;lines&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line&lt;&#x2F;span&gt;&lt;span&gt;| -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; { line.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map_err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;From&lt;&#x2F;span&gt;&lt;span&gt;::from) })
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        })
&lt;&#x2F;span&gt;&lt;span&gt;        .collect::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_by&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;| b.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;cmp&lt;&#x2F;span&gt;&lt;span&gt;(a));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;((elves[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;take&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()))
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span&gt;(test)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;mod &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;tests &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use super&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;#&amp;quot;1000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;2000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;3000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;4000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;5000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;6000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;7000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;8000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;9000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;10000&amp;quot;#&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_sort_sol&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;24000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;45000&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This somewhat resembles our Python implementation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;we split the input into elf sections,&lt;&#x2F;li&gt;
&lt;li&gt;we calculate the sum of each section,&lt;&#x2F;li&gt;
&lt;li&gt;we sort the resulting collection and determine our results.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For the most part, Rust just makes us be a little bit more explicit about our
error conditions. This solution will still panic for empty inputs, for instance.
But our python solution would throw for lines that don&#x27;t contain valid integers.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s see if our test passes!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo test
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Compiling day01 v0.1.0 (&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day01&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Finished test &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;unoptimized + debuginfo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; target(s&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;in 0.45s
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running unittests src&#x2F;lib.rs (target&#x2F;debug&#x2F;deps&#x2F;day01-1b30f96f7eb97059&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 1 test
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_sort_sol ... ok
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 1 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Doc-tests day01
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 0 tests
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 0 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Excellent.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s wire it up into a binary by creating a &lt;code&gt;day01&#x2F;src&#x2F;bin&#x2F;main.rs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::error::Error;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;day01::sort_sol;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;include_str!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;..&#x2F;..&#x2F;..&#x2F;..&#x2F;input&#x2F;01&#x2F;input.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;(part1, part2) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(input)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Sort sol p1: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{part1}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;, p2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{part2}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s run it!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo run
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Compiling day01 v0.1.0 (&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day01&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Finished dev &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;unoptimized + debuginfo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; target(s&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;in 0.15s
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running `target&#x2F;debug&#x2F;main`
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Sort sol p1: 70509, p2: 208567
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Cool beans. Let&#x27;s try to get the heap implementation in place. We can use
the unstable &lt;code&gt;into_iter_sorted&lt;&#x2F;code&gt; function to convert a &lt;code&gt;BinaryHeap&lt;&#x2F;code&gt;
directly to an &lt;code&gt;Iterator&lt;&#x2F;code&gt; and then take the first 3 elements for part 2.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s what that looks like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;feature&lt;&#x2F;span&gt;&lt;span&gt;(binary_heap_into_iter_sorted)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::{collections::BinaryHeap, error::Error};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; elves &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; input
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;            elf.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;lines&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line&lt;&#x2F;span&gt;&lt;span&gt;| -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; { line.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map_err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;From&lt;&#x2F;span&gt;&lt;span&gt;::from) })
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        })
&lt;&#x2F;span&gt;&lt;span&gt;        .collect::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_by&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;| b.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;cmp&lt;&#x2F;span&gt;&lt;span&gt;(a));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;((elves[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;take&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()))
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;heap_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; elves &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; input
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;            elf.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;lines&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line&lt;&#x2F;span&gt;&lt;span&gt;| -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; { line.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map_err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;From&lt;&#x2F;span&gt;&lt;span&gt;::from) })
&lt;&#x2F;span&gt;&lt;span&gt;                .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        })
&lt;&#x2F;span&gt;&lt;span&gt;        .collect::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;BinaryHeap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;((
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;peek&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;        elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;into_iter_sorted&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;take&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span&gt;(test)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;mod &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;tests &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use super&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;#&amp;quot;1000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;2000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;3000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;4000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;5000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;6000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;7000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;8000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;9000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;10000&amp;quot;#&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_sort_sol&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;24000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;45000&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_heap_sol&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;heap_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;24000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;45000&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We run the tests...&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo test
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Compiling day01 v0.1.0 (&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day01&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Finished test &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;unoptimized + debuginfo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; target(s&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;in 0.23s
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running unittests src&#x2F;lib.rs (target&#x2F;debug&#x2F;deps&#x2F;day01-1b30f96f7eb97059&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 2 tests
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_heap_sol ... ok
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_sort_sol ... ok
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 2 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running unittests src&#x2F;bin&#x2F;main.rs (target&#x2F;debug&#x2F;deps&#x2F;main-abe929b1b2534503&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 0 tests
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 0 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Doc-tests day01
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 0 tests
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 0 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;wire it up to our binary...&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::error::Error;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;day01::{heap_sol, sort_sol};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;include_str!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;..&#x2F;..&#x2F;..&#x2F;..&#x2F;input&#x2F;01&#x2F;input.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;(sp1, sp2) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(input)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Sort sol p1: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{sp1}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;, p2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{sp2}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;(hp1, hp2) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;heap_sol&lt;&#x2F;span&gt;&lt;span&gt;(input)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Heap sol p1: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{hp1}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;, p2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{hp2}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and run it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo run
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Finished dev &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;unoptimized + debuginfo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; target(s&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;in 0.01s
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running `&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day01&#x2F;target&#x2F;debug&#x2F;main`
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Sort sol p1: 70509, p2: 208567
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Heap sol p1: 70509, p2: 208567
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Neat.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a little bit of common code that I feel like we should be able to pull
into it&#x27;s own function. Let&#x27;s give it a shot!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span&gt;#![&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;feature&lt;&#x2F;span&gt;&lt;span&gt;(binary_heap_into_iter_sorted)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::{collections::BinaryHeap, error::Error};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;AocResult&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;a&lt;&#x2F;span&gt;&lt;span&gt;, T&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;T, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;a&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;parse_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; impl &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Iterator&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;Item = AocResult&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    input.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elf&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;        elf.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;lines&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line&lt;&#x2F;span&gt;&lt;span&gt;| -&amp;gt; AocResult&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; { line.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map_err&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;From&lt;&#x2F;span&gt;&lt;span&gt;::from) })
&lt;&#x2F;span&gt;&lt;span&gt;            .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;    })
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; AocResult&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let mut&lt;&#x2F;span&gt;&lt;span&gt; elves &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse_input&lt;&#x2F;span&gt;&lt;span&gt;(input).collect::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_by&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;| b.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;cmp&lt;&#x2F;span&gt;&lt;span&gt;(a));
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;((elves[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;], elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;take&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()))
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;heap_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; AocResult&amp;lt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;)&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; elves &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse_input&lt;&#x2F;span&gt;&lt;span&gt;(input).collect::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;BinaryHeap&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;((
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;peek&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;        elves.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;into_iter_sorted&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;take&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;(),
&lt;&#x2F;span&gt;&lt;span&gt;    ))
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span&gt;(test)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;mod &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;tests &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use super&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;#&amp;quot;1000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;2000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;3000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;4000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;5000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;6000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;7000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;8000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;9000
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;10000&amp;quot;#&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_parse_input&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; AocResult&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;static&lt;&#x2F;span&gt;&lt;span&gt;, ()&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse_input&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;).collect::&amp;lt;AocResult&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;vec!&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;11000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;24000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;10000&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;        );
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_sort_sol&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; AocResult&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;static&lt;&#x2F;span&gt;&lt;span&gt;, ()&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sort_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;24000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;45000&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_heap_sol&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; AocResult&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;static&lt;&#x2F;span&gt;&lt;span&gt;, ()&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;heap_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;, (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;24000&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;45000&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now it&#x27;s time to see how our solutions compare.&lt;&#x2F;p&gt;
&lt;p&gt;For that we&#x27;ll use &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;criterion&#x2F;latest&#x2F;criterion&#x2F;&quot;&gt;Criterion.rs&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;First we install &lt;code&gt;criterion&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo add criterion
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we add a benchmark to our &lt;code&gt;Cargo.toml&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;toml&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-toml &quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;dev-dependencies&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;criterion &lt;&#x2F;span&gt;&lt;span&gt;= { &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;version &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;0.4.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;features &lt;&#x2F;span&gt;&lt;span&gt;= [&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;html_reports&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;] }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;[[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;bench&lt;&#x2F;span&gt;&lt;span&gt;]]
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;name &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;my_benchmark&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;harness &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;false
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And add our benchmark file &lt;code&gt;benches&#x2F;my_benchmark.rs&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::hint::black_box;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;criterion::{criterion_group, criterion_main, Criterion};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;INPUT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;include_str!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;..&#x2F;..&#x2F;..&#x2F;input&#x2F;01&#x2F;input.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;criterion_benchmark&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; Criterion) {
&lt;&#x2F;span&gt;&lt;span&gt;    c.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;bench_function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;sort_sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;| b.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;(|| day01::sort_sol(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;black_box&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;INPUT&lt;&#x2F;span&gt;&lt;span&gt;))));
&lt;&#x2F;span&gt;&lt;span&gt;    c.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;bench_function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;heap_sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;| b.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;(|| day01::heap_sol(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;black_box&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;INPUT&lt;&#x2F;span&gt;&lt;span&gt;))));
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;criterion_group!&lt;&#x2F;span&gt;&lt;span&gt;(benches, criterion_benchmark);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;criterion_main!&lt;&#x2F;span&gt;&lt;span&gt;(benches);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And now we run our benchmarks:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo bench
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running unittests src&#x2F;lib.rs (target&#x2F;release&#x2F;deps&#x2F;day01-aec6c446d7e6dd94&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 3 tests
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_heap_sol ... ignored
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_parse_input ... ignored
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_sort_sol ... ignored
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 0 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;3 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running unittests src&#x2F;bin&#x2F;main.rs (target&#x2F;release&#x2F;deps&#x2F;main-cc52451e5c082913&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 0 tests
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 0 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running benches&#x2F;my_benchmark.rs (target&#x2F;release&#x2F;deps&#x2F;my_benchmark-710fed971563135d&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Gnuplot not found, using plotters backend
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;sort_sol                time:   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;35.656 µs 35.678 µs 35.699 µs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;change: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;-0.1767% &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0.0397% +0.1173%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; (p = 0.60 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.05&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;No change in performance detected.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 5 outliers among 100 measurements (5.00%&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;5 (5.00%&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;high severe
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;heap_sol                time:   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;32.523 µs 32.553 µs 32.601 µs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;change: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;-0.3934% &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0.2565% &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0.1198%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; (p = 0.00 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.05&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Change within noise threshold.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 6 outliers among 100 measurements (6.00%&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;2 (2.00%&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;high mild
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;4 (4.00%&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;high severe
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nice, our heap solution is slightly faster than our sort solution. Also, 32 &lt;em&gt;microseconds&lt;&#x2F;em&gt;
is pretty quick... so quick that it&#x27;s not even really worth benchmarking our solution with &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sharkdp&#x2F;hyperfine&quot;&gt;hyperfine&lt;&#x2F;a&gt;.
We&#x27;ll save that for another time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;that-s-it&quot;&gt;That&#x27;s it!&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s all for now. Now that most of the boilerplate is out of the way, I&#x27;m hopeful that
the next several days will go much quicker! See you next time.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Day 2</title>
        <published>2023-01-23T00:00:00+00:00</published>
        <updated>2023-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/series/aoc2022/day02/"/>
        <id>https://samgeo.codes/series/aoc2022/day02/</id>
        
        <content type="html" xml:base="https://samgeo.codes/series/aoc2022/day02/">&lt;p&gt;Alright, day 2.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;problem-statement&quot;&gt;Problem statement&lt;&#x2F;h2&gt;
&lt;p&gt;Rock Paper Scissors!&lt;&#x2F;p&gt;
&lt;p&gt;We are given a &amp;quot;strategy guide&amp;quot; that looks like:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fcf0ca;color:#282828aa;&quot;&gt;&lt;code&gt;&lt;span&gt;A Y
&lt;&#x2F;span&gt;&lt;span&gt;B X
&lt;&#x2F;span&gt;&lt;span&gt;C Z
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and we need to follow the provided scheme.&lt;&#x2F;p&gt;
&lt;p&gt;We save the example as &lt;code&gt;input&#x2F;02&#x2F;example.txt&lt;&#x2F;code&gt; and our input as &lt;code&gt;input&#x2F;02&#x2F;input.txt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python-time&quot;&gt;Python time!&lt;&#x2F;h2&gt;
&lt;p&gt;We create our solution in &lt;code&gt;2022&#x2F;py&#x2F;day02&#x2F;sol.py&lt;&#x2F;code&gt; and add a blank &lt;code&gt;2022&#x2F;py&#x2F;day02&#x2F;__init__.py&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Software engineering best practices be damned, let&#x27;s hard code everything!
Since we know the score associated with each combination of moves, we can
create a dictionary that maps each combination to the final score:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2022&#x2F;py&#x2F;day02&#x2F;sol.py
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;py.read_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;read_input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;read_input(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    scores &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 1
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 2
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 3
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 1
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 2
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 3
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 1
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 2
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;    result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(scores[line.strip()] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.splitlines())
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{result}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Part two involves a different scoring scheme, so we can take the same approach
but with a different &lt;code&gt;scores&lt;&#x2F;code&gt; table:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2022&#x2F;py&#x2F;day02&#x2F;sol.py
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;typing &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Final, Iterable, Mapping
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;py.read_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;read_input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P1_SCORES&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 2
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 2
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 2
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 3
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P2_SCORES&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 1 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2 + 6
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 1 + 0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 6
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2 + 0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 1 + 6
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games&lt;&#x2F;span&gt;&lt;span&gt;: Iterable[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;table&lt;&#x2F;span&gt;&lt;span&gt;: Mapping[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(table[game] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;read_input(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    games &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.splitlines()&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{score(games, P1_SCORES)}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{score(games, P2_SCORES)}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I guess one interesting note is the use of the &lt;code&gt;Iterable&lt;&#x2F;code&gt; type instead of
&lt;code&gt;list[str]&lt;&#x2F;code&gt; for the &lt;code&gt;games&lt;&#x2F;code&gt; argument and the &lt;code&gt;Mapping&lt;&#x2F;code&gt; type instead of
&lt;code&gt;dict[str, int]&lt;&#x2F;code&gt; for the &lt;code&gt;table&lt;&#x2F;code&gt; argument. In general when using type
hints, it can be nice to get in the habit of accepting more general abstract types.
It&#x27;s not likely for this program, but you could imagine that someone might
swap to using a &lt;code&gt;set&lt;&#x2F;code&gt; or &lt;code&gt;frozenset&lt;&#x2F;code&gt; to represent some collection. By using
argument types like &lt;code&gt;Iterable&lt;&#x2F;code&gt;, you can enable users of functions to pass in a
larger variety of inputs without additional copies or allocations. Additionally,
immutable container types are covariant on their value types. Using immutable
container argument types often makes your interfaces much more flexible.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;efficiency&quot;&gt;Efficiency&lt;&#x2F;h3&gt;
&lt;p&gt;This solution is optimal in terms of asymptotic complexity (it runs in linear time
over the length of the input). But one idea we could try would be to use a
&lt;code&gt;match&lt;&#x2F;code&gt; statement instead of a lookup table. It&#x27;s unlikely that this will yield
performance benefits since dictionary lookups are well optimized in Python. I&#x27;m
more curious to see how these approaches fare in Rust, but let&#x27;s try it in Python,
just to see!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2022&#x2F;py&#x2F;day02&#x2F;sol.py
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;time &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;perf_counter
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;typing &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Callable, Final, Iterable, Mapping, Sequence
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;py.read_input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;read_input
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P1_SCORES&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 2
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 2
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 6 + 1
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 0 + 2
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 3
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P2_SCORES&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 1 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2 + 6
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 1 + 0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 6
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 2 + 0
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 3 + 3
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# 1 + 6
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;table_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games&lt;&#x2F;span&gt;&lt;span&gt;: Iterable[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;table&lt;&#x2F;span&gt;&lt;span&gt;: Mapping[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(table[game] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;table_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games&lt;&#x2F;span&gt;&lt;span&gt;: Sequence[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;table_score(games, P1_SCORES)&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;table_score(games, P2_SCORES)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;score_fn_p1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    match game:
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;8
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;9
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;7
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;ValueError&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Invalid game: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{game}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;score_fn_p2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    match game:
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;4
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;8
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;9
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;7
&lt;&#x2F;span&gt;&lt;span&gt;        case &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;ValueError&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Invalid game: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{game}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;match_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games&lt;&#x2F;span&gt;&lt;span&gt;: Iterable[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;score_fn&lt;&#x2F;span&gt;&lt;span&gt;: Callable[[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(score_fn(game) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;match_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games&lt;&#x2F;span&gt;&lt;span&gt;: Sequence[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;match_score(games, score_fn_p1)&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;match_score(games, score_fn_p2)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;read_input(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    games &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.splitlines()&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    expected_output &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;table_sol(games)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part one: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{expected_output[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;]}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Part two: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{expected_output[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;]}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;benchmark&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;solution&lt;&#x2F;span&gt;&lt;span&gt;: Callable[[Sequence[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;]], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]]) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        start &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;perf_counter()
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;_ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;range&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;assert &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;solution(games) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span&gt;expected_output
&lt;&#x2F;span&gt;&lt;span&gt;        end &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;perf_counter()
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;end &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;start
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Table solution takes &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{benchmark(table_sol)}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;s&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Match solution takes &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{benchmark(match_sol)}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;s&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(main())
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Running this on my machine yields this result:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python -m py.day02.sol
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part one: 11906
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Part two: 11186
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Table solution takes 0.1719587080006022s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Match solution takes 0.38245958300103666s
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So the &lt;code&gt;match&lt;&#x2F;code&gt;-based solution takes more than twice as long as the lookup table
approach. I&#x27;m glad that Python now has some form of structural pattern matching, but
a little bit sad about the performance gap to lookup tables, especially when compared
with compiled languages like Rust or Standard ML.&lt;&#x2F;p&gt;
&lt;p&gt;So for Python, we&#x27;ll stick with our original lookup table approach.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust&quot;&gt;Rust!&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s try the same exercise in Rust.&lt;&#x2F;p&gt;
&lt;p&gt;You know most of the boilerplate from day 1, so I&#x27;ll gloss over most of those details.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ll use the &lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;phf&quot;&gt;&lt;code&gt;phf&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; crate to build our lookup table.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo add phf phf_macros
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;phf_macros::phf_map;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;parse_games&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    input.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;lines&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;::trim).collect::&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&amp;gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P1_SCORES&lt;&#x2F;span&gt;&lt;span&gt;: phf::Map&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;static str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;phf_map! &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P2_SCORES&lt;&#x2F;span&gt;&lt;span&gt;: phf::Map&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;static str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;phf_map! &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;table_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;table&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;phf::Map&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;&amp;#39;static str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    games
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(|&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game&lt;&#x2F;span&gt;&lt;span&gt;| table.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(game).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;invalid game&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))
&lt;&#x2F;span&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;table_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; games &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse_games&lt;&#x2F;span&gt;&lt;span&gt;(input);
&lt;&#x2F;span&gt;&lt;span&gt;    (
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;table_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;games, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P1_SCORES&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;table_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;games, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;P2_SCORES&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;score_fn_p1&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; game {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_ =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;panic!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;invalid game: {game}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;score_fn_p2&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;game&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;match&lt;&#x2F;span&gt;&lt;span&gt; game {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;A Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;B Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C X&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Y&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;C Z&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;,
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;_ =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;panic!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;invalid game: {game}&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;match_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;games&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;], &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;score_fn&lt;&#x2F;span&gt;&lt;span&gt;: impl Fn(&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32 &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    games.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;cloned&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;(score_fn).&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;match_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;i32&lt;&#x2F;span&gt;&lt;span&gt;) {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; games &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;parse_games&lt;&#x2F;span&gt;&lt;span&gt;(input);
&lt;&#x2F;span&gt;&lt;span&gt;    (
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;match_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;games, score_fn_p1),
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;match_score&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;games, score_fn_p2),
&lt;&#x2F;span&gt;&lt;span&gt;    )
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;#[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;cfg&lt;&#x2F;span&gt;&lt;span&gt;(test)]
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;mod &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;tests &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use super&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;#&amp;quot;A Y
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;B X
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;C Z&amp;quot;#&lt;&#x2F;span&gt;&lt;span&gt;;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_table_sol&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;table_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    #[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;test_match_sol&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;match_sol&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;EXAMPLE&lt;&#x2F;span&gt;&lt;span&gt;), (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;));
&lt;&#x2F;span&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s hook it all up in our &lt;code&gt;main&lt;&#x2F;code&gt; function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::error::Error;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;day02::{match_sol, table_sol};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;(), &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Box&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;dyn Error&amp;gt;&amp;gt; {
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;include_str!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;..&#x2F;..&#x2F;..&#x2F;..&#x2F;input&#x2F;02&#x2F;input.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;(tp1, tp2) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;table_sol&lt;&#x2F;span&gt;&lt;span&gt;(input);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Table sol p1: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{tp1}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;, p2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{tp2}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;let &lt;&#x2F;span&gt;&lt;span&gt;(mp1, mp2) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;match_sol&lt;&#x2F;span&gt;&lt;span&gt;(input);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Match sol p1: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{mp1}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;, p2: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{mp2}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span&gt;(())
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can run it and get our expected results:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo run
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Finished dev &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;unoptimized + debuginfo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; target(s&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;in 0.02s
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running `&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day02&#x2F;target&#x2F;debug&#x2F;main`
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Table sol p1: 11906, p2: 11186
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Match sol p1: 11906, p2: 11186
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Similarly, we add a benchmark file for &lt;code&gt;criterion&lt;&#x2F;code&gt; to use:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-rust &quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;std::hint::black_box;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;use &lt;&#x2F;span&gt;&lt;span&gt;criterion::{criterion_group, criterion_main, Criterion};
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;static &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;INPUT&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;str &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;include_str!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;..&#x2F;..&#x2F;..&#x2F;input&#x2F;02&#x2F;input.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pub fn &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;criterion_benchmark&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span&gt; Criterion) {
&lt;&#x2F;span&gt;&lt;span&gt;    c.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;bench_function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;table_sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;        b.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;(|| day02::table_sol(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;black_box&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;INPUT&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;    c.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;bench_function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;match_sol&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, |&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;| {
&lt;&#x2F;span&gt;&lt;span&gt;        b.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;iter&lt;&#x2F;span&gt;&lt;span&gt;(|| day02::match_sol(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;black_box&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;INPUT&lt;&#x2F;span&gt;&lt;span&gt;)))
&lt;&#x2F;span&gt;&lt;span&gt;    });
&lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;criterion_group!&lt;&#x2F;span&gt;&lt;span&gt;(benches, criterion_benchmark);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;criterion_main!&lt;&#x2F;span&gt;&lt;span&gt;(benches);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And finally, we run our benchmarks:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ cargo bench
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Finished bench &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;optimized&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; target(s&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;in 0.03s
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running unittests src&#x2F;lib.rs (&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day02&#x2F;target&#x2F;release&#x2F;deps&#x2F;day02-14b54ca39dda7916&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 2 tests
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_match_sol ... ignored
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test tests::test_table_sol ... ignored
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 0 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;2 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running unittests src&#x2F;bin&#x2F;main.rs (&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day02&#x2F;target&#x2F;release&#x2F;deps&#x2F;main-ea2d4c751f6a8144&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;running 0 tests
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;test result: ok. 0 passed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 failed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 ignored&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 measured&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0 filtered out&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;finished in 0.00s
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Running benches&#x2F;my_benchmark.rs (&#x2F;Users&#x2F;sgeisenh&#x2F;projects&#x2F;aoc&#x2F;2022&#x2F;rust&#x2F;day02&#x2F;target&#x2F;release&#x2F;deps&#x2F;my_benchmark-24b0eacb110149e1&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Gnuplot not found, using plotters backend
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;table_sol               time:   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;105.59 µs 105.63 µs 105.69 µs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;change: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;-0.1857% &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;0.0658% +0.0629%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; (p = 0.31 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.05&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;No change in performance detected.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 4 outliers among 100 measurements (4.00%&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;1 (1.00%&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;high mild
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;3 (3.00%&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;high severe
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;match_sol               time:   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;47.056 µs 47.131 µs 47.222 µs&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;change: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;-6.3413% &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;5.8155% &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;5.1458%&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; (p = 0.00 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.05&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Performance has improved.
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 5 outliers among 100 measurements (5.00%&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;1 (1.00%&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;high mild
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;4 (4.00%&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;high severe
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As expected, the &lt;code&gt;match&lt;&#x2F;code&gt;-based solution is significantly faster than the table
lookup solution in Rust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;that-s-it&quot;&gt;That&#x27;s it!&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;m a little bit sad that day 1 had some more interesting algorithmic ideas to
explore than day 2. Oh well. I&#x27;ll probably jump to something like day 20 for my
next post so we can get into some juicy ideas.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Weeks 2 and 3 at RC</title>
        <published>2023-01-22T00:00:00+00:00</published>
        <updated>2023-01-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/recurse-weeks-2-and-3/"/>
        <id>https://samgeo.codes/recurse-weeks-2-and-3/</id>
        
        <content type="html" xml:base="https://samgeo.codes/recurse-weeks-2-and-3/">&lt;p&gt;It has been a great 3 weeks at RC, so far. Not especially proud that I stopped
writing for ~2 weeks, but it has been quite a whirlwind.&lt;&#x2F;p&gt;
&lt;p&gt;The most concrete thing that I&#x27;ve been working on is a project I&#x27;m calling
&lt;a href=&quot;https:&#x2F;&#x2F;brainlove.dev&quot;&gt;Brainlove&lt;&#x2F;a&gt; which is basically just random exploration
of Brainfuck tooling. It&#x27;s been really cool to see how mature the compile-to-wasm
ecosystem has become. I still don&#x27;t think that it would be my first choice for a
professional setting, but the developer experience is &lt;em&gt;much&lt;&#x2F;em&gt; better than I was
expecting. Deploying the debugger to Netlify as a static bundle was a breeze.&lt;&#x2F;p&gt;
&lt;p&gt;Beyond that, I&#x27;ve probably been spreading myself a little bit too thin in terms of
what I&#x27;m working on:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Paired a lot with &lt;a href=&quot;https:&#x2F;&#x2F;healeycodes.com&#x2F;&quot;&gt;Andrew&lt;&#x2F;a&gt;. Learning a lot about
effective communication in these sessions. I&#x27;ve also really enjoyed reading Andrew&#x27;s
website and blog.
&lt;ul&gt;
&lt;li&gt;We reached a reasonable conclusion on the 2048 strategy project. We attempted
a low-level implementation of board operations that turned out to be slower
than the naiive list-based implementation. Really interesting exercise.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sgeisenh&#x2F;2048ai&quot;&gt;repo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Wrote a &amp;quot;compiler&amp;quot; for compiling a very small expression language to Brainfuck.
This was a mind bender. We both avoided seeking out external resources so it
was a lot of fun to solve these problems from scratch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Paired on a bunch of other things (ranging from Leetcode to an Octave LSP).
&lt;ul&gt;
&lt;li&gt;I think pairing has been the biggest benefit of being at RC so far. There are
so many things I &lt;em&gt;could&lt;&#x2F;em&gt; explore, but I really want to make the most of being
at RC right now, so I hope to continue emphasizing pairing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;I put together a small python script for generating LICENSE files. There are
already a bunch of implementations of this, but I thought it would be a fun way to
learn about how to package python libraries and scripts. There are a lot of
outdated resources for python packaging, so this was surprisingly painful.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~sgeisenh&#x2F;genlic&quot;&gt;repo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;genlic&#x2F;&quot;&gt;PyPI&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;I hobbled together a URL shortener that runs on fly.io but is only accessible
within my tailscale network. I used an existing Flask URL shortener that I had
worked on with Rana (my wife) a while ago. Once I had a reasonable understanding
of how everything fit together, this wasn&#x27;t too bad. But my mental model of networking
could probably use some work.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fly-apps&#x2F;tailscale-router&quot;&gt;repo&lt;&#x2F;a&gt; for the router code (I didn&#x27;t write this)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~sgeisenh&#x2F;reeneeurl&quot;&gt;repo&lt;&#x2F;a&gt; for the URL shortener&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;blog&#x2F;golink&#x2F;&quot;&gt;post&lt;&#x2F;a&gt; discussing go links on tailscale blog&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Thought a lot about how to set up an election website that enables users to
choose the voting system they use.&lt;&#x2F;li&gt;
&lt;li&gt;Made some progress on Crafting Interpreters in C++.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~sgeisenh&#x2F;cpplox&quot;&gt;repo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Most of garbage collection is in place&lt;&#x2F;li&gt;
&lt;li&gt;Spent a good amount of time comparing performance with clox across both
x86-64 and Apple silicon&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Read a few chapters of &lt;a href=&quot;https:&#x2F;&#x2F;dataintensive.net&#x2F;&quot;&gt;DDIA&lt;&#x2F;a&gt;
&lt;ul&gt;
&lt;li&gt;There&#x27;s a small reading group for the book at RC where we&#x27;ve had some great
discussion, so far. Planning to coordinate reading some papers as well!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Finished the available &lt;a href=&quot;https:&#x2F;&#x2F;protohackers.com&#x2F;&quot;&gt;Protohackers&lt;&#x2F;a&gt; problems in Python.
These are a blast. I&#x27;ve really been enjoying &lt;a href=&quot;https:&#x2F;&#x2F;fasterthanli.me&#x2F;&quot;&gt;Amos&#x27;&lt;&#x2F;a&gt;
series covering Advent of Code in Rust. I think it would be fun to put together
a similar style series for Protohackers describing my approach to building out solutions
(first in Python, then translating to Rust).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Not a ton of structure to this post, but I want to get back into the swing of
writing regularly, so I&#x27;m lowering the bar a little bit. If you&#x27;ve made it this
far, thanks for reading!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Day 4 at RC</title>
        <published>2023-01-07T00:00:00+00:00</published>
        <updated>2023-01-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/recurse-day-4/"/>
        <id>https://samgeo.codes/recurse-day-4/</id>
        
        <content type="html" xml:base="https://samgeo.codes/recurse-day-4/">&lt;p&gt;What a week! RC has been a huge mental (and emotional) shift for me. I still
feel anxious about making rapid progress; I hope as I settle on a more concrete direction
that I&#x27;ll be able to manage some of those feelings a little bit better.
I feel like I&#x27;m shifting more toward a relaxed &amp;quot;let&#x27;s just write some code&amp;quot; mindset. That feels good.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;self-reflection&quot;&gt;Self Reflection&lt;&#x2F;h2&gt;
&lt;p&gt;I think back to some of the early performance discussions that I had with my
managers as I was starting my career. At the time, I think I was reasonably
satisfied with my own work. I was solving interesting problems and had a good
dynamic with my teammates. It was satisfying to hear that others on the team
were also satisfied with the work that I was doing.&lt;&#x2F;p&gt;
&lt;p&gt;Over time, the expectations that I&#x27;ve set for myself have grown. In some ways,
I think those expectations may have stunted my growth as an engineer. With each
new project or endeavor, it became more and more difficult to be satisfied with
my own work. I think this is something I&#x27;ve struggled with since I was young.
The first few times that I solved a particular type of math problem were
satisfying. After that, I &lt;em&gt;expected&lt;&#x2F;em&gt; myself to be able to solve that kind of
problem. There was no joy to be had in demonstrating again that I could solve
that kind of problem. I would seek out progressively harder problems to solve
while procrastinating on the exercises that I already knew I &lt;em&gt;should&lt;&#x2F;em&gt; be able
to solve.&lt;&#x2F;p&gt;
&lt;p&gt;Software engineering is &lt;em&gt;mostly&lt;&#x2F;em&gt; working on things that you are already
familiar with in some capacity. Understanding how to structure a particular
abstraction or what kind of approach to take while solving a problem is mostly
a consequence of experience. With enough time in the saddle, you get to see
which decisions have the most significant consequences. When I feel like I am
struggling to make good decisions easily, I quickly get frustrated with
myself.&lt;&#x2F;p&gt;
&lt;p&gt;In that sense, being at RC feels great. I don&#x27;t have to justify making a salary.
I can convince myself that there are no external expecations which helps me
to take it easy on myself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-about-day-4&quot;&gt;More about day 4&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;2048&quot;&gt;2048&lt;&#x2F;h3&gt;
&lt;p&gt;The little 2048 project that I&#x27;ve been pairing on is shaping up really well.
It&#x27;s a lot of fun to see how different strategies compare with one another. It
reminds me a little bit of looking at some of the wordle solvers from the
beginning of 2022. I&#x27;m excited to pair more on this on Monday.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;leetcode&quot;&gt;LeetCode&lt;&#x2F;h3&gt;
&lt;p&gt;I paired on a LeetCode problem again. I think I did a really bad job of driving
and felt pretty bad in the moment. I was really impatient and didn&#x27;t take the
time to make sure I was on the same page as my navigator. My partner handled the
situation really well and asked if we could take a step back to get on the same page.&lt;&#x2F;p&gt;
&lt;p&gt;I think this was a great experience for me. It was a chance to see how I can
improve the way that I collaborate, which was awesome. I feel badly that I maybe
didn&#x27;t create the best experience for my partner, but I&#x27;m glad that I am getting
better.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;crafting-interpreters&quot;&gt;Crafting Interpreters&lt;&#x2F;h3&gt;
&lt;p&gt;I finally dusted off my in-progress C++ implementation of a Lox bytecode interpreter.
I think I&#x27;m going to forge toward the end with the hopes of thinking more about
how to express some of the idioms in Rust.&lt;&#x2F;p&gt;
&lt;p&gt;One of the ideas I&#x27;ve been mulling over:
I&#x27;d like to write a two-pass Lox compiler in Rust and implement an
interactive debugger. If the debugger runtime is sufficiently modular, it
should be feasible to get something up and running in wasm with a
Rust-based front-end (maybe Leptos?). I think this would be a fun way
to build on top of what I&#x27;ve learned while working through Crafting Interpreters
while getting a better understanding of the compile-to-wasm space (with some
web development thrown in there). We&#x27;ll see how I&#x27;m feeling as I wrap up my
C++ implementation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;databases&quot;&gt;Databases&lt;&#x2F;h3&gt;
&lt;p&gt;I had a great coffee chat with an RC alum mostly discussing databases. I think
I definitely want to pursue something in this space. I think I&#x27;m a bit anxious
about building a toy database but maybe it&#x27;s worth just trying.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;presentations&quot;&gt;Presentations&lt;&#x2F;h3&gt;
&lt;p&gt;The presentations were awesome. It&#x27;s a lot of fun to see the sheer variety of
things that people are working on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;that-s-all-for-now&quot;&gt;That&#x27;s all for now&lt;&#x2F;h2&gt;
&lt;p&gt;Thanks for reading. These posts will probably continue to lose structure over
time. It&#x27;s a lot of fun to write about random thoughts that I&#x27;ve been having
even if they&#x27;re not quite fully baked.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Day 3 at RC</title>
        <published>2023-01-06T00:00:00+00:00</published>
        <updated>2023-01-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/recurse-day-3/"/>
        <id>https://samgeo.codes/recurse-day-3/</id>
        
        <content type="html" xml:base="https://samgeo.codes/recurse-day-3/">&lt;p&gt;Day 3 was really packed. Here&#x27;s a quick summary before I jump in:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I started my day by writing down my reflections on day 2 (yesterday&#x27;s post).&lt;&#x2F;li&gt;
&lt;li&gt;Pairing session on a 2048 implementation in python.&lt;&#x2F;li&gt;
&lt;li&gt;Heard from a bunch of folks about their plans&#x2F;advice at RC.&lt;&#x2F;li&gt;
&lt;li&gt;Paired on a LeetCode problem in JavaScript.&lt;&#x2F;li&gt;
&lt;li&gt;Responded to a creative coding prompt in p5js as part of a group.&lt;&#x2F;li&gt;
&lt;li&gt;Paired some more on a neat Pokémon image downloader in async rust.&lt;&#x2F;li&gt;
&lt;li&gt;Had a coffee chat with an RC alum to talk about some of our experience in
the programming language sphere.&lt;&#x2F;li&gt;
&lt;li&gt;Had a really interesting discussion about reusing some open source C++ code
to create an LSP implementation in Rust by bridging the gap with &lt;a href=&quot;https:&#x2F;&#x2F;cxx.rs&quot;&gt;cxx&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Dove into some of the cxx documentation.&lt;&#x2F;li&gt;
&lt;li&gt;Watched the first half of Jon Gjengset&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;9_3krAQtD2k&quot;&gt;The What and How of Futures and async&#x2F;await in Rust&lt;&#x2F;a&gt; video.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The rest of this post will be some of my thoughts during day 3.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reflecting-in-the-morning&quot;&gt;Reflecting in the morning&lt;&#x2F;h2&gt;
&lt;p&gt;I think I like this routine of beginning each day by
reflecting on the previous day. So I&#x27;m doing it again today!&lt;&#x2F;p&gt;
&lt;p&gt;I haven&#x27;t done a great job of writing down these kinds of reflections
professionally. I don&#x27;t really know why that is. Maybe it&#x27;s because I&#x27;m not
all that comfortable being vulnerable at my place of work? Regardless, I&#x27;d like
to care a lot less about others&#x27; perception of me and my work and focus more on
creating things that I&#x27;m proud of or excited about. So far writing down some of
my thoughts has really helped clarify how I&#x27;m feeling.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2048&quot;&gt;2048&lt;&#x2F;h2&gt;
&lt;p&gt;This morning pairing session was great. The dialogue felt pretty good and there was
a nice exchange of thoughts back and forth while producing a good amount of code.
We made a solid amount of progress in a little over an hour and had
a mostly functional version of 2048 playable in the terminal. We planned another
pairing session around wiring up a simple AI to see how well it might perform.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;d love to work on a more in-depth writeup about this at some point in the future.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;leetcode&quot;&gt;LeetCode&lt;&#x2F;h2&gt;
&lt;p&gt;I really gravitate toward LeetCode-style problems. In some sense, I find it
really satisfying to come up with an efficient solution to a problem. But on
the other hand, I don&#x27;t know that spending time on LeetCode is &amp;quot;working at the
edge of my abilities&amp;quot; (one of the &lt;a href=&quot;https:&#x2F;&#x2F;www.recurse.com&#x2F;self-directives&quot;&gt;self directives&lt;&#x2F;a&gt; at RC).
I&#x27;ve spent a lot of time working on competitive coding prompts like Advent of Code,
Codeforces and LeetCode. I&#x27;m not the best that I could be -- I certainly don&#x27;t crank out
LC hards -- but it&#x27;s &lt;em&gt;comfortable&lt;&#x2F;em&gt; for me.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll probably try to fight the temptation to spend a lot of time on this style of
programming throughout the rest of my batch.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;creative-coding&quot;&gt;Creative Coding&lt;&#x2F;h2&gt;
&lt;p&gt;I had a lot of fun navigating on a creative coding prompt. We built an interactive
scene where an emoji person was trying to decide on which outfit to wear. It was
a great reminder that programming doesn&#x27;t have to be serious. I think these
sessions will be especially good as a foil for solving really complex technical
challenges. I&#x27;ve historically leaned on playing trumpet for this kind of release.
But when I really want to focus on growing as a programmer for a few months,
creative coding sessions with a group of folks seems pretty great.&lt;&#x2F;p&gt;
&lt;p&gt;I mentioned in an earlier post that I struggle with some of the improvisational
skills that are sometimes called upon for activities like this. The group setting
felt pretty nice and it was a lot of fun to think about ways to structure the
scene we built.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust&quot;&gt;Rust&lt;&#x2F;h2&gt;
&lt;p&gt;Rust seems to be everywhere. There are a bunch of folks in my batch that seem
really interested in learning Rust which is really exciting.&lt;&#x2F;p&gt;
&lt;p&gt;For a low-level language, Rust has a really compelling feedback loop. Top-notch
developer tooling (at least compared with clangd), built-in testing functionality
and a package management ecosystem that makes it easy to focus on the problem you
want to solve instead of how to repackage an open source library as a Bazel library
instead of using CMake (I&#x27;m not salty at all...).&lt;&#x2F;p&gt;
&lt;p&gt;And the community is fantastic. There are so many resources for learning and most of them are fairly up-to-date. I think C++ is simply
too large of a language for most resources to be broadly applicable. Recently, I have enjoyed
Klaus Iglberger&#x27;s CppCon talks on YouTube; and I&#x27;m curious about his recently
published book &lt;a href=&quot;https:&#x2F;&#x2F;www.oreilly.com&#x2F;library&#x2F;view&#x2F;c-software-design&#x2F;9781098113155&#x2F;&quot;&gt;C++ Software Design&lt;&#x2F;a&gt;.
But it gets really frustrating to see recommendations for pasting over
decades-old language design mistakes by adding yet another keyword or annotation
to your method declaration. Rust corrects a lot of these mistakes and incorporates
better mechanisms for encoding invariants in programs.
In many ways, Rust is now one of the most accessible
languages with explicit memory management: you get best-practices by default
instead of opting into them with a keyword.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m sure I&#x27;ll write a lot more about Rust in the coming weeks so I&#x27;ll leave it
at that, for now.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;closing-thoughts&quot;&gt;Closing Thoughts&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve been spending a lot of time in group activities this week. I think I&#x27;m
developing a stronger sense for how I want to spend my time during the rest of
my batch. I definitely want to continue with
these daily reflections. Thanks again for reading!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Day 2 at RC</title>
        <published>2023-01-05T00:00:00+00:00</published>
        <updated>2023-01-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/recurse-day-2/"/>
        <id>https://samgeo.codes/recurse-day-2/</id>
        
        <content type="html" xml:base="https://samgeo.codes/recurse-day-2/">&lt;p&gt;Day 2 of RC was really interesting. The biggest event of the day was a pairing
workshop. But I also attended a couple of group events:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a discussion of WebGL,&lt;&#x2F;li&gt;
&lt;li&gt;the start of a reading group for Nand2Tetris.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And then in the evening I attended a couple of non-programming talks.&lt;&#x2F;p&gt;
&lt;p&gt;I also finally finished Protohackers day 6 in Rust which felt really good.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pairing-workshop&quot;&gt;Pairing Workshop&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;m really interested in pair programming but I haven&#x27;t done much of it.
I have watched a good number of &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@RubberDuckEng&#x2F;streams&quot;&gt;Rubber Duck Engineering&lt;&#x2F;a&gt;
streams and thought &amp;quot;yeah, that seems like some of the most fun I can imagine&amp;quot;.
The workshop brought me back to earth a little bit: I don&#x27;t think I am very
good at pairing. That being said, I really want to do as much pairing as possible
over the next few months.&lt;&#x2F;p&gt;
&lt;p&gt;At the beginning of the workshop, some of the RC
staff discussed the benefits of pairing and provided an example of what effective
pairing might look like. We then split off into groups to work on implementing Mastermind.
As we jumped into groups, I found myself in a
group of three. I ended up driving to start out. There are 2 roles in pair
programming: the driver who types and the navigator who follows along. Driving is
hard. From experiences that I&#x27;ve had, it feels most similar to taking a coding
interview with a bit more communication. I got a little carried away and ended up
taking 30 minutes instead of 20 minutes for my section of driving. When we
switched off, I discovered that navigating is at least as hard as driving.
Finding the right time to mention something to the driver is tough and I can get
a little bit fixated on tiny issues (as my wife would surely attest). Overall,
this was a really valuable session and I&#x27;m looking forward to working through
some of my discomfort with pairing over the coming weeks.&lt;&#x2F;p&gt;
&lt;p&gt;As an aside, node&#x27;s blocking-averse design made it surprisingly difficult
to read input from the user. Especially when compared with python&#x27;s &lt;code&gt;input&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;webgl&quot;&gt;WebGL&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;ve always been kind of curious about graphics programming, but I consistently
bounce off. I think the gap between &amp;quot;wow, this is a triangle with a gradient&amp;quot; to
&amp;quot;holy smokes, a hand-written shader for a high-fidelity 3D flying sequence&amp;quot; seems
insurmountable. I&#x27;ve also always struggled with extemporaneous creativity.
Whenever I was called on to improvise in jazz band, I would clam up immediately.
I&#x27;m curious how I might be able to work through some of my &amp;quot;improv anxiety&amp;quot; and
come up with silly ideas to try that might help me work through some of my
misgivings with shaders. We&#x27;ll see.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nand2tetris&quot;&gt;Nand2Tetris&lt;&#x2F;h2&gt;
&lt;p&gt;I recently read &lt;a href=&quot;https:&#x2F;&#x2F;codehiddenlanguage.com&#x2F;&quot;&gt;Charles Petzold&#x27;s Code&lt;&#x2F;a&gt; which
I thoroughly enjoyed. Slowly building up a stack of abstractions starting from
sending signals between neighboring houses was really neat. I bought &lt;a href=&quot;https:&#x2F;&#x2F;mitpress.mit.edu&#x2F;9780262539807&#x2F;the-elements-of-computing-systems&#x2F;&quot;&gt;The Elements
of Computing Systems&lt;&#x2F;a&gt;
a while ago, but haven&#x27;t done much aside from the first couple of chapters.&lt;&#x2F;p&gt;
&lt;p&gt;Working through the book seems like it might be a fun way to bolster my mental
model of hardware and the hardware&#x2F;software interface.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;non-programming-talks&quot;&gt;Non-programming Talks&lt;&#x2F;h2&gt;
&lt;p&gt;These talks were great. I learned a lot about tabletop RPGs and chairmaking.
Most of all, it was further proof that the people at RC are awesome.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;protohackers-day-6-in-rust&quot;&gt;Protohackers day 6 in Rust&lt;&#x2F;h2&gt;
&lt;p&gt;It was really neat to finally finish protohackers day 6 in Rust &lt;a href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~sgeisenh&#x2F;protohackers&#x2F;tree&#x2F;main&#x2F;item&#x2F;06&#x2F;src&#x2F;main.rs&quot;&gt;link&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not handling connections the best and I could definitely use some logging
to make debugging easier. But the automated tests passed, and a heck of a lot
faster than my python implementation, at that!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;that-s-all-for-now&quot;&gt;That&#x27;s all for now&lt;&#x2F;h2&gt;
&lt;p&gt;Most of these will probably be quick updates with maybe a more in-depth update
once every week or two. Thanks for reading!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>First day at the Recurse Center</title>
        <published>2023-01-03T00:00:00+00:00</published>
        <updated>2023-01-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/recurse-day-1/"/>
        <id>https://samgeo.codes/recurse-day-1/</id>
        
        <content type="html" xml:base="https://samgeo.codes/recurse-day-1/">&lt;p&gt;Today was my first day at the &lt;a href=&quot;https:&#x2F;&#x2F;recurse.com&quot;&gt;Recurse Center&lt;&#x2F;a&gt; (RC). I had so
much fun hearing about what awaits me over the next ~12 weeks and meeting a bunch
of new people, all of whom seem to be just about as excited as I am!&lt;&#x2F;p&gt;
&lt;p&gt;A lot of the discussions I had with folks revolved around what everyone was planning
to work on during the coming weeks. I&#x27;ve been curious about a handful of programming
topics recently so I have some initial ideas for things to explore:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I&#x27;ve been working my way through Robert Nystrom&#x27;s &lt;a href=&quot;http:&#x2F;&#x2F;craftinginterpreters.com&#x2F;&quot;&gt;Crafting Interpreters&lt;&#x2F;a&gt;
and I have a couple of ideas for different directions to take.&lt;&#x2F;li&gt;
&lt;li&gt;Andy Pavlo is a great speaker and writer and I&#x27;d love to dive into some of the
course material he has put together on &lt;a href=&quot;https:&#x2F;&#x2F;15445.courses.cs.cmu.edu&#x2F;fall2022&#x2F;&quot;&gt;database systems&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@awesomekling&quot;&gt;Andreas Kling&lt;&#x2F;a&gt; is my go-to for relaxing
and satisfying YouTube viewing. It would be a blast to contribute to SerenityOS in some way.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are also a bunch of reading groups and other interesting gatherings to attend.
I&#x27;ll probably attend lots of stuff early in the batch and see what sticks.&lt;&#x2F;p&gt;
&lt;p&gt;Most of all, regardless of what I am working on, I want to make a real effort to
communicate about it. I&#x27;d love to improve my writing and communication skills
significantly over the next few months.&lt;&#x2F;p&gt;
&lt;p&gt;In the rest of this post, I&#x27;ll dive into some of the things I&#x27;ve been thinking about.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;joy-in-programming&quot;&gt;Joy in Programming&lt;&#x2F;h2&gt;
&lt;p&gt;I love programming. I get a deep sense of satisfaction watching a program that I&#x27;ve written
solve a problem. I also love the craft of programming. There are so many different ways
to solve problems with code. Which way is the most expressive? Which techniques help
reduce or eliminate bugs? I&#x27;m constantly thinking about these sorts of things
whether solving an Advent of Code problem or starting a design document at work.&lt;&#x2F;p&gt;
&lt;p&gt;Often when I&#x27;ve started conversations about the &lt;em&gt;practice&lt;&#x2F;em&gt; of programming at work,
I&#x27;ve received blank stares from many of my coworkers. This has been pretty discouraging.
From everything I&#x27;ve read and everything I&#x27;ve seen so far, RC is the kind of place
where these kinds of discussions are met with curiosity from the people around you.
Whether they are experts in a particular programming topic or looking to learn more.&lt;&#x2F;p&gt;
&lt;p&gt;The summer after I graduated, I attended the &lt;a href=&quot;https:&#x2F;&#x2F;www.cs.uoregon.edu&#x2F;research&#x2F;summerschool&#x2F;summer22&#x2F;&quot;&gt;Oregon Programming Languages Summer School&lt;&#x2F;a&gt;
(OPLSS). Everyone there was &lt;em&gt;psyched&lt;&#x2F;em&gt; to exchange ideas about programming
languages across the full spectrum from theory to practice.
That was the last time that I remember being surrounded by a group of people so
enthusiastic about the subject at hand.&lt;&#x2F;p&gt;
&lt;p&gt;I really enjoy programming as a career. But necessarily, programming and the
&lt;em&gt;practice&lt;&#x2F;em&gt; of programming is a means to an end in a business context.
There is a lot of satisfaction to be had in generating business value, but
sometimes the drive to produce impact can quell some natural curiosity.
There isn&#x27;t always time to peek under the hood and learn about the different
systems and abstractions that we lean on to get our work done, every single day.&lt;&#x2F;p&gt;
&lt;p&gt;This is what I&#x27;m most excited about being at RC. To have the time and space to
explore those nooks and crannies and muse about it with a bunch of likeminded people.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;high-level-programming-language-runtimes&quot;&gt;High-level Programming Language Runtimes&lt;&#x2F;h2&gt;
&lt;p&gt;A lot of my background in the programming language space comes from my undergraduate
curriculum. I loved the PL classes in school, but there was a heavy emphasis on
static type systems and theory in general. Reading and working through Crafting
Interpreters has been a blast. High-level dynamic languages were generally derided
(&lt;a href=&quot;https:&#x2F;&#x2F;existentialtype.wordpress.com&#x2F;2011&#x2F;03&#x2F;19&#x2F;dynamic-languages-are-static-languages&#x2F;&quot;&gt;example&lt;&#x2F;a&gt;)
during my school years. Writing a good amount of code in python and JavaScript over
the years has me convinced that dynamic languages have their place, though I still
generally prefer to have a powerful static type system.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m really fascinated by all of the efforts that have gone into creating absurdly
fast language runtimes over the last couple of decades. I&#x27;m hoping to do some reading
starting with the smalltalk and Self optimization papers of the 80s and 90s, working
my way through LuaJIT in the mid 2000s and V8 and pypy in the late 2000s.&lt;&#x2F;p&gt;
&lt;p&gt;Ideally, I&#x27;d be able to incorporate some of those ideas into a Lox interpreter,
but that might be overly ambitious. We&#x27;ll see!&lt;&#x2F;p&gt;
&lt;p&gt;Somewhat unrelated, I&#x27;ve been running into an issue where a C++ implementation
of Lox that I&#x27;ve been working on runs ~100% slower than clox on a simple
&lt;code&gt;for&lt;&#x2F;code&gt; loop example. Most of the time seems to be spent in &lt;code&gt;std::vector&lt;&#x2F;code&gt; reads.
Not totally sure what&#x27;s going on, but it&#x27;d be fun to dive deeper and do a write up.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;protohackers-rust-and-python&quot;&gt;Protohackers, Rust and Python&lt;&#x2F;h2&gt;
&lt;p&gt;Since I wasn&#x27;t sure how much time I would have amidst the orientation events,
this week, I&#x27;ve lined up some bite-sized tasks to tackle.&lt;&#x2F;p&gt;
&lt;p&gt;I started working on &lt;a href=&quot;https:&#x2F;&#x2F;protohackers.com&#x2F;&quot;&gt;protohackers&lt;&#x2F;a&gt; at the end of
August. I had started in Rust which has been a ton of fun. When I reached
problem 6 (Speed Daemon), I stalled a little bit as there was more synchronization
required than the previous problems. I made a couple of adjustments with the hope
that I might be able to make more sustainable progress:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Swapped from &lt;a href=&quot;https:&#x2F;&#x2F;digitalocean.com&quot;&gt;DigitalOcean&lt;&#x2F;a&gt; to &lt;a href=&quot;https:&#x2F;&#x2F;fly.io&quot;&gt;fly.io&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Solved the problem in Python instead of Rust&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;do-to-fly&quot;&gt;DO to fly&lt;&#x2F;h3&gt;
&lt;p&gt;DigitalOcean is great. It&#x27;s super simple to spin up a tiny VM, ssh into it, grab
the latest copy of my code and run my program. I&#x27;ve been curious to get better
familiarized with fly.io and similar hosting providers.&lt;&#x2F;p&gt;
&lt;p&gt;For the most part, &lt;a href=&quot;https:&#x2F;&#x2F;fly.io&#x2F;docs&#x2F;languages-and-frameworks&#x2F;dockerfile&#x2F;&quot;&gt;deploying via a Dockerfile&lt;&#x2F;a&gt;
is pretty straightforward. I encountered two issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I couldn&#x27;t get UDP to work; protohackers problem 4 specifies a key-value store
accessed over UDP. I tried following the &lt;a href=&quot;https:&#x2F;&#x2F;fly.io&#x2F;docs&#x2F;app-guides&#x2F;udp-and-tcp&#x2F;&quot;&gt;fly.io guide on UDP&lt;&#x2F;a&gt;
but gave up before getting anything to work.&lt;&#x2F;li&gt;
&lt;li&gt;The default concurrency settings caused my service to reject some connections when testing
my solution. The auto-generated &lt;code&gt;fly.toml&lt;&#x2F;code&gt; file I was using included this snippet:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;toml&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-toml &quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;services.concurrency&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;connections&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;hard_limit &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;25
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;soft_limit &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;20
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For a while, I thought I had a logic error in my program that was causing me to
close connections before I found a log entry from the proxy layer that indicated the
concurrent connections were being limited. Eliminating the snippet from &lt;code&gt;fly.toml&lt;&#x2F;code&gt; had
no effect, but replacing those lines with:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;toml&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-toml &quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;services.concurrency&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;type &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;connections&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;hard_limit &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;150
&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;font-weight:bold;color:#407959;&quot;&gt;soft_limit &lt;&#x2F;span&gt;&lt;span&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;100
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;seemed to fix the issues.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, fly.io is really pleasant to use. I don&#x27;t have a lot of experience
using Heroku which seems to be the main comparison for fly. But the ability
to launch a service anywhere in the world from my command line is pretty neat.
It&#x27;s still quite a bit faster to iterate over ssh, but I&#x27;m hoping I can find
ways to optimize my workflow.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rust-to-python&quot;&gt;Rust to Python&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;m pretty much head-over-heels for Rust. It&#x27;s a really satisfying combination
of ideas from &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ML_(programming_language)&quot;&gt;ML&lt;&#x2F;a&gt;
and C++.&lt;&#x2F;p&gt;
&lt;p&gt;That being said, there is a lot to think about when dealing with concurrency
in Rust. Sometimes you need to wrap something in &lt;code&gt;Arc&amp;lt;Mutex&amp;lt;...&amp;gt;&amp;gt;&lt;&#x2F;code&gt; to provide
mutable access to some shared state across threads. &lt;a href=&quot;https:&#x2F;&#x2F;tokio.rs&#x2F;&quot;&gt;Tokio&lt;&#x2F;a&gt; is
fantastic, but you still need to think about multi-threading and synchronization.
Python&#x27;s &lt;code&gt;asyncio&lt;&#x2F;code&gt; offers a programming model that is conceptually similar to
Rust&#x27;s asynchronous runtimes but without the need for synchronization (since programs
that leverage &lt;code&gt;asyncio&lt;&#x2F;code&gt; run the event loop in a single thread).&lt;&#x2F;p&gt;
&lt;p&gt;It took me a surprisingly long time to get an implementation working in python.
I don&#x27;t have a ton of experience dealing with binary encodings in python, so that
took some adjustment. On the &lt;code&gt;asyncio&lt;&#x2F;code&gt; side of things, it took me a while to figure out
that I might want to use &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;asyncio-stream.html#asyncio.StreamReader.readexactly&quot;&gt;&lt;code&gt;readexactly&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
for the implementation of reading a single message from a client. In general,
I think I have an easier time discovering python documentation but an easier time
reading Rust documentation once I&#x27;ve found it.&lt;&#x2F;p&gt;
&lt;p&gt;I also made the embarassing mistake of forgetting to explicitly set &lt;code&gt;flush=True&lt;&#x2F;code&gt;
for my &lt;code&gt;print&lt;&#x2F;code&gt; debugging. I spent far too long trying to figure out why my service
didn&#x27;t seem to start.&lt;&#x2F;p&gt;
&lt;p&gt;All-in-all, it was really satisfying to watch the last test case pass and I&#x27;m
excited to keep working on the rest of the problems that I haven&#x27;t solved yet.
Maybe I&#x27;ll find a chance to do a writeup on solving the problems in python and
Rust at some point during my batch.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;eloquent-javascript&quot;&gt;Eloquent JavaScript&lt;&#x2F;h2&gt;
&lt;p&gt;I love reading programming language books and I had seen lots of recommendations
for &lt;a href=&quot;https:&#x2F;&#x2F;eloquentjavascript.net&#x2F;&quot;&gt;Eloquent JavaScript&lt;&#x2F;a&gt; by Marijn Haverbeke in the past.&lt;&#x2F;p&gt;
&lt;p&gt;I am currently reading Chapter 16 which discusses the implementation of a small
platformer using the DOM for rendering the game world. The book is great. I really
enjoy the general style (a practical mix of functional and imperative) that Marijn
uses in his examples. He also uses a lot of closures, which I think are the most
powerful and expressive feature of high-level garbage collected languages.&lt;&#x2F;p&gt;
&lt;p&gt;But so far, the most interesting bits from the book have been general software
engineering concepts. Chapter 10 discussing modules opens with this gem:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;A typical real program grows organically. New pieces of functionality are added
as new needs come up. Structuring--and preserving structure--is additional work.
It&#x27;s work that will pay off only in the future, the &lt;em&gt;next&lt;&#x2F;em&gt; time someone works
on the program. So it is tempting to neglect it and allow the parts of the program
to become deeply entangled.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Marijn continues describing the issues of this sort of &amp;quot;entaglement&amp;quot;. I thought
it was a really empathetic way of describing how some programs accrue technical
debt.&lt;&#x2F;p&gt;
&lt;p&gt;On the other side of the coin, there is a section in chapter 16 labeled
&amp;quot;Encapsulation as a Burden&amp;quot;. Marijn discusses the tradeoffs involved when choosing
where to introduce abstraction in your programs. This
is a subtle topic that takes a lot of experience to master (I certainly haven&#x27;t mastered
it yet). But Marijn makes convincing arguments and plants the seed in the reader&#x27;s
mind.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, it&#x27;s been a great read so far! I&#x27;m excited to finish it up and maybe
do some JavaScript pairing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wrap-up&quot;&gt;Wrap Up&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;ve made it this far, thanks for reading! Stay tuned to hear more about my experience at RC.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting Started With Advent of Code</title>
        <published>2022-11-29T00:00:00+00:00</published>
        <updated>2022-11-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/aoc-template/"/>
        <id>https://samgeo.codes/aoc-template/</id>
        
        <content type="html" xml:base="https://samgeo.codes/aoc-template/">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; This is my second post discussing Advent of Code. Check out
&lt;a href=&quot;https:&#x2F;&#x2F;samgeo.codes&#x2F;aoc&#x2F;&quot;&gt;the first post&lt;&#x2F;a&gt; to learn more about why I love AoC.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Advent of Code is only a day away! I can&#x27;t wait to get started. If you&#x27;re thinking
about trying Advent of Code but you&#x27;re not sure where to start, I hope I can share
some tips.&lt;&#x2F;p&gt;
&lt;p&gt;First and foremost, make sure you&#x27;ve signed up at &lt;a href=&quot;https:&#x2F;&#x2F;adventofcode.com&#x2F;&quot;&gt;adventofcode.com&lt;&#x2F;a&gt;.
Each day, a new puzzle will become available at midnight. Now that you&#x27;ve signed up, let&#x27;s talk about
how to start writing some code to solve each puzzle.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s often difficult to start on any programming project. The number of options
and approaches can feel overwhelming. I definitely experience this sensation of
overwhelm when starting a project. Over the years, I&#x27;ve learned strategies for
overcoming some of the anxious thoughts that can creep in when just getting
started with something. The strategy I come back to time after time is to start
with the simplest approach that works.&lt;&#x2F;p&gt;
&lt;p&gt;This is the strategy that I recommend for jumping into Advent of Code. In this
post, I&#x27;ll demonstrate two simple templates that should make it fairly easy to
get started solving Advent of Code problems.&lt;&#x2F;p&gt;
&lt;p&gt;There are other resources that suggest templates that will automatically download
your input and submit your output. Or that will even show performance benchmarks
for each of your solutions. These are great, but I think it&#x27;s even more fun to
start simple and introduce your own features as you get more comfortable using
a basic setup.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to check out a great example of a more advanced setup,
Anthony Sottile posted &lt;a href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;CZZLCeRya74&quot;&gt;a great video&lt;&#x2F;a&gt; demonstrating
his template for solving AoC quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;python&quot;&gt;Python&lt;&#x2F;h2&gt;
&lt;p&gt;I love solving the problems with python each year. For small puzzles like those
in AoC, python gives you a lot of power with very little ceremony.&lt;&#x2F;p&gt;
&lt;p&gt;For a basic setup, I recommend using the &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;fileinput.html&quot;&gt;&lt;code&gt;fileinput&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
module from the standard library. This library takes care of all of the boilerplate of loading input files
and makes it easy to swap in a sample input if you want to debug your solution
on a simpler example.&lt;&#x2F;p&gt;
&lt;p&gt;Usually, I start with something like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;fileinput
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;lines &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;line.strip() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span&gt;line &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fileinput.input()&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If I&#x27;ve saved my solution to a file named &lt;code&gt;sol.py&lt;&#x2F;code&gt; and my input to a file named
&lt;code&gt;input.txt&lt;&#x2F;code&gt;, then I can run my solution by running the command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;python3 -m sol input.txt
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let&#x27;s see how it looks to solve day 1 part 1 from the 2021 edition of Advent of Code.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-diff &quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span&gt; import fileinput
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#9d0006;color:#282828;&quot;&gt;-lines = [line.strip() for line in fileinput.input()]
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+depths = [int(line.strip()) for line in fileinput.input()]
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+result = 0
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+for i in range(len(depths) - 1):
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+  if depths[i] &amp;lt; depths[i + 1]:
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+    result += 1
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+print(&amp;quot;Part one:&amp;quot;, result)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, most of the adjustments that we&#x27;ve made are focused on just
solving the specifics of the problem. First we parse an integer from each line,
then we are able to walk our list to figure out how many times the depth increases.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;javascript&quot;&gt;JavaScript&lt;&#x2F;h1&gt;
&lt;p&gt;JavaScript is a great language for getting started learning to code especially because
the web is such a ubiquitous platform. There are several excellent JavaScript
runtimes that you can use to solve AoC problems in JavaScript. I recommend
&lt;a href=&quot;https:&#x2F;&#x2F;nodejs.org&#x2F;&quot;&gt;node.js&lt;&#x2F;a&gt; as it is the most popular server-side JavaScript
platform.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, node does not provide quite as much convenience as python (and its
enormous standard library). But once you get past the boilerplate setup, it&#x27;s not
so bad!&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take a look:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;javascript&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fs &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;fs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;fs.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;readFileSync&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;.&#x2F;input.txt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;toString&lt;&#x2F;span&gt;&lt;span&gt;();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;lines &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;input.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;map&lt;&#x2F;span&gt;&lt;span&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;s.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;());
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To run this, assuming that I&#x27;ve saved this to &lt;code&gt;sol.js&lt;&#x2F;code&gt; (and the input to &lt;code&gt;input.txt&lt;&#x2F;code&gt;) I can run the command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;node sol.js
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that we&#x27;ve hardcoded the path of the input file, so you&#x27;ll have to do
a little bit more work to test out your solution on a sample input. It&#x27;s possible
to recreate our setup from the python section with a little bit of research
on command line argument parsing (see the docs on &lt;a href=&quot;https:&#x2F;&#x2F;nodejs.org&#x2F;api&#x2F;process.html#processargv&quot;&gt;&lt;code&gt;process.argv&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
for more details).&lt;&#x2F;p&gt;
&lt;p&gt;Now let&#x27;s see what it looks like to solve 2021 day 1 part 1 in JavaScript:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-diff &quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span&gt; const fs = require(&amp;quot;fs&amp;quot;);
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt; const input = fs.readFileSync(&amp;quot;.&#x2F;input.txt&amp;quot;).toString();
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#9d0006;color:#282828;&quot;&gt;-const lines = input.split(&amp;quot;\n&amp;quot;).map((s) =&amp;gt; s.trim());
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+const depths = input.split(&amp;quot;\n&amp;quot;).map((s) =&amp;gt; parseInt(s.trim()));
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+let result = 0;
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+for (let i = 0; i &amp;lt; depths.length - 1; ++i) {
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+  if (depths[i] &amp;lt; depths[i + 1]) {
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+    ++result;
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+  }
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+}
&lt;&#x2F;span&gt;&lt;span style=&quot;background-color:#407959;color:#282828;&quot;&gt;+console.log(&amp;quot;Part one:&amp;quot;, result);
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not too bad!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wrap-up&quot;&gt;Wrap Up&lt;&#x2F;h2&gt;
&lt;p&gt;As you can see, it&#x27;s possible to get started solving Advent of Code puzzles with
just a little bit of setup. Once you&#x27;ve solved your first few puzzles, it can
be fun to experiment with different ways to speed up your solutions or to automatically
handle fetching your input or submitting your output. But it&#x27;s fine to start simple!
Hopefully you&#x27;ll join me tomorrow night (and the rest of the month) in solving some festive puzzles!&lt;&#x2F;p&gt;
&lt;p&gt;Good luck!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why I love Advent of Code</title>
        <published>2022-11-15T00:00:00+00:00</published>
        <updated>2022-11-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/aoc/"/>
        <id>https://samgeo.codes/aoc/</id>
        
        <content type="html" xml:base="https://samgeo.codes/aoc/">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;NOTE:&lt;&#x2F;em&gt;&lt;&#x2F;strong&gt; This will be the first post in a short series of maybe 2 or 3 posts discussing Advent of Code.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;adventofcode.com&quot;&gt;Advent of Code&lt;&#x2F;a&gt; is one of my favorite &amp;quot;events&amp;quot; each
year. In case you haven&#x27;t heard of it, Advent of Code (AoC) is an Advent calendar
that consists of 25 programming puzzles of varying levels of difficulty. Each puzzle consists of two parts:
the first part is released at 12 AM EST each day and the second part of each puzzle
is only unlocked upon completing the first part.&lt;&#x2F;p&gt;
&lt;p&gt;Here are a few reasons why I think AoC is great:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Community&lt;&#x2F;li&gt;
&lt;li&gt;Progressive difficulty&lt;&#x2F;li&gt;
&lt;li&gt;Theming&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;community&quot;&gt;Community&lt;&#x2F;h2&gt;
&lt;p&gt;More than almost any other programming competition, AoC fosters a wonderful
supportive community.&lt;&#x2F;p&gt;
&lt;p&gt;There is a fantastic subreddit:
&lt;a href=&quot;https:&#x2F;&#x2F;old.reddit.com&#x2F;r&#x2F;adventofcode&#x2F;&quot;&gt;old.reddit.com&#x2F;r&#x2F;adventofcode&#x2F;&lt;&#x2F;a&gt;
devoted to AoC with a daily thread for participants to share their solutions.
And there are often fun posts with visualizations or other AoC themed content.
There are great discussions of why different approaches might work better than
others or helping out with tricky bits of the puzzles.&lt;&#x2F;p&gt;
&lt;p&gt;From an official perspective, there is a very competitive main leaderboard
available for folks to compete for the fastest solutions each day. But you can
also create and join private leaderboards to have a friendly competition among
friends and&#x2F;or colleagues. Many of the top scorers on the main leaderboard have
YouTube channels and&#x2F;or public repositories to display their solutions.&lt;&#x2F;p&gt;
&lt;p&gt;Here are a couple of my favorite YouTube channels for watching rapid solutions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;channel&#x2F;UCuWLIm0l4sDpEe28t41WITA&#x2F;featured&quot;&gt;Jonathan Paulson&lt;&#x2F;a&gt;:
Consistently close to the top of the leaderboards, I&#x27;ve learned a good bit
about rapidly coding and debugging in python and Jonathan usually includes a
walkthrough of the puzzle and solution at the end of each video.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;c&#x2F;NealWuProgramming&quot;&gt;Neal Wu&lt;&#x2F;a&gt;: Neal produces
solutions in C++ incredibly quickly with a satisfyingly clicky keyboard.
Neal also has videos of himself competing in (and often winning) several other
programming competitions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are also many channels that have videos walking through solutions from a
pedagogical perspective:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;c&#x2F;anthonywritescode&quot;&gt;Anthony Sottile&lt;&#x2F;a&gt;: Great educational
python videos and usually creates a playlist with AoC solutions each year.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@lizthegrey&quot;&gt;Liz Fong-Jones&lt;&#x2F;a&gt;: SRE and observability
guru who solves AoC on stream each year and posts the recordings to YouTube.
Solved 2021 in Go.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And there are many channels with solutions in... unconventional styles:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;user&#x2F;Mitchellh3&quot;&gt;Mitchell Hashimoto&lt;&#x2F;a&gt;: The founder
of HashiCorp produced solutions to days 1-7 of AoC 2021 in PostgreSQL.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;c&#x2F;MarkGritter&quot;&gt;Mark Gritter&lt;&#x2F;a&gt;: An engineer at Akita
Software wrote solutions to all of 2021 in &lt;a href=&quot;https:&#x2F;&#x2F;fstar-lang.org&#x2F;&quot;&gt;F*&lt;&#x2F;a&gt;!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are so many fun variations on AoC solutions to find and explore.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;progressive-difficulty&quot;&gt;Progressive difficulty&lt;&#x2F;h2&gt;
&lt;p&gt;AoC usually starts out fairly simple and works up to a pretty good difficulty,
usually reaching close to the peak around day 15. This makes AoC an ideal
candidate for learning! Whether you&#x27;re trying out a new programming language
or a new library or style, AoC is a fantastic resource to push yourself to
get familiar with your tools, new and old.&lt;&#x2F;p&gt;
&lt;p&gt;Since the puzzle inputs are provided as plain text, the early puzzles emphasize
basic string processing techniques in your chosen language. Even as a
professional programmer, it&#x27;s really helpful to get more comfortable with
the standard library from time to time. I typically try to solve each puzzle
as quickly as possible in python and then jump to a programming language that I
want to know better. Usually, I spend the early puzzles getting familiarized with
the standard library in the second language before the difficult really ramps up.
Once the puzzles get more challenging, it&#x27;s a good opportunity to see how
problem solving approaches differ across different programming languages.&lt;&#x2F;p&gt;
&lt;p&gt;Since the early puzzles are usually not &lt;em&gt;too&lt;&#x2F;em&gt; difficult, AoC is great for
getting folks of all different skill levels to dip their toe in and then start
learning new techniques for solving puzzles using their toolset.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;theming&quot;&gt;Theming&lt;&#x2F;h2&gt;
&lt;p&gt;A lot of other programming competitions have fairly dry and minimal presentations
for their puzzles. &lt;a href=&quot;http:&#x2F;&#x2F;was.tl&#x2F;&quot;&gt;Eric Wastl&lt;&#x2F;a&gt; (the creater of AoC) puts a ton
of care into the preparation of the prompts for each puzzle, often relating the
puzzles back to a common holiday-related theme. This is just plain fun. Eric
has appeared in &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;results?search_query=eric+wastl+advent+of+code&quot;&gt;many videos&lt;&#x2F;a&gt;
providing a behind-the-scenes look at AoC and its history.&lt;&#x2F;p&gt;
&lt;p&gt;At the end of the day, these details help AoC bring a ton of joy to my holiday
season.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;&#x2F;h2&gt;
&lt;p&gt;I think Advent of Code is one of the coolest programming-related events of the
year. It&#x27;s a chance to learn, struggle and grow as part of a larger coding
community. Give it a shot in a couple of weeks! In the meantime, you can
explore the puzzles from previous years to prepare.&lt;&#x2F;p&gt;
&lt;p&gt;Stay tuned for my next post on putting together an AoC template in a few
different languages.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Musings on Python Type Hints</title>
        <published>2022-10-13T00:00:00+00:00</published>
        <updated>2022-10-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://samgeo.codes/python-types/"/>
        <id>https://samgeo.codes/python-types/</id>
        
        <content type="html" xml:base="https://samgeo.codes/python-types/">&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;wphomes.soic.indiana.edu&#x2F;jsiek&#x2F;what-is-gradual-typing&#x2F;&quot;&gt;&amp;quot;Gradual Typing&amp;quot;&lt;&#x2F;a&gt;
has become incredibly popular over the last 8 years or so. The most notable
examples of this phenomena exist in the JavaScript space. Since JavaScript is the
&lt;a href=&quot;https:&#x2F;&#x2F;blog.codinghorror.com&#x2F;javascript-the-lingua-franca-of-the-web&#x2F;&quot;&gt;lingua franca of the web&lt;&#x2F;a&gt;
there have been several efforts to leverage the benefits of static type systems
to enable easier programming-in-the-large for JavaScript. Gradual type systems
such as TypeScript and Flow have found the most success in this space.&lt;&#x2F;p&gt;
&lt;p&gt;Shortly after the release of TypeScript, Guido van Rossum and Ivan Levkivskyi
created &lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0483&#x2F;&quot;&gt;PEP 483&lt;&#x2F;a&gt; proposing a type hinting
system for Python. Notably absent from this proposal is any &amp;quot;official&amp;quot; type
checking program for verifying the correctness of type hints. As a result, there
are four &amp;quot;major&amp;quot; type checkers for python:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;mypy-lang.org&#x2F;about.html&quot;&gt;mypy&lt;&#x2F;a&gt;: A very early project (starting in 2012)
from Jukka Lehtosalo. mypy and its predecessors have heavily influenced
direction of python type hints. mypy has been supported heavily by Jukka&#x27;s
employer Dropbox. mypy is arguably the most popular type checker for Python.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;microsoft&#x2F;pyright&quot;&gt;pyright&lt;&#x2F;a&gt;: A type checker built by Microsoft
with great VS Code and LSP integration. Pyright was first released in 2019
and is bundled in the Microsoft Python extension for VS Code.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;google.github.io&#x2F;pytype&#x2F;&quot;&gt;pytype&lt;&#x2F;a&gt;: A static type analyzer built by
Google. Pytype was first released in 2018 and emphasizes type inference and
local leniency.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;pyre-check.org&#x2F;&quot;&gt;pyre&lt;&#x2F;a&gt;: A static type checker built by Meta. Designed
for large code bases and first-class integration with Buck, Meta&#x27;s build system.
The first release I can find dates back to 2019.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There have been countless arguments over the value of static types over the
years. I really like having a type system that can help me to avoid some
common mistakes and guide me when refactoring. Most of all, however, type hints
should broadcast intent; they are one of the main forms of documentation that
the computer can help to verify.&lt;&#x2F;p&gt;
&lt;p&gt;Since starting a new job earlier this year, I&#x27;ve spent a good amount of time
learning how to leverage type hints to help write readable, maintainable code.
Let&#x27;s take a look at some patterns that arise in Python where type hinting can
get a little bit tricky.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;getting-started&quot;&gt;Getting started&lt;&#x2F;h3&gt;
&lt;p&gt;I&#x27;ll be using mypy since it seems to be the most widely used tool, at the moment.&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t already have python installed, follow the instructions
on the &lt;a href=&quot;https:&#x2F;&#x2F;www.python.org&#x2F;&quot;&gt;official python website&lt;&#x2F;a&gt; to install python for your
platform. At the time of writing, the latest stable version is &lt;code&gt;3.10.7&lt;&#x2F;code&gt; which is
what I will be using for my examples.&lt;&#x2F;p&gt;
&lt;p&gt;With those out of the way, we can start our python project and install mypy:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mkdir python_types &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;&amp;amp;&amp;amp; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; python_types
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3 -m venv venv
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ source venv&#x2F;bin&#x2F;activate  &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#928374;&quot;&gt;# may be different on Windows
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3 -m pip install mypy
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;hello-world-of-type-checking&quot;&gt;&amp;quot;Hello, world!&amp;quot; of type checking&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s start with a simple example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(add(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can run this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3 -m src.hello
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;3
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, let&#x27;s see what mypy has to say:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict src&#x2F;hello.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;hello.py:1: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;hello.py:5: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;add&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 2 errors in 1 file (checked 1 source file&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In strict mode, mypy expects type annotations in certain locations. In particular,
function parameters and return types must be annotated.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s modify our program and try again:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(add(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When we run mypy now:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Success: no issues found in 1 source file
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Cool.&lt;&#x2F;p&gt;
&lt;p&gt;Now you may have noticed that there are some seemingly valid uses of the &lt;code&gt;add&lt;&#x2F;code&gt;
function that mypy now rejects; for example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(add(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;bar&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This program runs just fine:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3 -m src.hello
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;foobar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But when we run mypy:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;hello.py:5: error: Argument 1 to &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;add&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; has incompatible type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;str&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;expected &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;int&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;hello.py:5: error: Argument 2 to &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;add&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; has incompatible type &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;str&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;expected &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;int&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 2 errors in 1 file (checked 1 source file&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, if we annotate the function parameters as being integers, any
reasonable type checker should complain here. But a lot of the power of using
python comes from being able to use functions in a flexible manner.&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately, there are features in the standard library that enable us to create
better annotations fairly easily.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s start with &lt;code&gt;TypeVar&lt;&#x2F;code&gt;
(introduced in &lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0483&#x2F;#type-variables&quot;&gt;pep 483&lt;&#x2F;a&gt;). If
you are familiar with generics in another language such as TypeScript or Java,
&lt;code&gt;TypeVar&lt;&#x2F;code&gt; enables something similar.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take a look at what our function signature might look like with the use of
&lt;code&gt;TypeVar&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;typing &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;TypeVar
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;T &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TypeVar(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;T&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;: T, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;: T) -&amp;gt; T:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(add(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;bar&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This looks close to reasonable, let&#x27;s make sure it runs:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3 -m src.hello
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;foobar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Nice. Let&#x27;s see if mypy likes it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;hello.py:8: error: Returning Any from function declared to return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;T&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;hello.py:8: error: Unsupported left operand type for + (&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;T&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 2 errors in 1 file (checked 1 source file&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Huh. Well, when you think about it, just because &lt;code&gt;x&lt;&#x2F;code&gt; and &lt;code&gt;y&lt;&#x2F;code&gt; have the same type
doesn&#x27;t necessarily mean that &lt;code&gt;x&lt;&#x2F;code&gt; and &lt;code&gt;y&lt;&#x2F;code&gt; can be added together. Maybe &lt;code&gt;x&lt;&#x2F;code&gt;
and &lt;code&gt;y&lt;&#x2F;code&gt; are dictionaries; the add operation is not defined for dictionaries.&lt;&#x2F;p&gt;
&lt;p&gt;Perhaps we can do a little bit better. The critical idea here is called a
&lt;code&gt;Protocol&lt;&#x2F;code&gt; (introduced in &lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0544&#x2F;&quot;&gt;pep 544&lt;&#x2F;a&gt;). A &lt;code&gt;Protocol&lt;&#x2F;code&gt;
lets us specify the shape of objects that we expect to see. In the literature,
you might see this described as &amp;quot;structural subtyping&amp;quot; but most of the time you&#x27;ll
hear it as &amp;quot;duck typing&amp;quot;: if it looks like a duck and quacks like a duck, it must
be a duck.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s see if we can get mypy to approve our program:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;typing &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Protocol, TypeVar
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Self &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TypeVar(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Self&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, bound&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Addable&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;class &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Addable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Protocol&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__add__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: Self, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;other&lt;&#x2F;span&gt;&lt;span&gt;: Self) -&amp;gt; Self:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;T &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TypeVar(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;T&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, bound&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Addable)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span&gt;: T, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;y&lt;&#x2F;span&gt;&lt;span&gt;: T) -&amp;gt; T:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;x &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span&gt;y
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(add(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;bar&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Whew, that&#x27;s quite a bit of typing for such a simple example.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s at least see if it works. First we run it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3 -m src.hello
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;foobar
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now let&#x27;s run mypy:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy src&#x2F;hello.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Success: no issues found in 1 source file
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hooray! This is a lot of machinery for such a simple example. Let&#x27;s unpack
what&#x27;s going on here:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span&gt;Self &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TypeVar(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Self&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, bound&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Addable&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;class &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Addable&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Protocol&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__add__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;: Self, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;other&lt;&#x2F;span&gt;&lt;span&gt;: Self) -&amp;gt; Self:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This allows us to refer to the type of objects that can be added to other
objects of the same type to produce yet another object of that same type.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Self&lt;&#x2F;code&gt; nonsense going on here allows us to constrain the type of the value
that can be added to only those of the same type (and constrain the return type
to the same type). This gets a lot easier in python 3.11 with the introduction of
the &lt;code&gt;Self&lt;&#x2F;code&gt; type to the standard library (&lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0673&#x2F;&quot;&gt;pep 673&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Anthony Sotille has a great video covering the &lt;code&gt;Self&lt;&#x2F;code&gt; type, as well: &lt;a href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;ThATVufmTz8&quot;&gt;link&lt;&#x2F;a&gt;.
As an aside, many of Anthony&#x27;s videos are great bite-sized examples of various
python concepts; he also has a great live stream!&lt;&#x2F;p&gt;
&lt;p&gt;Now, this protocol isn&#x27;t perfect: addition may be defined for combinations
of types. As far as I know, there isn&#x27;t a great way to express that sort of thing,
just yet. Furthermore, while mypy accepts this program, both pyre and pyright seem
to reject it. This is one of the downsides of having several different
type checker implementations. Hopefully these discrepancies get ironed out
as the ecosystem matures.&lt;&#x2F;p&gt;
&lt;p&gt;With that introduction out of the way, let&#x27;s take a look at a pattern that
seem to come up pretty often in python and how we might be able to add type
annotations.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;decorator-factories&quot;&gt;Decorator factories&lt;&#x2F;h3&gt;
&lt;p&gt;Decorators are a curiously functional feature of python. Decorator factories
(functions that produce decorators) are fairly common but surprisingly difficult
to write type annotations for.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re going to take a look at a much more complex example than the &lt;code&gt;add&lt;&#x2F;code&gt; case
that we explored above. In particular, we are going to leverage asynchronous code!
If you aren&#x27;t familiar with &lt;code&gt;asyncio&lt;&#x2F;code&gt; in python, I encourage you to explore
the official documentation: &lt;a href=&quot;https:&#x2F;&#x2F;docs.python.org&#x2F;3&#x2F;library&#x2F;asyncio.html&quot;&gt;asyncio docs&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To start out, we have a complete implementation of a decorator that continuously
prints out the running time of the decorated async function:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;asyncio
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;functools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;inspect
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;time
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;typing &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Final
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;print_with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;interval&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0.1&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    start &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.time()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        elapsed &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.time() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;start
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.format(elapsed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elapsed), end&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(interval)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;OVERWRITE_LINE&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\033[F&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TIMER_FORMAT&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;OVERWRITE_LINE&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;Invocation {{module}}.{{name}}({{arguments}}) has been running for {{{{elapsed:0.2f}}}}s&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;interval_or_callback&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;inner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;        @functools.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;wraps&lt;&#x2F;span&gt;&lt;span&gt;(func)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;wrapper&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;kwargs&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;            arguments &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;inspect.signature(func).bind(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;args, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;kwargs)&lt;&#x2F;span&gt;&lt;span&gt;.arguments
&lt;&#x2F;span&gt;&lt;span&gt;            argument_string &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.join(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{name}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt; = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{value&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;!r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;name, value &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;arguments.items())
&lt;&#x2F;span&gt;&lt;span&gt;            timer_format &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TIMER_FORMAT.format(module&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__module__&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__qualname__&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, arguments&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;argument_string)
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;isinstance&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(interval_or_callback, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                task &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.create_task(print_with_timer(timer_format, interval_or_callback))
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                task &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.create_task(print_with_timer(timer_format))
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;args, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;kwargs)
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;task.cancel()
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span&gt;task
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;except &lt;&#x2F;span&gt;&lt;span&gt;asyncio.CancelledError:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pass
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;result
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;wrapper
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;isinstance&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(interval_or_callback, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;inner
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;inner(interval_or_callback)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;with_timer
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;do_stuff&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5.0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;42
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0.5&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;do_more_stuff&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(duration)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Do a good turn daily.&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    important_number &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;do_stuff()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;The meaning of life is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{important_number}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    scout_slogan &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;do_more_stuff(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3.0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;The scout slogan is \&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{scout_slogan}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;\&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(asyncio.run(main()))
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First, let&#x27;s run it to see what this program does:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ python3 -m src.timer
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Invocation __main__.do_stuff(&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;has been running for 4.97s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;The meaning of life is 42
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Invocation __main__.do_more_stuff(duration = 3.0&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;has been running for 2.51s
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;The scout slogan is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Do a good turn daily.&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s neat! We can see which coroutine we are waiting for and how long it has
been running.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s see if mypy likes this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict src&#x2F;untyped_timer.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:20: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:21: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:23: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:46: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;inner&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:49: error: Untyped decorator makes function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;do_stuff&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; untyped
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:55: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;with_timer&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:55: error: Untyped decorator makes function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;do_more_stuff&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; untyped
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 7 errors in 1 file (checked 1 source file&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Aha, mypy loses track of the types of &lt;code&gt;do_stuff&lt;&#x2F;code&gt; and &lt;code&gt;do_more_stuff&lt;&#x2F;code&gt; since we
haven&#x27;t added type hints to the decorator.&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t a huge deal, here, but if we are relying on mypy to be able to determine
the type of an intermediate expression as we are coding, this can be a pretty
big pain. For example, let&#x27;s try revealing the type of &lt;code&gt;do_stuff&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;reveal_type(do_stuff)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;reveal_type(do_more_stuff)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When we run mypy:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict src&#x2F;untyped_timer.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:20: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:21: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:23: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:46: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;inner&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:49: error: Untyped decorator makes function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;do_stuff&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; untyped
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:55: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;with_timer&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:55: error: Untyped decorator makes function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;do_more_stuff&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; untyped
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:61: note: Revealed type is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Any&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:62: note: Revealed type is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Any&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 7 errors in 1 file (checked 1 source file&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We see that the revealed type is &lt;code&gt;Any&lt;&#x2F;code&gt; which isn&#x27;t very helpful.&lt;&#x2F;p&gt;
&lt;p&gt;If we remove the decorator, let&#x27;s see if we can get a little bit more help:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict src&#x2F;untyped_timer.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:20: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:21: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:23: error: Function is missing a type annotation
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:46: error: Call to untyped function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;inner&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt; in typed context
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:59: note: Revealed type is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;def () -&amp;gt; typing.Coroutine[Any, Any, builtins.int]&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;untyped_timer.py:60: note: Revealed type is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;def (duration: builtins.float) -&amp;gt; typing.Coroutine[Any, Any, builtins.str]&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Found 4 errors in 1 file (checked 1 source file&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So we see that mypy can handle this sort of thing, in general. How can we
leverage type hints to give mypy enough information to tell us the type with
the decorator in use?&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s dive in!&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;asyncio
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;functools
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;inspect
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;time
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;from &lt;&#x2F;span&gt;&lt;span&gt;typing &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;import &lt;&#x2F;span&gt;&lt;span&gt;Awaitable, Callable, Final, overload, ParamSpec, Protocol, TypeVar
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;print_with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;interval&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0.1&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;None&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    start &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.time()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;while &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        elapsed &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;time.time() &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;- &lt;&#x2F;span&gt;&lt;span&gt;start
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.format(elapsed&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;elapsed), end&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(interval)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;OVERWRITE_LINE&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\033[F&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TIMER_FORMAT&lt;&#x2F;span&gt;&lt;span&gt;: Final[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;\n&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;OVERWRITE_LINE&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;Invocation {{module}}.{{name}}({{arguments}}) has been running for {{{{elapsed:0.2f}}}}s&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;P &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;ParamSpec(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;P&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;R &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TypeVar(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;R&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;class &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Decorator&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;Protocol&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__call__&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt;: Callable[P, Awaitable[R]]) -&amp;gt; Callable[P, Awaitable[R]]:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;overload
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;interval_or_callback&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; Decorator:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;overload
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;interval_or_callback&lt;&#x2F;span&gt;&lt;span&gt;: Callable[P, Awaitable[R]]) -&amp;gt; Callable[P, Awaitable[R]]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;interval_or_callback&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;Callable[P, Awaitable[R]]) -&amp;gt; Decorator &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span&gt;Callable[P, Awaitable[R]]:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;inner&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func&lt;&#x2F;span&gt;&lt;span&gt;: Callable[P, Awaitable[R]]) -&amp;gt; Callable[P, Awaitable[R]]:
&lt;&#x2F;span&gt;&lt;span&gt;        @functools.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;wraps&lt;&#x2F;span&gt;&lt;span&gt;(func)
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;wrapper&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;args&lt;&#x2F;span&gt;&lt;span&gt;: P.args, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;kwargs&lt;&#x2F;span&gt;&lt;span&gt;: P.kwargs) -&amp;gt; R:
&lt;&#x2F;span&gt;&lt;span&gt;            arguments &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;inspect.signature(func).bind(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;args, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;kwargs)&lt;&#x2F;span&gt;&lt;span&gt;.arguments
&lt;&#x2F;span&gt;&lt;span&gt;            argument_string &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;.join(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{name}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt; = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{value&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;!r&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;for &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;name, value &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;in &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;arguments.items())
&lt;&#x2F;span&gt;&lt;span&gt;            timer_format &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;TIMER_FORMAT.format(module&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__module__&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__qualname__&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;, arguments&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;argument_string)
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;isinstance&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(interval_or_callback, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                task &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.create_task(print_with_timer(timer_format, interval_or_callback))
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                task &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.create_task(print_with_timer(timer_format))
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                result &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;func(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;args, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;kwargs)
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;finally&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;task.cancel()
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;try&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span&gt;task
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;except &lt;&#x2F;span&gt;&lt;span&gt;asyncio.CancelledError:
&lt;&#x2F;span&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;pass
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;()
&lt;&#x2F;span&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;result
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;wrapper
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;isinstance&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(interval_or_callback, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;inner
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;inner(interval_or_callback)
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;with_timer
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;do_stuff&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;5.0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;42
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;with_timer&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0.5&lt;&#x2F;span&gt;&lt;span&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;do_more_stuff&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;duration&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;float&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;str&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;asyncio.sleep(duration)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;Do a good turn daily.&amp;quot;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;async def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#407959;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    important_number &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;do_stuff()
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;The meaning of life is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{important_number}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    scout_slogan &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;await &lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;do_more_stuff(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;3.0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;The scout slogan is \&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;{scout_slogan}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;\&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;__name__ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b23c15;&quot;&gt;== &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:
&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9d0006;&quot;&gt;raise &lt;&#x2F;span&gt;&lt;span style=&quot;color:#b57614;&quot;&gt;SystemExit&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;(asyncio.run(main()))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There&#x27;s a lot going on here, so let&#x27;s walk through some of the new additions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ParamSpec&lt;&#x2F;code&gt;: this enables us to capture the signature of a &lt;code&gt;Callable&lt;&#x2F;code&gt; object.
You can do some pretty powerful things including adding additional arguments to functions
while enabling your type checker to still understand the types being used. See &lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0612&#x2F;&quot;&gt;pep 612&lt;&#x2F;a&gt;
to read more about how &lt;code&gt;ParamSpec&lt;&#x2F;code&gt; works.&lt;&#x2F;li&gt;
&lt;li&gt;Decorator protocol: in many cases, mypy doesn&#x27;t actually force us to use a protocol for this sort of thing, but it is actually pretty nice.
This basically says that our decorator can take any callable object that takes in arguments that adhere to parameter specification &lt;code&gt;P&lt;&#x2F;code&gt;
and returns objects of type &lt;code&gt;R&lt;&#x2F;code&gt; and our decorator will return a callable object with that same type.&lt;&#x2F;li&gt;
&lt;li&gt;Overload: we want users to be able to use &lt;code&gt;with_timer&lt;&#x2F;code&gt; with and without an interval. Always having to write
&lt;code&gt;with_timer()&lt;&#x2F;code&gt; is kind of awkward, so we can branch on the type that we receive as input. &lt;code&gt;overload&lt;&#x2F;code&gt; informs the
type checker that the return type of our decorator factory is always consistent depending on the input type
to our decorator. Details on &lt;code&gt;overload&lt;&#x2F;code&gt; can be found in &lt;a href=&quot;https:&#x2F;&#x2F;peps.python.org&#x2F;pep-0484&#x2F;#function-method-overloading&quot;&gt;pep 484&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;By leveraging these ideas, we are able to get mypy to fully understand what is going on with the types
of our decorated functions.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s first run mypy and see if it works:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict src&#x2F;timer.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Success: no issues found in 1 source file
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Great!&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s see if mypy can correctly identify the types of our decorated functions
by adding &lt;code&gt;reveal_type&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;reveal_type(do_stuff)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;reveal_type(do_more_stuff)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#8f3f71;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we run mypy again:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#fcf0ca;color:#282828aa;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#282828;&quot;&gt;$ mypy --strict src&#x2F;timer.py
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;timer.py:75: note: Revealed type is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;def () -&amp;gt; typing.Awaitable[builtins.int]&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;src&#x2F;timer.py:76: note: Revealed type is &lt;&#x2F;span&gt;&lt;span style=&quot;color:#79740e;&quot;&gt;&amp;quot;def (duration: builtins.float) -&amp;gt; typing.Awaitable[builtins.str]&amp;quot;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#282828;&quot;&gt;Success: no issues found in 1 source file
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pretty neat!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;&#x2F;h3&gt;
&lt;p&gt;You can see that as library authors, there are lots of tools at our disposal for
ensuring that we can produce well-typed APIs for our users while still leveraging
many of the dynamic features of python.&lt;&#x2F;p&gt;
&lt;p&gt;There are plenty more things to learn about in the world of python type hints.
If these ideas are exciting to you, dive into the peps and consider contributing
to one of the type checking projects!&lt;&#x2F;p&gt;
&lt;p&gt;The static typing story for python is still very young. We don&#x27;t have many of the
type computation facilities of TypeScript. But the story is getting better!
And from my perspective, having another way to help communicate intent and enable
users to better understand interfaces is fantastic.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
