advent of code solutions aoc.oppi.li
haskell aoc

2025/09: better type annotations

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

oppi.li ff935fe5 c8f19f2e

verified
+15 -11
+8 -6
out/2.5-day-9.html
··· 108 108 <div class="sourceCode" id="cb1"><pre 109 109 class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List.Split</span> (splitOn)</span> 110 110 <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span> 111 - <span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">parse ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> [[<span class="dt">Integer</span>]]</span> 112 - <span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>parse <span class="ot">=</span> <span class="fu">map</span> (<span class="fu">map</span> <span class="fu">read</span> <span class="op">.</span> splitOn <span class="st">&quot;,&quot;</span>) <span class="op">.</span> <span class="fu">lines</span></span></code></pre></div> 111 + <span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Point</span> <span class="ot">=</span> [<span class="dt">Integer</span>]</span> 112 + <span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span> 113 + <span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ot">parse ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> [<span class="dt">Point</span>]</span> 114 + <span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>parse <span class="ot">=</span> <span class="fu">map</span> (<span class="fu">map</span> <span class="fu">read</span> <span class="op">.</span> splitOn <span class="st">&quot;,&quot;</span>) <span class="op">.</span> <span class="fu">lines</span></span></code></pre></div> 113 115 </div> 114 116 </div> 115 117 <div class="row"> ··· 126 128 of a point is <code>[x, y]</code>:</p> 127 129 <div class="code"> 128 130 <div class="sourceCode" id="cb2"><pre 129 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">area ::</span> [<span class="dt">Integer</span>] <span class="ot">-&gt;</span> [<span class="dt">Integer</span>] <span class="ot">-&gt;</span> <span class="dt">Integer</span></span> 131 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">area ::</span> <span class="dt">Point</span> <span class="ot">-&gt;</span> <span class="dt">Point</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span> 130 132 <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>area [x, y] [x&#39;, y&#39;] <span class="ot">=</span> </span> 131 133 <span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> (<span class="dv">1</span> <span class="op">+</span> <span class="fu">abs</span> (x <span class="op">-</span> x&#39;)) <span class="op">*</span> (<span class="dv">1</span> <span class="op">+</span> <span class="fu">abs</span> (y <span class="op">-</span> y&#39;))</span></code></pre></div> 132 134 </div> ··· 136 138 list comprehension:</p> 137 139 <div class="code"> 138 140 <div class="sourceCode" id="cb3"><pre 139 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">p1 ::</span> [[<span class="dt">Integer</span>]] <span class="ot">-&gt;</span> <span class="dt">Integer</span></span> 141 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">p1 ::</span> [<span class="dt">Point</span>] <span class="ot">-&gt;</span> <span class="dt">Integer</span></span> 140 142 <span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>p1 poly <span class="ot">=</span> <span class="fu">maximum</span> [area p p&#39; <span class="op">|</span> p <span class="ot">&lt;-</span> poly, p&#39; <span class="ot">&lt;-</span> poly]</span></code></pre></div> 141 143 </div> 142 144 </div> ··· 162 164 rectangle:</p> 163 165 <div class="code"> 164 166 <div class="sourceCode" id="cb4"><pre 165 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">intersects ::</span> [<span class="dt">Integer</span>] <span class="ot">-&gt;</span> [<span class="dt">Integer</span>] <span class="ot">-&gt;</span> [[<span class="dt">Integer</span>]] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span> 167 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">intersects ::</span> <span class="dt">Point</span> <span class="ot">-&gt;</span> <span class="dt">Point</span> <span class="ot">-&gt;</span> [<span class="dt">Point</span>] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span> 166 168 <span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>intersects [x, y] [x&#39;, y&#39;] <span class="ot">=</span> <span class="fu">not</span> <span class="op">.</span> <span class="fu">all</span> away <span class="op">.</span> pairs</span> 167 169 <span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">where</span></span> 168 170 <span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> pairs (p <span class="op">:</span> ps) <span class="ot">=</span> <span class="fu">zip</span> (p <span class="op">:</span> ps) (ps <span class="op">++</span> [p])</span> ··· 189 191 comprehension with an additional guard:</p> 190 192 <div class="code"> 191 193 <div class="sourceCode" id="cb5"><pre 192 - class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">p2 ::</span> [[<span class="dt">Integer</span>]] <span class="ot">-&gt;</span> <span class="dt">Integer</span></span> 194 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">p2 ::</span> [<span class="dt">Point</span>] <span class="ot">-&gt;</span> <span class="dt">Integer</span></span> 193 195 <span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>p2 poly <span class="ot">=</span></span> 194 196 <span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="fu">maximum</span></span> 195 197 <span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> [ area p p&#39;</span>
+7 -5
src/2025/09.lhs
··· 7 7 ```haskell 8 8 import Data.List.Split (splitOn) 9 9 10 - parse :: String -> [[Integer]] 10 + type Point = [Integer] 11 + 12 + parse :: String -> [Point] 11 13 parse = map (map read . splitOn ",") . lines 12 14 ``` 13 15 ··· 18 20 This part requires us to simply find a rectangle with the largest area among the points given to us, so first write a method to compute areas given a point. Remember that our representation of a point is `[x, y]`: 19 21 20 22 ```haskell 21 - area :: [Integer] -> [Integer] -> Integer 23 + area :: Point -> Point -> Integer 22 24 area [x, y] [x', y'] = 23 25 (1 + abs (x - x')) * (1 + abs (y - y')) 24 26 ``` ··· 26 28 Thus, the solution to the first part is given by the following list comprehension: 27 29 28 30 ```haskell 29 - p1 :: [[Integer]] -> Integer 31 + p1 :: [Point] -> Integer 30 32 p1 poly = maximum [area p p' | p <- poly, p' <- poly] 31 33 ``` 32 34 ··· 37 39 Luckily, the intersections are quite easily calculated, since all lines of the polygon are oriented along the axes, and so are the lines forming the rectangle. If a line of the polygon falls to the left of the leftmost line of the rectangle, or to the right of the rightmost line, or above the topmost line, or below the bottommost line, then the line does not intersect the rectangle: 38 40 39 41 ```haskell 40 - intersects :: [Integer] -> [Integer] -> [[Integer]] -> Bool 42 + intersects :: Point -> Point -> [Point] -> Bool 41 43 intersects [x, y] [x', y'] = not . all away . pairs 42 44 where 43 45 pairs (p : ps) = zip (p : ps) (ps ++ [p]) ··· 53 55 Thus, the solution to the second part is a similar list comprehension with an additional guard: 54 56 55 57 ```haskell 56 - p2 :: [[Integer]] -> Integer 58 + p2 :: [Point] -> Integer 57 59 p2 poly = 58 60 maximum 59 61 [ area p p'