<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Matthew Herman</title>
    <description>A collection of tech-related ramblings and other things I&apos;m interested in.
</description>
    <link>http://www.matthewherman.net/</link>
    <atom:link href="http://www.matthewherman.net/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 18 Jun 2023 21:53:15 -0500</pubDate>
    <lastBuildDate>Sun, 18 Jun 2023 21:53:15 -0500</lastBuildDate>
    <generator>Jekyll v4.2.2</generator>
    
      <item>
        <title>Printing Diagnostics in Neovim</title>
        <description>&lt;p&gt;I’m starting to understand what is so great about the extensibility of (Neo)Vim.&lt;/p&gt;

&lt;p&gt;The language server support built into Neovim will display diagnostic messages (errors, warnings, etc.) as a hovering tooltip to the right of the line where they occur. This is normally perfectly fine, but if you have a long line or message it will result in the message being cut off.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/neovim-print-diagnostics/diagnostics_before.png&quot; alt=&quot;diagnostic messages displayed inline&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I wasn’t able to figure out how to view the message when that happens. It doesn’t seem to let you scroll to the right. There is probably some way to see them or to force them to be displayed elsewhere (for example, below the line), but I decided to use it as an opportunity to work with the Neovim API again.&lt;/p&gt;

&lt;p&gt;We can retrieve the diagnostics for the current buffer using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vim.diagnostic.get(0)&lt;/code&gt; and display them to the user with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vim.notify(...)&lt;/code&gt;. First we’ll handle the case where there are no diagnostics:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;local diagnostics = vim.diagnostic.get(0)
if (not diagnostics or #diagnostics == 0) then
    vim.notify(&quot;No issues found&quot;, vim.log.levels.INFO)
    return
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The log level passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vim.notify&lt;/code&gt; affects how Neovim displays the message.&lt;/p&gt;

&lt;p&gt;If there are diagnostics, we want to display them. I’m not sure how the order of the diagnostics table is determined, but we probably want to show them in line number order:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;local function by_line_num (a, b)
    return a.lnum &amp;lt; b.lnum
end
...
table.sort(diagnostics, by_line_num)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally we build up a table of formatted messages, concatenate them, and display them as an error with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vim.notify&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;local messages = { &quot;&quot; }
local sev_text = {
    [vim.diagnostic.severity.ERROR] = &quot;Error&quot;,
    [vim.diagnostic.severity.WARN] = &quot;Warning&quot;
}
for _, d in ipairs(diagnostics) do
    local sev = sev_text[d.severity] or &quot;Info&quot;
    table.insert(messages, sev..&quot;: &quot;..d.message..&quot; [&quot;..d.lnum..&quot;:&quot;..d.col..&quot;]&quot;)
end
vim.notify(table.concat(messages, &quot;\n&quot;), vim.log.levels.ERROR)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The full function looks like this:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;local function print_diagnostics()
    local function by_line_num (a, b)
        return a.lnum &amp;lt; b.lnum
    end

    local diagnostics = vim.diagnostic.get(0)
    if (not diagnostics or #diagnostics == 0) then
        vim.notify(&quot;No issues found&quot;, vim.log.levels.INFO)
        return
    end

    table.sort(diagnostics, by_line_num)
    local messages = { &quot;&quot; }
    local sev_text = {
        [vim.diagnostic.severity.ERROR] = &quot;Error&quot;,
        [vim.diagnostic.severity.WARN] = &quot;Warning&quot;
    }
    for _, d in ipairs(diagnostics) do
        local sev = sev_text[d.severity] or &quot;Info&quot;
        table.insert(messages, sev..&quot;: &quot;..d.message..&quot; [&quot;..d.lnum..&quot;:&quot;..d.col..&quot;]&quot;)
    end
    vim.notify(table.concat(messages, &quot;\n&quot;), vim.log.levels.ERROR)
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using that function we can view all diagnostic messages for a buffer at the same time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/neovim-print-diagnostics/diagnostics_after.png&quot; alt=&quot;diagnostic messages displayed with vim.notify&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It is incredibly powerful to be able to interact with your editor programatically. I think there is some risk that it becomes an infinite number of yaks to shave, but so far I’ve enjoyed using the Neovim API for tasks like this.&lt;/p&gt;
</description>
        <pubDate>Sun, 18 Jun 2023 21:44:00 -0500</pubDate>
        <link>http://www.matthewherman.net/programming/2023/06/18/neovim-print-diagnostics.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2023/06/18/neovim-print-diagnostics.html</guid>
        
        <category>programming neovim lua</category>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Trying to Write</title>
        <description>&lt;p&gt;I want to write.&lt;/p&gt;

&lt;p&gt;A couple days ago I posted something for the first time since 2020. It felt good. I’ve always enjoyed writing (editing not so much), but I haven’t really had much opportunity since I finished college. I mean, I write every day at my job: emails, documentation, design docs, but those things aren’t really for me.&lt;/p&gt;

&lt;p&gt;I haven’t written because of all the usual excuses. I don’t have time. I have nothing to write about. I’m not good enough at it. At the end of the day that’s all they are. Excuses.&lt;/p&gt;

&lt;p&gt;I’ve mainly written about programming since it’s what I know and is something I enjoy. I’m hoping to continue to do so, but I also want to write about other things in my life like my family, my dogs, gardening, and nature.&lt;/p&gt;

&lt;p&gt;If I post something at least once a month I think I will be happy with my progress. Like anything else, the more I do it the easier it will get.&lt;/p&gt;
</description>
        <pubDate>Wed, 14 Jun 2023 14:40:00 -0500</pubDate>
        <link>http://www.matthewherman.net/writing/2023/06/14/trying-to-write.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/writing/2023/06/14/trying-to-write.html</guid>
        
        <category>writing</category>
        
        
        <category>writing</category>
        
      </item>
    
      <item>
        <title>Creating a Persistent Terminal in Neovim</title>
        <description>&lt;p&gt;I’ve dabbled with using Vim as an editor off and on over the years and it still hasn’t quite stuck. Mostly I have just switched to using Vim keybindings in other editors (such as VS Code and JetBrains Rider) since I like how ergonomic and quick they are.&lt;/p&gt;

&lt;p&gt;A while back I became familiar with &lt;a href=&quot;https://neovim.io&quot;&gt;Neovim&lt;/a&gt; and was intrigued by the Lua API it exposes for configuration and plugins. Vimscript always seemed…strange, so it was refreshing to see it use a more popular, general-purpose programming language like Lua. I am once again attempting to learn to use (Neo)Vim and this time I tried my hand at some scripting in Lua.&lt;/p&gt;

&lt;p&gt;While learning Lua (by doing the excellent exercises over at &lt;a href=&quot;https://exercism.org&quot;&gt;Exercism&lt;/a&gt;) I would often want to switch between my editor and another shell to run unit tests or test something in the REPL. I could do that using something like tmux or just separate tabs in my terminal emulator, but I wanted to be able to run the commands without leaving Neovim.&lt;/p&gt;

&lt;p&gt;It turns out that Neovim provides the &lt;a href=&quot;https://neovim.io/doc/user/nvim_terminal_emulator.html#terminal-emulator&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:terminal&lt;/code&gt;&lt;/a&gt; command which will start your default shell in a new buffer. I quickly created a keymap to run the command, but was disappointed by the workflow. To close the terminal I was running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit&lt;/code&gt; to exit my shell and then hitting enter to automatically close the buffer.&lt;/p&gt;

&lt;p&gt;This quickly became annoying so I checked the docs and saw that I could return to normal mode with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-\&amp;gt;&amp;lt;C-n&amp;gt;&lt;/code&gt; and then hit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-o&amp;gt;&lt;/code&gt; to return to my previous buffer. This worked fine (although desperately needed its own keymap), but whenever I would return to my terminal it would create a brand new shell and buffer instead of reusing the old one.&lt;/p&gt;

&lt;p&gt;The terminal is a buffer like any other and will show up if you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:ls&lt;/code&gt;, but switching between buffers in that way is still slow for me so I wanted to try scripting my solution:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;function toggle_terminal()
    for i, buffer in ipairs(vim.api.nvim_list_bufs()) do
        local buffer_name = vim.api.nvim_buf_get_name(buffer)
        if (string.sub(buffer_name, 1, 7) == &quot;term://&quot;) then
            vim.api.nvim_win_set_buf(0, buffer)
            return
        end
    end
    vim.api.nvim_command(&quot;:terminal&quot;)
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The function grabs the list of all buffers and looks for the first name that starts with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;term://&lt;/code&gt; (the default naming scheme for terminal buffers) and sets the current window to that buffer if it finds one. Otherwise, it runs the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:terminal&lt;/code&gt; command to open a new one. I tried to figure out how to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvim_term_open&lt;/code&gt; function instead of the command, but I couldn’t get it to work.&lt;/p&gt;

&lt;p&gt;This worked great! The first time I run it Neovim will spin up a new terminal, but after that it will simply switch back to the original terminal with all of my output and history.&lt;/p&gt;

&lt;p&gt;So far I’ve been enjoying Neovim, especially with all of the really nice plugins people have created for it. I have found &lt;a href=&quot;https://github.com/nvim-telescope/telescope.nvim&quot;&gt;telescope&lt;/a&gt; and &lt;a href=&quot;https://github.com/nvim-tree/nvim-tree.lua&quot;&gt;nvim-tree&lt;/a&gt; to be really useful. The fact that LSP support is built-in rather than provided by plugins is also nice. The API documentation, which is available online and with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:help&lt;/code&gt; command, is very detailed, but the thing I’ve been missing the most has been examples of how to do certain tasks like creating a terminal with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvim_term_open&lt;/code&gt;. I could dig through the source of other plugins to figure it out, but most are complex enough that finding the specific use case I need is difficult. Overall, it feels like (Neo)Vim is “sticking” a little bit more for me now and may actually become an editor that I use regularly.&lt;/p&gt;
</description>
        <pubDate>Mon, 12 Jun 2023 19:40:00 -0500</pubDate>
        <link>http://www.matthewherman.net/programming/2023/06/12/nvim-persistent-terminal.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2023/06/12/nvim-persistent-terminal.html</guid>
        
        <category>programming neovim</category>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Functional Gift Wrapping</title>
        <description>&lt;p&gt;This year I decided to contribute to the &lt;a href=&quot;https://sergeytihon.com/2020/10/22/f-advent-calendar-in-english-2020/&quot;&gt;F# Advent Calendar&lt;/a&gt;, a yearly event where members of the F# community share their thoughts with others through a series of blog posts and articles.&lt;/p&gt;

&lt;p&gt;In light of the holiday season I chose a project that is related to something many of us our doing this time of year - wrapping gifts! But let me stop you before you get carried away with visions of present-wrapping robots or machine learning algorithms for selecting the best gifts. It’s not going to be quite that exciting, but it could help you be a more efficient wrapper.&lt;/p&gt;

&lt;p&gt;I’m going to be walking through the implementation of one of my favorite algorithms: the &lt;a href=&quot;https://en.wikipedia.org/wiki/Gift_wrapping_algorithm&quot;&gt;Gift Wrapping algorithm&lt;/a&gt;. It’s an algorithm that is used to compute the &lt;a href=&quot;https://en.wikipedia.org/wiki/Convex_hull&quot;&gt;“convex hull”&lt;/a&gt; of a set of points, which is the smallest subset of points which form a convex polygon that encapsulates all the remaining points.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/dots-complete.png&quot; alt=&quot;completed convex hull&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The Gift Wrapping algorithm (also known as Jarvis march) is an interesting solution to the problem as it operates by wrapping the points similar to how you would wrap a gift. It has a time complexity of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O(nh)&lt;/code&gt; where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n&lt;/code&gt; is the total number of points and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;h&lt;/code&gt; is the number of points in the hull, so its performance is dependent on the size of the result set. It’s often outperformed by other convex hull algorithms, but it is simple to implement and interesting nonetheless. You can learn about some of the other algorithms &lt;a href=&quot;https://en.wikipedia.org/wiki/Convex_hull_algorithms&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;the-algorithm&quot;&gt;The Algorithm&lt;/h1&gt;

&lt;p&gt;We will be be working off of the pseudocode that is presented on the &lt;a href=&quot;https://en.wikipedia.org/wiki/Gift_wrapping_algorithm#Pseudocode&quot;&gt;wikipedia page&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;algorithm jarvis(S) is
    // S is the set of points
    // P will be the set of points which form the convex hull. Final set size is i.
    pointOnHull = leftmost point in S // which is guaranteed to be part of the CH(S)
    i := 0
    repeat
        P[i] := pointOnHull
        endpoint := S[0]      // initial endpoint for a candidate edge on the hull
        for j from 0 to |S| do
            // endpoint == pointOnHull is a rare case and can happen only when j == 1 and a better endpoint has not yet been set for the loop
            if (endpoint == pointOnHull) or (S[j] is on left of line from P[i] to endpoint) then
                endpoint := S[j]   // found greater left turn, update endpoint
        i := i + 1
        pointOnHull = endpoint
    until endpoint = P[0]      // wrapped around to first hull point
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The algorithm is best explained visually. We start with a point that we know will be on the hull, the leftmost point in the set, which is point &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; in this case.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/dots-labeled.png&quot; alt=&quot;initial set of six points, A through F&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We then choose an arbitrary point in the set as our first endpoint. Let’s say we chose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt;. From here, we’re going to imagine a line through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; by which we’re going to judge other points.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/gift-wrapping-1.png&quot; alt=&quot;first test line from A to B&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For each other point in the set we need to determine whether it is left of the line or right of the line. If it is left of the line, it becomes the new endpoint by which we test the remaining points. By the time we test every point, we’ll have identified the leftmost point (rotationally, relative to the last hull point) which must be on the hull as well.&lt;/p&gt;

&lt;p&gt;So for example, we have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; which is our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pointOnHull&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; which is our current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt;, and we’re going to begin testing points. We might start with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt;. The point falls to the right of the line through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; so we know &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt; cannot be on the hull.&lt;/p&gt;

&lt;p&gt;If we tested &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; next, we’d see that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; is in fact to the left of the line. Since it’s further left than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt;, it becomes our new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/gift-wrapping-2.png&quot; alt=&quot;new test line from A to D&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We would continue on to test &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;E&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F&lt;/code&gt;, both of which would be right of the line through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt;, and determine that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; is the next point on the hull.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/gift-wrapping-3.png&quot; alt=&quot;added D to the hull&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This process repeats with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; as our new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pointOnHull&lt;/code&gt;, then the next one we find, and so on until we make our way back to the original starting point. By then we’ll have finished identifying our convex hull.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/gift-wrapping-4.png&quot; alt=&quot;completed hull from A to D to E to F&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;an-imperative-approach&quot;&gt;An Imperative Approach&lt;/h1&gt;

&lt;p&gt;Before we implement the algorithm in F# functionally, I’d like to begin by showing it in the imperative style mirroring the pseudocode above. This will let us get to a working implementation quickly and give us a good starting point for an iterative refactor.&lt;/p&gt;

&lt;p&gt;The only custom type we need for this is a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Point&lt;/code&gt; record:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot; data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The imperative implementation of our function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toConvexHull: Point list -&amp;gt; Point list&lt;/code&gt; is the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot; data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toConvexHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; 
    &lt;span class=&quot;c1&quot;&gt;// Start at the leftmost point since it is guaranteed to be on the hull&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minBy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atStartingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atStartingPoint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isLeftOfLine&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;atStartingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You should be able to line it up with the pseudocode pretty easily. We get our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;startingPoint&lt;/code&gt; by finding the point in our list with the smallest &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X&lt;/code&gt; coordinate and then initialize our list of hull points and our first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pointOnHull&lt;/code&gt;. From there we enter our while loop where we add our current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pointOnHull&lt;/code&gt; to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hull&lt;/code&gt; and choose an arbitrary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt; (the first item in the list) to test with. We then test each point in the set, and if it is further left than our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt;, we make it the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt;. Once we’re done, we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pointOnHull&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt; since it is our newest hull point. Then as long as that point wasn’t the one we started with, we start all over to find the next hull point.&lt;/p&gt;

&lt;p&gt;The one bit that we’ve skimmed over on purpose is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isLeftOfLine&lt;/code&gt; function. That is the predicate we use to determine if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;candidatePoint&lt;/code&gt; is left of the line created by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pointOnHull&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt;. In order to explain its implementation, we’ll need to take a detour into some math…&lt;/p&gt;

&lt;p&gt;One way we can determine whether a point is to the left (or right) of a line is by using a &lt;a href=&quot;https://en.wikipedia.org/wiki/Cross_product&quot;&gt;cross product&lt;/a&gt;. Cross products are used for all sorts of things that I don’t remember from school, but the one that is useful for us is the fact that the sign of the cross product determines whether the angle created by two vectors is clockwise or counter-clockwise. For example, imagine we have two vectors &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V1&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/cross-product-1.png&quot; alt=&quot;vectors V1 and V2 on a grid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The cross product, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V1 X V2&lt;/code&gt;, will be positive since the angle from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V1&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V2&lt;/code&gt; is counter-clockwise. The opposite cross product, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V2 X V1&lt;/code&gt;, is negative because the angle is clockwise. I don’t know why this is true, just that it is.&lt;/p&gt;

&lt;p&gt;So now if we have a line from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; and a third point &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt;, we can use the cross product to determine if the angle between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A-&amp;gt;B&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A-&amp;gt;P&lt;/code&gt; is counter-clockwise, which would mean that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt; is left of the line.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/cross-product-2.png&quot; alt=&quot;A, B, and P with the angle between A-&amp;gt;B and A-&amp;gt;P&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To do that we treat &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt; as the two vectors, but since they’re starting from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; rather than the origin &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(0,0)&lt;/code&gt; we need to subtract the vector &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; from each of them.&lt;/p&gt;

&lt;p&gt;The formula to calculate the cross product of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt; is:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;B X P = (Bx * Py) - (By * Px)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Which becomes the following after we subtract the vector &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; from both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(B - A) X (P - A) = ((Bx - Ax) * (Py - Ay)) - ((By - Ay) * (Px - Ax))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can translate this into code as the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;directionFromLine&lt;/code&gt; which is then used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isLeftOfLine&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot; data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Direction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Left&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Right&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Colinear&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;directionFromLine&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;crossProduct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;crossProduct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Left&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;crossProduct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Right&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Colinear&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isLeftOfLine&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;point&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lineStart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lineEnd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;directionFromLine&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lineStart&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lineEnd&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With that we’ve got a complete implementation of the Gift Wrapping algorithm, but it’s littered with loops and mutable state. Next we’ll work towards refactoring that code to be more functional in nature.&lt;/p&gt;

&lt;h1 id=&quot;towards-a-functional-solution&quot;&gt;Towards a Functional Solution&lt;/h1&gt;

&lt;p&gt;Let’s approach this by trying to convert a piece at a time. The meat of the function is in the two loops: an inner for loop that is used to identify the next hull point and a surrounding while loop that collects them all.&lt;/p&gt;

&lt;p&gt;We should be able to extract that inner for loop pretty easily. It takes a point it knows is on the hull, a point that could be on the hull, and then tests each of the other points, replacing the assumed new hull point whenever it finds one that is further left. This could be rewritten as a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reduce&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot; data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findNextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isLeftOfLine&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The function passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List.reduce&lt;/code&gt; takes an accumulator and the next element in the list. It starts by passing the first two elements of the list in, then the result of that with the third element, the result of that with the fourth element, and so on. We utilize this behavior by passing the potential hull point, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt; as the accumulated value. In the function we test whether the next point in the list, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;candidatePoint&lt;/code&gt; is left of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endpoint&lt;/code&gt;, and if so pass that point as the accumulated value instead. This lets us mimic the behavior of the for loop without the need for mutable state.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot; data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toConvexHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findNextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isLeftOfLine&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minBy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atStartingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atStartingPoint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findNextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;atStartingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hull&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Our code is looking a little more functional, but there’s still some work to do. A few mutable values remain and it would be great if we could eliminate that while loop.&lt;/p&gt;

&lt;h1 id=&quot;functional-gift-wrapping&quot;&gt;Functional Gift Wrapping&lt;/h1&gt;

&lt;p&gt;The easiest way for us to replace that while loop is through recursion. This part of the algorithm is a natural fit since we are using a known hull point to find the next hull point, then using that new hull point to find the next hull point, and on and on, until we eventually hit our stop condition by running into our initial starting point. From there we just need to collect all of the values we’ve identified.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot; data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findPointsOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findNextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;findPointsOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;With that recursive helper function defined, our final &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toConvexHull&lt;/code&gt; function looks like the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-fsharp&quot; data-lang=&quot;fsharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toConvexHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findNextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isLeftOfLine&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;candidatePoint&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;rec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findPointsOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findNextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;findPointsOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextPointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidatePoints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minBy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;findPointsOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startingPoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pointOnHull&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;points&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;We now have a working, functional implementation of the Gift Wrapping algorithm.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/gift-wrapping/fable-app.png&quot; alt=&quot;working application&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you would like to play with the application or view the complete source code, you can find the repository &lt;a href=&quot;https://github.com/mattherman/fable-gift-wrapping&quot;&gt;here&lt;/a&gt;. I implemented the small &lt;a href=&quot;https://fable.io&quot;&gt;Fable&lt;/a&gt; application you see above. It will let you randomize the points and generate the convex hull. The three implementations of the algorithm can be found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/GiftWrapping.fs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Happy holidays!&lt;/p&gt;

</description>
        <pubDate>Sun, 13 Dec 2020 17:22:00 -0600</pubDate>
        <link>http://www.matthewherman.net/programming/2020/12/13/functional-gift-wrapping.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2020/12/13/functional-gift-wrapping.html</guid>
        
        <category>programming</category>
        
        <category>F#</category>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>.NET Core Tools</title>
        <description>&lt;p&gt;Beginning with .NET Core 2.1, developers are able to easily create and distribute “.NET Core Tools”. These tools are simply .NET console applications that are delivered as a special form of NuGet package. Due to how simple they are to create it is a great way to share small applications and tools with your fellow developers.&lt;/p&gt;

&lt;h1 id=&quot;creating-net-core-tools&quot;&gt;Creating .NET Core Tools&lt;/h1&gt;

&lt;p&gt;Creating a new .NET Core tool is as simple as creating a new console app, adding a few lines to the project file, and packaging the project. To begin, create your console application using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet new console&lt;/code&gt;. Update the generated project to do whatever you like (or just leave the default “Hello World!” implementation) and then add the following to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PropertyGroup&lt;/code&gt; node in your project’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csproj&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PackAsTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PackAsTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ToolCommandName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ToolCommandName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PackAsTool&lt;/code&gt; element is what signifies that this should be packaged as a tool rather than a regular NuGet package. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ToolCommandName&lt;/code&gt; lets you optionally specify the command that should be used to run the tool. If it is not provided, it will default to the project name. As these tools are still NuGet packages you will also want to provide the usual NuGet metadata like an ID, version, etc. It’s important that you choose an ID that avoids any naming collisions if you’re publishing this to the public nuget.org repository.&lt;/p&gt;

&lt;p&gt;The final steps are to build your project with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet build&lt;/code&gt; and then package it using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet pack&lt;/code&gt;. From there, all you need to do is upload it to a NuGet repository in order to make it available for others to install.&lt;/p&gt;

&lt;h1 id=&quot;using-net-core-tools&quot;&gt;Using .NET Core Tools&lt;/h1&gt;

&lt;p&gt;Once the tool is packaged and published, users are able to install it using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet tool install -g &amp;lt;tool_name&amp;gt;&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-g&lt;/code&gt; switch will install the package globally. This adds the command to the machine’s path and allows it to be run anywhere by simply executing the appropriate command, like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello-world&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Starting in .NET Core 3.1, the SDK also supports installing tools locally to a project. This allows you to install different versions of the same tool in different workspaces. Local tools rely on a manifest file which can be used to restore/install all the tools necessary for that project. Local tools must be run via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet tool run &amp;lt;command_name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before installing any tools make sure you trust the author and have reviewed the source if possible. These tools are not sandboxed or restricted in any way so it is vital that you know what you are installing. To uninstall a tool you can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dotnet tool uninstall &amp;lt;tool_name&amp;gt;&lt;/code&gt; command. If the tool was installed globally, be sure to include the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-g&lt;/code&gt; switch.&lt;/p&gt;

&lt;h1 id=&quot;additional-reading&quot;&gt;Additional Reading&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools&quot;&gt;.NET Core tools&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools-how-to-create&quot;&gt;Create a .NET Core tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Sun, 30 Aug 2020 16:13:00 -0500</pubDate>
        <link>http://www.matthewherman.net/programming/2020/08/30/net-core-tools.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2020/08/30/net-core-tools.html</guid>
        
        <category>programming</category>
        
        <category>tools</category>
        
        <category>dotnet</category>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Seven Day Roguelike 2020</title>
        <description>&lt;p&gt;This year I decided to join the &lt;a href=&quot;https://7drl.com/&quot;&gt;Seven Day Roguelike (7DRL)&lt;/a&gt; game jam. It’s a week long event where participants spend time creating new roguelike games, individually or as a team. Games in this genre vary greatly but generally have the following elements:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Permadeath&lt;/strong&gt; - players are unable to respawn after death, they must start the game from scratch&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Procedural content&lt;/strong&gt; - levels, enemies, and items are unique within each play of the game&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Turn based&lt;/strong&gt; - gameplay is turn based, encouraging tactics over reflexes&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Simple graphics&lt;/strong&gt; - usually ASCII or tile based&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Some popular traditional roguelike games are NetHack, Angband, ADOM, and (of course) Rogue. Some newer games include DCSS, Brogue, and Cogmind.&lt;/p&gt;

&lt;p&gt;I had never participated in a game jam and had very little experience with game development. This challenge gave me the opportunity to learn more about game development, roguelikes, and even a fun new algorithm. While I made less progress than I anticipated, it was an enriching experience and has introduced me to a new potential hobby.&lt;/p&gt;

&lt;h1 id=&quot;getting-started-with-godot&quot;&gt;Getting Started With Godot&lt;/h1&gt;

&lt;p&gt;When I tried to get into game development in the past I had used &lt;a href=&quot;https://phaser.io/&quot;&gt;Phaser&lt;/a&gt;, but scarcely accomplished more than the tutorials. Since I was hoping to use this jam as another introduction to game development, I decided to choose a more fully featured game engine that would give me the ability to make all sorts of games once I invested the time into learning it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://godotengine.org/&quot;&gt;Godot&lt;/a&gt; is a free and open source game engine that allows you to create both 2d and 3d games. Although not as polished, it at least seems similar to the big players like Unity and Unreal Engine. It was also appealing to me that it was open source since I try to use free software as much as possible for my personal projects. There are a range of roguelike-specific game libraries (&lt;a href=&quot;http://ondras.github.io/rot.js/hp/&quot;&gt;rot.js&lt;/a&gt;, &lt;a href=&quot;https://github.com/libtcod/libtcod&quot;&gt;libtcod&lt;/a&gt;) that are often recommended for the game jam, but again, I wanted to learn something a little more general purpose than that.&lt;/p&gt;

&lt;p&gt;I was pleased to find a really nice set of &lt;a href=&quot;https://docs.godotengine.org/en/stable/getting_started/step_by_step/index.html&quot;&gt;tutorials&lt;/a&gt; were available on their website. These range from informational articles on specific topics to a step-by-step tutorial where you make a full game from scratch. I found that while they didn’t use anything similar to a roguelike to demonstrate these concepts, they covered a wide enough range of material that I was much more prepared by the time I had finished them.&lt;/p&gt;

&lt;p&gt;Game development with Godot is centered around creating “scenes” that are made up of trees of nodes that have different properties. These scenes can define specific entities like the player or enemies, as well as something more abstract like a map or level in the game. Generally these are then composed into a game via “instancing”. For example, if you were to define a Player scene you might start with a node called Area2D at the root which is used for 2d collision and physics. Then you would add children like a Sprite node for the characters image and a CollisionShape2D to define how it collides with other objects.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Player (Area2D)
  |---Sprite
  |---CollisionShape2D
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;An instance of this scene could then be added to a separate top-level scene that defines the game itself, which may have other nodes like the map and the heads-up display.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Main (Node)
  |---Player
  |---Map
  |---HUD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also instance scenes programatically. You would use that strategy for things that may be defined dynamically like enemies that spawn at different intervals.&lt;/p&gt;

&lt;p&gt;Godot allows you to attach scripts to any node in a scene. These scripts basically define a class that extends whatever the type of the node is. They come with a variety of methods you can override related to the game loop such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_init&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_ready&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_process&lt;/code&gt;. The documentation suggests you write your scripts using a language called GDScript which was created for the engine itself, but you can also use C# or C++. I decided to use GDScript because of its tight integration with the tooling even though I am more experienced with C#.&lt;/p&gt;

&lt;p&gt;Communication between different nodes is done using an event system that Godot calls “signals”. There are predefined signals that nodes emit such as Area2D’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;area_entered&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;area_exited&lt;/code&gt; but developers can also define their own signals to emit and handle.&lt;/p&gt;

&lt;p&gt;With these basic building blocks we should be able to construct our entire game.&lt;/p&gt;

&lt;h1 id=&quot;entering-the-labyrinth-of-the-lich&quot;&gt;Entering the &lt;em&gt;Labyrinth of the Lich&lt;/em&gt;&lt;/h1&gt;

&lt;p&gt;After spending a day going through Godot tutorials, it was time to get started on the game. I had given a little thought to what I wanted to create and had landed on a vague premise involving a spaceship taken over by alien lifeforms where the player would need to navigate their way to the escape pods in order to survive. This idea hit a roadblock when I failed to find any free sets of sci-fi sprites I could use for the game art. I’m definitely not an artist and I did not want to be slowed down even further by choosing to make my own art. Since most roguelikes are set in a fantasy world, there was a lot of art I could use if I chose that setting.&lt;/p&gt;

&lt;p&gt;The new game (which I would later title “Labyrinth of the Lich”) would center around a wizard who must find his way through a series of mazes while encountering various enemies in a search for forbidden knowledge. The plan was to have a few levels of procedurally generated mazes with different types of enemies. This would culminate in a boss fight of some sort once the exit of last level ws reached. The player character would be limited in how many spells they could “know” at a time. Their starting spells would either be chosen at the beginning of the game or be randomly selected and then they could find additional spells to replace these within the game. These spells would be mix of offensive, defensive, and utility spells such as a fire AoE spell, a warding spell that splinters to damage attacking enemies, and invisibility.&lt;/p&gt;

&lt;p&gt;I knew my plans were ambitious for someone with no experience but they gave me a set of concepts to focus on. Much of what I would end up spending my time on would be the general gameplay mechanics of roguelikes rather than the specifics of my game.&lt;/p&gt;

&lt;h1 id=&quot;time-to-jam&quot;&gt;Time to Jam&lt;/h1&gt;

&lt;p&gt;The first thing I had to tackle was the creation of the map and the tiles that it is made up of. Eventually, I would want to procedurally generate these levels, but while trying to nail down the basic mechanics I just created a static set of rooms. I used &lt;a href=&quot;https://imgur.com/a/uHx4k&quot;&gt;Quale’s Scroll O’ Sprites&lt;/a&gt; for all of the game’s art. Since it is provided as a regular image file I had to use GIMP to crop out the sprites I needed in order to make a tileset. Then, within Godot I was able to create a Tilemap node that uses that tileset. A Tilemap is a node that allows you to define a set of tiles and easily “paint” them onto the screen in order to build the map. It also lets you easily define collision shapes for each of the tiles. I began by making the wall’s collision shapes match the entire space of the tile, but later would shrink this down in order to make line-of-sight more realistic.&lt;/p&gt;

&lt;p&gt;Next I created a Player node that could be instanced onto this map. I implemented traditional eight direction movement using &lt;a href=&quot;http://kidscancode.org/godot_recipes/2d/grid_movement/&quot;&gt;a tutorial from KidsCanCode&lt;/a&gt;. The technique outlined in that tutorial involves responding to directional input and then using a Raycast2D node to test whether there would be a collision in that direction. If there is not, move the character, otherwise do nothing.&lt;/p&gt;

&lt;p&gt;Once I got that working I began tackling spell targeting. In most roguelikes, ranged attacks like spells will use some sort of selector to choose your target. The selector will often auto-target nearby enemies to make it easier to use, but in my case I relied on manual movement.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/7drl-2020/7drl_spell_targeting.gif&quot; alt=&quot;eight direction movement and spell targeting&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To get this working I had to create a new Target scene as an Area2D with the “X” as a Sprite, a CollisionShape2D, and a Raycast2D. I originally had a timer that caused the flashing behavior you see above, but later ditched that as it was hard to see where the target was at times. I hid the target by default, and then when the player pressed “Z” to cast their spell it would appear. The same raycast-based movement is implemented here in order to prevent the target from going through walls. Once the player has moved to their target and pressed “Enter”, the current position is sent back to the Player node using a signal.&lt;/p&gt;

&lt;p&gt;From there I needed to make the spell casting actually do something. I decided the first spell I would implement would be a simple, single tile fire spell. This involved creating a simple scene that could be instanced when the spell is cast. In order to cause damage, I used groups. Groups are a simple way to share behaviors across sets of nodes. In this case, I added each entity that collided with the fire into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;condition:burning&lt;/code&gt; group. Then, on each turn, I was able to get each entity that was marked as burning and apply damage to them.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/7drl-2020/7drl_flames.gif&quot; alt=&quot;fire spell casting&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that I could move around and cast spells, the next challenge was going to be adding actual enemies that could see and pursue the player. For that, I found &lt;a href=&quot;http://kidscancode.org/blog/2018/03/godot3_visibility_raycasts/&quot;&gt;another KidsCanCode tutorial&lt;/a&gt; that explained visibility and targeting using an example game with automated turrets. There are two parts to this: detecting when the player is within range and determining if the enemy can see the player. The first half is implemented by giving the enemy an additional Area2D with a circular collision shape as wide as their visibility range. If the player enters that circle, the enemy will attempt to target them. To determine if the enemy can see the player, we can use raycasts again.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/7drl-2020/7drl_enemy_visibility_improved.gif&quot; alt=&quot;enemy visibility and targeting&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You’ll notice that there are actually four separate rays. This is a trick that the tutorial gives to increase the accuracy of these line of sight tests. If you used a single ray to the center of the player, the game would consider them not visible when they are standing around the edge of a corner, even though logically the enemy could see them.&lt;/p&gt;

&lt;p&gt;It was also at this point that I adopted a new raycasting technique that the tutorial mentioned. Instead of giving each entity a Raycast2D node (or multiple), it is more performant to get direct access to the 2d world state where you can perform as many casts from point A to B as you want.&lt;/p&gt;

&lt;p&gt;So at this point we had enemies that know when they see the player, but have no way to actually pursue them. For this I had to implement a custom A* pathfinding algorithm. I had heard of A* before, but had never implemented it myself so this part ended up being really fun for me. For an in-depth explanation of the algorithm you can read through the &lt;a href=&quot;https://www.redblobgames.com/pathfinding/a-star/introduction.html&quot;&gt;blog post&lt;/a&gt; that I used to implement my version. The general idea is that you expand outward from the starting tile, generating a cost for each neighboring tile, until you reach your target. It is more efficient than Breadth First Search or Dijkstra’s since it will prioritize its expansion based on some heuristic function. The simplest heuristic (and the one I used) is the Manhattan Distance from the current tile to the target. In most cases this is going to get you the most efficient path rather quickly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/7drl-2020/7drl_astar_cardinal.gif&quot; alt=&quot;enemy pathfinding&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When an enemy sees the player it will calculate the best path to reach them. If they later lose sight of the player it will remember this path and move to the end of it, either regaining visibility of the player and calculating a new path, or stopping its movement.&lt;/p&gt;

&lt;p&gt;I also added melee combat at this point. If the player or enemy try to move and collide with something that belongs to the opposite group, they will cause damage.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/7drl-2020/7drl_combat.gif&quot; alt=&quot;combat&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s almost starting to look like a game!&lt;/p&gt;

&lt;p&gt;The last major change I made was to spell targeting. It’s not exactly fair if the player’s spells have infinite range and can be cast through obstacles. In order to remedy this I implemented a similar system to how enemies handle visibility and targeting. The spell target was given a circular area as its range and kept track of whether or not the player was within that circle. It also used raycasting to check whether it had line of sight back to the player. If both of those conditions were met, the spell could be cast. Otherwise, the cursor would turn red.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/7drl-2020/7drl_spell_range.gif&quot; alt=&quot;spell range&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By the time I finished that it was about 11 pm of the last night of the jam. My very last additions were some improvements to the HUD. I added a heart sprite with a counter for the player’s health and implemented a simple combat log that displays messages such as when the player receives/causes damage, when enemies see the player, etc.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/7drl-2020/7drl_final.gif&quot; alt=&quot;final game&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you’re interested, you can play a web version of the game on my &lt;a href=&quot;https://carnivaltears.itch.io/labyrinth-of-the-lich&quot;&gt;itch.io page&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h1&gt;

&lt;p&gt;Although it’s not quite a full roguelike yet, it has the skeleton of one. I’m planning to hopefully complete the game over time since there are still more things I’d like to learn how to implement.&lt;/p&gt;

&lt;p&gt;In order to finish it I’ll need to add the following things:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Fog of war so the player can only see their immediate surroundings (and not through walls)&lt;/li&gt;
  &lt;li&gt;Procedural level generation&lt;/li&gt;
  &lt;li&gt;A mana/energy system for spell casting&lt;/li&gt;
  &lt;li&gt;Procedural enemies and items&lt;/li&gt;
  &lt;li&gt;More spells/conditions&lt;/li&gt;
  &lt;li&gt;A final boss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The one I’m most excited about is the level generation. I’m looking forward to learning some new algorithms related to maze generation.&lt;/p&gt;

&lt;p&gt;Overall, I’m satisfied with the progress I was able to make during the game jam and I’m excited to see some of the other games that were completed. I had a lot of fun and hope that this is the beginning of a satisfying hobby of making games.&lt;/p&gt;

</description>
        <pubDate>Sun, 15 Mar 2020 16:49:00 -0500</pubDate>
        <link>http://www.matthewherman.net/programming/gamedev/2020/03/15/7drl-2020.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/gamedev/2020/03/15/7drl-2020.html</guid>
        
        <category>programming</category>
        
        <category>gamedev</category>
        
        <category>7drl</category>
        
        <category>godot</category>
        
        
        <category>programming</category>
        
        <category>gamedev</category>
        
      </item>
    
      <item>
        <title>Advent of Code - Day 5 (Part 1)</title>
        <description>&lt;p&gt;The Day 5 puzzle heralds our (hopefully triumphant) return to intcode. We will be modifying our original intcode computer to handle a few new instructions as well as “parameter modes”. Up until now our computer implicitly supported a single parameter mode: position mode. This means that the value of a parameter tells you to look at that address (i.e. index) for its value. We will need to be able to support an additional parameter mode called immediate where the parameter itself is the value.&lt;/p&gt;

&lt;p&gt;These modes are encoded directly in the instruction. For example, an instruction of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CBAXX&lt;/code&gt; represents an instruction XX (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;02&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;99&lt;/code&gt;) with three parameters where A is the mode (0 for position, 1 for immediate) of the first parameter, B the mode of the second, and C the mode of the third. Any leading zeroes can also be omitted with the assumption that they are mode 0, so the instruction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;, would have the same meaning as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00002&lt;/code&gt;. We can also assume that any parameters that involve writing/setting a value are in position mode.&lt;/p&gt;

&lt;p&gt;In addition to parameter modes we will be supporting two new instructions. They are essentially a read and write that work based on an “input” value which is defined in the puzzle. The write instruction (opcode &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;03&lt;/code&gt;) takes a single parameter and writes the input value to that position and the read instruction (opcode &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;04&lt;/code&gt;) will output the value at the position of its parameter.&lt;/p&gt;

&lt;p&gt;If we’re going to support these changes we’ll need to overhaul how we read instructions. Let’s start by attempting to decode the new instruction format and separate the instruction from the parameter modes.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parse-opcode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;opcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;opcode-list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pad-list-to-n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;int-to-list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;max-mode-length&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode-length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;reverse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;subseq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode-list&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;max-mode-length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;subseq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode-list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;max-mode-length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This function is a little complicated but is easier to understand if we break it down into steps. Imagine we are parsing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1002&lt;/code&gt; instruction. We first use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int-to-list&lt;/code&gt; helper to turn it into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(1 0 0 2)&lt;/code&gt;. Since the instructions can omit leading zeroes for position mode parameters, we’ll want to add those back in so that we have a consistent format. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pad-list-to-n&lt;/code&gt; helper assists with that and turns the list into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(0 1 0 0 2)&lt;/code&gt;. Then we just divide the list up into modes and opcode and smash it back together resulting in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;((0 1 0) (0 2))&lt;/code&gt;. The first list is the parameter modes and the second is the opcode. Also note that we’ve reversed the first list so that the modes are in the order of the parameters themselves.&lt;/p&gt;

&lt;p&gt;To execute one of these instructions we’ll need to combine it with the parameters first. The goal here is to get to a point where we have an opcode along with pairs of parameters and their nodes. For example an instruction with parameters like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1002, 4, 3, 4&lt;/code&gt; could give us something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;((0 2) (0 4) (1 3) (0 4))&lt;/code&gt;. Before we can combine the parameters with modes however, we will need to parse them out of the program.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;get-parameters&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;num-parameters&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;instruction-size&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;num-parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;collect&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The function calculates the number of parameters to extract based on the instruction size. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; instruction has a size of 4 (one opcode plus three parameters). Using that value we can use the loop to collect the next N values starting at the current instruction pointer.&lt;/p&gt;

&lt;p&gt;Now that we’ve parsed both the opcode and the parameters, we can attempt to put them together.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;get-instruction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let*&lt;/span&gt; 
        &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;opcode-and-modes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;parse-opcode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;opcode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode-and-modes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;modes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode-and-modes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;opcode&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mapcar&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;modes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-parameters&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;opcode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mapcar&lt;/code&gt; in the function is a neat little trick. Mapping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;list&lt;/code&gt; over multiple lists performs a zip of those lists. So if we hade modes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(0 1 0)&lt;/code&gt; and parameters &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(4 3 4)&lt;/code&gt;, it will neatly zip them together to get &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;((0 4) (1 3) (0 4))&lt;/code&gt;. We then combine that with the opcode to get the structure we laid out above.&lt;/p&gt;

&lt;p&gt;We now have a way to retrieve the instruction at the current instruction pointer. All we have to do is update our instruction execution pipeline to handle the new format.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;execute-instruction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cond&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;addp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;execute-add&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;multp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;execute-mult&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;writep&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;execute-write&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;readp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;execute-read&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;execute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;loop&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-instruction&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;haltp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;HALT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;execute-instruction&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ip&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;instruction-size&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The big difference here is the last line of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute&lt;/code&gt;. Since not all instructions have the same number of parameters anymore we need to be able to advance the instruction pointer based on the size of the instruction executed.&lt;/p&gt;

&lt;p&gt;In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute-&amp;lt;instruction&amp;gt;&lt;/code&gt; functions we need to fetch the parameter values differently based on mode through the use of some helper methods. This is what the add instruction looks like now (along with the helpers):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;get-parameter-value-by-mode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;positionp&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;;; Sets are always performed by position so ignore mode&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;set-parameter-value-by-mode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;set-at&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;execute-add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;input1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-parameter-value-by-mode&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
         &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;input2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-parameter-value-by-mode&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;third&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;set-parameter-value-by-mode&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;program&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;fourth&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;instruction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;input1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;input2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The other instructions are implemented similarly. For the input value that the read/write instructions rely on I ended up just storing it as global state. I didn’t want to have to pass it through all of these other functions and I wasn’t sure of a better way to handle it. One idea I had was to have a top level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;computer&lt;/code&gt; function that encapsulated all of the other functions by defining them within itself. Any necessary state could then be set within that function and still used by the encapsulated function. In the end I abandoned this since the state makes it nearly impossible to run/test those functions independently.&lt;/p&gt;

&lt;p&gt;My full solution can be found on &lt;a href=&quot;https://github.com/mattherman/advent-of-code-2019&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
        <pubDate>Tue, 17 Dec 2019 20:47:00 -0600</pubDate>
        <link>http://www.matthewherman.net/programming/2019/12/17/aoc-day-5-part-1.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2019/12/17/aoc-day-5-part-1.html</guid>
        
        <category>aoc</category>
        
        <category>lisp</category>
        
        <category>programming</category>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Finalizers in C#</title>
        <description>&lt;p&gt;Similar to how programmers can use constructors to initialize an object, C# provides the concept of finalizers for cleaning them up. A finalizer declaration looks very similar to a constructor except it begins with a special &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~&lt;/code&gt; syntax and cannot take any arguments.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyClass&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// cleanup&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The purpose of finalizers is to perform additional cleanup related to the destruction of an object. Generally in C# the runtime will handle allocating and freeing memory, but if an object has any unmanaged resources (e.g. file handles, sockets, etc.) it will need to clean up after itself. The runtime is unable to do it automatically since it is not managing those native resources. Since most C# programmers do not find themselves dealing with unmanaged resources often, they usually do not need to implement a finalizer.&lt;/p&gt;

&lt;h1 id=&quot;finalizers-and-garbage-collection&quot;&gt;Finalizers and Garbage Collection&lt;/h1&gt;

&lt;p&gt;It is impossible to call an object’s finalizer directly. An object that provides a finalizer will be marked so that the garbage collector knows it requires a finalizer call. Once that object is no longer referenced the next run of the garbage collector will move it to the finalizer (f-reachable) queue. Objects without a finalizer are not added to this queue since they can be collected immediately. In addition, the object will be moved to the next “generation” of the managed heap.&lt;/p&gt;

&lt;p&gt;The .NET garbage collector organizes objects into sets known as generations. All objects are created in Generation 0 and are moved up a generation each time they survive collection and collections run less frequently on the higher generations. This allows the garbage collector to focus on the most short-lived objects and free their memory more frequently.&lt;/p&gt;

&lt;p&gt;After some time on the finalizer queue, a thread (separate from the main GC thread) will process items in the queue and call their finalizer. Each finalizer will implicitly call the finalizer of its base class so finalization occurs in an inheritance hierarchy chain from child to parent. After this point, the object will be removed from the queue and be available for removal on the next garbage collection.&lt;/p&gt;

&lt;p&gt;It’s unclear why the finalizer queue is processed on a thread separate from the garbage collector but sources online seem to imply it is for performance issues. This seems reasonable since a garbage collection requires a pause of the application.&lt;/p&gt;

&lt;h1 id=&quot;deterministic-cleanup-with-dispose&quot;&gt;Deterministic Cleanup with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt;&lt;/h1&gt;

&lt;p&gt;Since it is unknown when the finalizer will be executed the language provides another mechanism for deterministic release of resources. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt; interface provides a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt; method that can be called on an object explicitly to perform the cleanup that a finalizer would normally provide. A very common pattern for implementing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt; looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyClass&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disposed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;GC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SuppressFinalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disposing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disposed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disposing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// cleanup managed resources&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// cleanup unmanaged resources&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;disposed&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The public &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt; method will be called by any consumers attempting to clean up an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyClass&lt;/code&gt;. This will in turn call the protected helper &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose(bool)&lt;/code&gt; which will perform the actual cleanup. This method has a few guards in it. First, a flag is checked in order to prevent disposal of the same resources more than once. Second, the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;disposing&lt;/code&gt; will determine whether to clean up managed resources (e.g. other objects that implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt;) in addition to the unmanaged ones. When it is called from the publicly-exposed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt; that flag is set to true since it should clean up all resources the object owns. However, when it is called from the finalizer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;disposing&lt;/code&gt; is set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;. If the finalizer is being called, the managed resources this object has may have already been destroyed and disposing of them again may cause issues.&lt;/p&gt;

&lt;p&gt;The last part to point out is the call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GC.SuppressFinalize(this)&lt;/code&gt; at the end of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt;. Since all of the resources have been manually cleaned up, there is no reason for the finalizer to run at a later time. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SuppressFinalize&lt;/code&gt; will mark the object as not needing to execute a finalizer, allowing it to be cleaned up by the garbage collector without first waiting in the finalizer queue that was mentioned earlier.&lt;/p&gt;

&lt;h1 id=&quot;the-using-statement&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using&lt;/code&gt; Statement&lt;/h1&gt;

&lt;p&gt;Another benefit to implementing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt; interface is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using&lt;/code&gt; statement. In order to ensure disposable objects get cleaned up properly a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;try&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finally&lt;/code&gt; would need to be used.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyMethod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyDisposableClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// do something&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The language provides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using&lt;/code&gt; statement as a helpful piece of syntactic sugar to simplify this.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyMethod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyDisposableClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// do something&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Everything in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;using&lt;/code&gt; block will be wrapped in an implicit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;try&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finally&lt;/code&gt; and disposed of before exiting the statement.&lt;/p&gt;

&lt;p&gt;Most of the time programmers will not need to implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt; themselves. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt; method (and finalizer) is only necessary when the class contains resources that are not managed by the runtime or contains other managed objects that implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt;. While implementing this pattern is rare, it is important to understand when it is necessary in order to ensure that resources that are no longer needed get cleaned up properly.&lt;/p&gt;

&lt;h1 id=&quot;additional-reading&quot;&gt;Additional Reading&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors&quot;&gt;Finalizers (Destructors)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.object.finalize?view=netframework-4.8&quot;&gt;System.Object.Finalize&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose&quot;&gt;Implementing Dispose&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals&quot;&gt;Garbage Collection Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
        <pubDate>Mon, 16 Dec 2019 13:55:00 -0600</pubDate>
        <link>http://www.matthewherman.net/programming/2019/12/16/csharp-finalizer.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2019/12/16/csharp-finalizer.html</guid>
        
        <category>c#</category>
        
        <category>garbage collection</category>
        
        <category>programming</category>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Advent of Code - Day 4</title>
        <description>&lt;p&gt;If the length of the puzzle description is at all correlated with difficulty, this one should be pretty simple. The goal is to identify “passwords” that meet specific requirements. The passwords must be six numeric digits long, each digit must be greater than or equal to the previous one, and there must be at least two adjacent digits that are equal to each other. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;122345&lt;/code&gt; would be valid but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;123456&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;123324&lt;/code&gt; would not. We are also given a specific range of numbers to search as input.&lt;/p&gt;

&lt;p&gt;The first thing we will want to do is split the numbers into a collection of digits in order to perform operations on them more easily. I figure there should be a simpler way to do this, but the best I found involved converting the number to a string, looping over the characters, and converting each individual character back to an integer.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;int-to-list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;across&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;write-to-string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;collect&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;digit-char-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Maybe not the most performant, but it will have to do for now.&lt;/p&gt;

&lt;p&gt;We basically have two conditions that we need to test on all password candidates: that they increase left to right and that they contain at least one sequence of digits. Validating the increasing values can be done with a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; call.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;increasing&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To validate that the potential password includes a sequence of matching digits we’ll first write a function that can determine all the sequences present in the value. Our goal is to take a list of digits as input and output a list of sequences. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(1 2 2 3 4 4)&lt;/code&gt; would return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;((4 4) (3) (2 2) (1))&lt;/code&gt;. This can be accomplished via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reduce&lt;/code&gt; with a lambda that performs the accumulation of sequences.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;split-sequences&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;reduce&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cdr&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt;
        &lt;span class=&quot;ss&quot;&gt;:initial-value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Let’s deconstruct that lambda with a few examples. Since we’re expecting a list of lists, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(car (car acc))&lt;/code&gt; in the condition will be matching the current digit with the last one that was collected (or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nil&lt;/code&gt;). So if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;acc&lt;/code&gt; equals &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;((2) (1))&lt;/code&gt;, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(car (car acc))&lt;/code&gt; = &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now imagine the next digit is also a value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;. The condition will return true and we’ll follow the first path. Let’s see what it would look like if we resolved those forms iteratively.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;       &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cdr&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;car&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cdr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;                        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;acc&lt;/code&gt; would now be equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;((2 2) (1))&lt;/code&gt;. If the next digit is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt; we would follow the second branch of logic.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cons&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now that we have a way of splitting the list of digits into a list of sequences we just need to test whether any of the sequences have a length greater than one. We can accomplish this with the help of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any&lt;/code&gt; function.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;includes-sequence-of-n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;split-sequences&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Finally, with our two test functions AND’d together and a loop over our input range we’re able to get our answer.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;int-to-list&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;increasing&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;includes-sequence-of-n&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;find-matching-passwords&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;begin&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;begin&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;collect&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;find-matching-passwords&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;147981&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;691423&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The follow up exercise only requires us to change a single line of code. The new requirement is that the sequence of two matching digits cannot be part of a larger sequence. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;122234&lt;/code&gt; would be invalid but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;122333&lt;/code&gt; would be fine.&lt;/p&gt;

&lt;p&gt;In order to test this we update our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;includes-sequence-of-n&lt;/code&gt; function to require a sequence of exactly two digits.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;includes-sequence-of-n&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;split-sequences&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;My full solution can be found on &lt;a href=&quot;https://github.com/mattherman/advent-of-code-2019&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
        <pubDate>Wed, 11 Dec 2019 19:51:00 -0600</pubDate>
        <link>http://www.matthewherman.net/programming/2019/12/11/aoc-day-4.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2019/12/11/aoc-day-4.html</guid>
        
        <category>aoc</category>
        
        <category>lisp</category>
        
        <category>programming</category>
        
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Advent of Code - Day 3 (Part 2)</title>
        <description>&lt;p&gt;I finished the second exercise and I definitely didn’t make my solution any faster like I said I might. I may return to it eventually but for now I’m still playing catch up on the challenges.&lt;/p&gt;

&lt;p&gt;In the second part of this day’s puzzle they are switching up the distance calculation. Instead of looking for the intersection with the shortest Manhattan distance, we will now need to find the shortest “signal” distance. Basically, the intersection at which each wire’s path is the shortest.&lt;/p&gt;

&lt;p&gt;We can measure this distance using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;position&lt;/code&gt; function which returns the (first) index of a specific value in a list. We’ll also re-use our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector-equal&lt;/code&gt; function again for the comparisons:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;signal-distance&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;coords&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;position&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coords&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:test&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;vector-equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;combined-signal-distance&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;coords1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coords2&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;signal-distance&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coords1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;signal-distance&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coords2&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;coordinate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then it is just a small change to swap out the Manhattan distance mapping for our own:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;progn&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;path-data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;load-path-data&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;input.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;first-path-vectors&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;convert-strings-to-vectors&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;path-data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;second-path-vectors&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;convert-strings-to-vectors&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;path-data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;first-path-coordinates&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-coordinates-visited&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;first-path-vectors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;setf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;second-path-coordinates&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;get-coordinates-visited&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;second-path-vectors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mapcar&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;combined-signal-distance&lt;/span&gt; 
                        &lt;span class=&quot;nv&quot;&gt;first-path-coordinates&lt;/span&gt;
                        &lt;span class=&quot;nv&quot;&gt;second-path-coordinates&lt;/span&gt;
                        &lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;remove-if&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;vector-equal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;intersection&lt;/span&gt; 
                        &lt;span class=&quot;nv&quot;&gt;first-path-coordinates&lt;/span&gt;
                        &lt;span class=&quot;nv&quot;&gt;second-path-coordinates&lt;/span&gt;
                        &lt;span class=&quot;ss&quot;&gt;:test&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#&apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;vector-equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;My full solution can be found on &lt;a href=&quot;https://github.com/mattherman/advent-of-code-2019&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
        <pubDate>Sun, 08 Dec 2019 20:26:00 -0600</pubDate>
        <link>http://www.matthewherman.net/programming/2019/12/08/day-3-part-2.html</link>
        <guid isPermaLink="true">http://www.matthewherman.net/programming/2019/12/08/day-3-part-2.html</guid>
        
        <category>aoc</category>
        
        <category>lisp</category>
        
        <category>programming</category>
        
        
        <category>programming</category>
        
      </item>
    
  </channel>
</rss>
