advent of code solutions aoc.oppi.li
haskell aoc

2025/06: add type annotations

Signed-off-by: oppiliappan <me@oppi.li>

oppi.li f25f0039 c65bb314

verified
+19 -13
+14 -11
out/2.4-day-6.html
··· 112 112 the start of the list.</p> 113 113 <div class="code"> 114 114 <div class="sourceCode" id="cb1"><pre 115 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>solve (<span class="st">&quot;+&quot;</span> <span class="op">:</span> rest) <span class="ot">=</span> <span class="fu">sum</span> <span class="op">.</span> <span class="fu">map</span> <span class="fu">read</span> <span class="op">$</span> rest</span> 116 - <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>solve (<span class="st">&quot;*&quot;</span> <span class="op">:</span> rest) <span class="ot">=</span> <span class="fu">product</span> <span class="op">.</span> <span class="fu">map</span> <span class="fu">read</span> <span class="op">$</span> rest</span></code></pre></div> 115 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">solve ::</span> [<span class="dt">String</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span> 116 + <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>solve (<span class="st">&quot;+&quot;</span> <span class="op">:</span> rest) <span class="ot">=</span> <span class="fu">sum</span> <span class="op">.</span> <span class="fu">map</span> <span class="fu">read</span> <span class="op">$</span> rest</span> 117 + <span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>solve (<span class="st">&quot;*&quot;</span> <span class="op">:</span> rest) <span class="ot">=</span> <span class="fu">product</span> <span class="op">.</span> <span class="fu">map</span> <span class="fu">read</span> <span class="op">$</span> rest</span></code></pre></div> 117 118 </div> 118 119 </div> 119 120 <div class="row"> ··· 122 123 rotates a list forwards to move the last element to the first.</p> 123 124 <div class="code"> 124 125 <div class="sourceCode" id="cb2"><pre 125 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>rot <span class="ot">=</span> liftA2 (<span class="op">:</span>) <span class="fu">last</span> <span class="fu">init</span></span></code></pre></div> 126 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">rot ::</span> [a] <span class="ot">-&gt;</span> [a]</span> 127 + <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>rot <span class="ot">=</span> liftA2 (<span class="op">:</span>) <span class="fu">last</span> <span class="fu">init</span></span></code></pre></div> 126 128 </div> 127 129 </div> 128 130 <div class="row"> ··· 140 142 <div class="sourceCode" id="cb4"><pre 141 143 class="sourceCode haskell haskell-top"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (transpose)</span></code></pre></div> 142 144 <div class="sourceCode" id="cb5"><pre 143 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a></span> 145 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">p1 ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span> 144 146 <span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>p1 <span class="ot">=</span> <span class="fu">sum</span> <span class="op">.</span> <span class="fu">map</span> solve <span class="op">.</span> align <span class="op">.</span> rot <span class="op">.</span> <span class="fu">lines</span></span> 145 147 <span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">where</span></span> 146 148 <span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> align <span class="ot">=</span> transpose <span class="op">.</span> <span class="fu">map</span> <span class="fu">words</span></span></code></pre></div> ··· 203 205 <div class="sourceCode" id="cb10"><pre 204 206 class="sourceCode haskell haskell-top"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List.Split</span> (splitWhen)</span></code></pre></div> 205 207 <div class="sourceCode" id="cb11"><pre 206 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>p2 <span class="ot">=</span> <span class="fu">sum</span> <span class="op">.</span> <span class="fu">map</span> solve <span class="op">.</span> align <span class="op">.</span> rot <span class="op">.</span> <span class="fu">lines</span></span> 207 - <span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">where</span></span> 208 - <span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a> align <span class="ot">=</span></span> 209 - <span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a> <span class="fu">zipWith</span> (<span class="op">:</span>)</span> 210 - <span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a> <span class="op">&lt;$&gt;</span> (<span class="fu">words</span> <span class="op">.</span> <span class="fu">head</span>)</span> 211 - <span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a> <span class="op">&lt;*&gt;</span> (splitWhen (<span class="fu">all</span> (<span class="ch">&#39; &#39;</span> <span class="op">==</span>)) <span class="op">.</span> transpose <span class="op">.</span> <span class="fu">tail</span>)</span></code></pre></div> 208 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">p2 ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span> 209 + <span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>p2 <span class="ot">=</span> <span class="fu">sum</span> <span class="op">.</span> <span class="fu">map</span> solve <span class="op">.</span> align <span class="op">.</span> rot <span class="op">.</span> <span class="fu">lines</span></span> 210 + <span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">where</span></span> 211 + <span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a> align <span class="ot">=</span></span> 212 + <span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">zipWith</span> (<span class="op">:</span>)</span> 213 + <span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a> <span class="op">&lt;$&gt;</span> (<span class="fu">words</span> <span class="op">.</span> <span class="fu">head</span>)</span> 214 + <span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a> <span class="op">&lt;*&gt;</span> (splitWhen (<span class="fu">all</span> (<span class="ch">&#39; &#39;</span> <span class="op">==</span>)) <span class="op">.</span> transpose <span class="op">.</span> <span class="fu">tail</span>)</span></code></pre></div> 212 215 </div> 213 216 </div> 214 217 <div class="row"> ··· 248 251 249 252 </div> 250 253 </div> 251 - <pre><code>splitWhen (all isSpace) . transpose . tail</code></pre> 254 + <pre><code>splitWhen (all (&#39; &#39; ==)) . transpose . tail</code></pre> 252 255 <div class="row"> 253 256 <p>…is used to transpose numbers! Note what happens when we 254 257 transpose the lines containing numbers, we get:</p>
+5 -2
src/2025/06.lhs
··· 7 7 This part needs us to consider each operation on a column. `Data.List.transpose` fortunately makes this very simple. If we are able to massage our input into the form `["+", "1", "2", "3"]`, we can use this simple `solve` function to produce the result. The only motivation to use this format is the ease of pattern-matching over the start of the list. 8 8 9 9 ```haskell 10 + solve :: [String] -> Int 10 11 solve ("+" : rest) = sum . map read $ rest 11 12 solve ("*" : rest) = product . map read $ rest 12 13 ``` ··· 14 15 Thus, to solve the first part, we can break up our input using `lines`. `rot` is a simple function that rotates a list forwards to move the last element to the first. 15 16 16 17 ```haskell 18 + rot :: [a] -> [a] 17 19 rot = liftA2 (:) last init 18 20 ``` 19 21 ··· 28 30 ``` 29 31 30 32 ```haskell 31 - 33 + p1 :: String -> Int 32 34 p1 = sum . map solve . align . rot . lines 33 35 where 34 36 align = transpose . map words ··· 69 71 ``` 70 72 71 73 ```haskell 74 + p2 :: String -> Int 72 75 p2 = sum . map solve . align . rot . lines 73 76 where 74 77 align = ··· 91 94 92 95 The second part ... 93 96 94 - splitWhen (all isSpace) . transpose . tail 97 + splitWhen (all (' ' ==)) . transpose . tail 95 98 96 99 ...is used to transpose numbers! Note what happens when we transpose the lines containing numbers, we get: 97 100