advent of code solutions aoc.oppi.li
haskell aoc

2025: add d1

lost this solution because i solved this part at an airport on my phone
on the haskell playground!

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

oppi.li 13610586 ff935fe5

verified
+289 -68
+32 -37
out/1.2-day-2.html
··· 101 101 class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE LambdaCase #-}</span></span> 102 102 <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span> 103 103 <span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map</span> <span class="kw">as</span> <span class="dt">M</span></span> 104 - <span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">System.Environment</span> (getArgs)</span> 105 - <span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span> 106 - <span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>grid <span class="ot">=</span> M.fromList <span class="op">$</span> <span class="fu">zip</span> [(x, y) <span class="op">|</span> y <span class="ot">&lt;-</span> [<span class="dv">1</span>, <span class="dv">0</span>, <span class="op">-</span><span class="dv">1</span>], x <span class="ot">&lt;-</span> [<span class="op">-</span><span class="dv">1</span>, <span class="dv">0</span>, <span class="dv">1</span>]] [<span class="dv">1</span> <span class="op">..</span> <span class="dv">9</span>]</span> 107 - <span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span> 108 - <span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>grid2 <span class="ot">=</span></span> 109 - <span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a> M.fromList <span class="op">$</span></span> 110 - <span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a> <span class="fu">concat</span></span> 111 - <span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a> [ [((<span class="dv">0</span>, <span class="dv">2</span>), <span class="ch">&#39;1&#39;</span>)],</span> 112 - <span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a> [((<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>), <span class="ch">&#39;2&#39;</span>), ((<span class="dv">0</span>, <span class="dv">1</span>), <span class="ch">&#39;3&#39;</span>), ((<span class="dv">1</span>, <span class="dv">1</span>), <span class="ch">&#39;4&#39;</span>)],</span> 113 - <span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a> [((<span class="op">-</span><span class="dv">2</span>, <span class="dv">0</span>), <span class="ch">&#39;5&#39;</span>), ((<span class="op">-</span><span class="dv">1</span>, <span class="dv">0</span>), <span class="ch">&#39;6&#39;</span>), ((<span class="dv">0</span>, <span class="dv">0</span>), <span class="ch">&#39;7&#39;</span>), ((<span class="dv">1</span>, <span class="dv">0</span>), <span class="ch">&#39;8&#39;</span>), ((<span class="dv">2</span>, <span class="dv">0</span>), <span class="ch">&#39;9&#39;</span>)],</span> 114 - <span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a> [((<span class="op">-</span><span class="dv">1</span>, <span class="op">-</span><span class="dv">1</span>), <span class="ch">&#39;A&#39;</span>), ((<span class="dv">0</span>, <span class="op">-</span><span class="dv">1</span>), <span class="ch">&#39;B&#39;</span>), ((<span class="dv">1</span>, <span class="op">-</span><span class="dv">1</span>), <span class="ch">&#39;C&#39;</span>)],</span> 115 - <span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a> [((<span class="dv">0</span>, <span class="op">-</span><span class="dv">2</span>), <span class="ch">&#39;D&#39;</span>)]</span> 116 - <span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a> ]</span> 117 - <span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span> 118 - <span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>move <span class="ot">=</span> \<span class="kw">case</span></span> 119 - <span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;L&#39;</span> <span class="ot">-&gt;</span> (<span class="op">-</span><span class="dv">1</span>, <span class="dv">0</span>)</span> 120 - <span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;R&#39;</span> <span class="ot">-&gt;</span> (<span class="dv">1</span>, <span class="dv">0</span>)</span> 121 - <span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;U&#39;</span> <span class="ot">-&gt;</span> (<span class="dv">0</span>, <span class="dv">1</span>)</span> 122 - <span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;D&#39;</span> <span class="ot">-&gt;</span> (<span class="dv">0</span>, <span class="op">-</span><span class="dv">1</span>)</span> 123 - <span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a></span> 124 - <span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>mmove g pos d <span class="ot">=</span> <span class="kw">if</span> M.member npos g <span class="kw">then</span> npos <span class="kw">else</span> pos</span> 125 - <span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a> <span class="kw">where</span></span> 126 - <span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a> delta <span class="ot">=</span> move d</span> 127 - <span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a> npos <span class="ot">=</span> (<span class="fu">fst</span> pos <span class="op">+</span> <span class="fu">fst</span> delta, <span class="fu">snd</span> pos <span class="op">+</span> <span class="fu">snd</span> delta)</span> 128 - <span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a></span> 129 - <span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>p1 ns <span class="ot">=</span> <span class="fu">tail</span> <span class="op">$</span> <span class="fu">map</span> (grid <span class="op">M.!</span>) <span class="op">$</span> <span class="fu">scanl</span> (foldl&#39; (mmove grid)) (<span class="dv">0</span>, <span class="dv">0</span>) ns</span> 130 - <span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a></span> 131 - <span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a>p2 ns <span class="ot">=</span> <span class="fu">tail</span> <span class="op">$</span> <span class="fu">map</span> (grid2 <span class="op">M.!</span>) <span class="op">$</span> <span class="fu">scanl</span> (foldl&#39; (mmove grid2)) (<span class="op">-</span><span class="dv">2</span>, <span class="dv">0</span>) ns</span> 132 - <span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a></span> 133 - <span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span> 134 - <span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a> args <span class="ot">&lt;-</span> getArgs</span> 135 - <span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a> n <span class="ot">&lt;-</span> <span class="kw">case</span> args <span class="kw">of</span></span> 136 - <span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a> [<span class="st">&quot;-&quot;</span>] <span class="ot">-&gt;</span> <span class="fu">getContents</span></span> 137 - <span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a> [file] <span class="ot">-&gt;</span> <span class="fu">readFile</span> file</span> 138 - <span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a> <span class="kw">let</span> f <span class="ot">=</span> <span class="fu">lines</span> n</span> 139 - <span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span> <span class="op">$</span> p1 f</span> 140 - <span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span> <span class="op">$</span> p2 f</span></code></pre></div> 104 + <span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span> 105 + <span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>grid <span class="ot">=</span> M.fromList <span class="op">$</span> <span class="fu">zip</span> [(x, y) <span class="op">|</span> y <span class="ot">&lt;-</span> [<span class="dv">1</span>, <span class="dv">0</span>, <span class="op">-</span><span class="dv">1</span>], x <span class="ot">&lt;-</span> [<span class="op">-</span><span class="dv">1</span>, <span class="dv">0</span>, <span class="dv">1</span>]] [<span class="dv">1</span> <span class="op">..</span> <span class="dv">9</span>]</span> 106 + <span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span> 107 + <span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>grid2 <span class="ot">=</span></span> 108 + <span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a> M.fromList <span class="op">$</span></span> 109 + <span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">concat</span></span> 110 + <span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a> [ [((<span class="dv">0</span>, <span class="dv">2</span>), <span class="ch">&#39;1&#39;</span>)],</span> 111 + <span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a> [((<span class="op">-</span><span class="dv">1</span>, <span class="dv">1</span>), <span class="ch">&#39;2&#39;</span>), ((<span class="dv">0</span>, <span class="dv">1</span>), <span class="ch">&#39;3&#39;</span>), ((<span class="dv">1</span>, <span class="dv">1</span>), <span class="ch">&#39;4&#39;</span>)],</span> 112 + <span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a> [((<span class="op">-</span><span class="dv">2</span>, <span class="dv">0</span>), <span class="ch">&#39;5&#39;</span>), ((<span class="op">-</span><span class="dv">1</span>, <span class="dv">0</span>), <span class="ch">&#39;6&#39;</span>), ((<span class="dv">0</span>, <span class="dv">0</span>), <span class="ch">&#39;7&#39;</span>), ((<span class="dv">1</span>, <span class="dv">0</span>), <span class="ch">&#39;8&#39;</span>), ((<span class="dv">2</span>, <span class="dv">0</span>), <span class="ch">&#39;9&#39;</span>)],</span> 113 + <span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a> [((<span class="op">-</span><span class="dv">1</span>, <span class="op">-</span><span class="dv">1</span>), <span class="ch">&#39;A&#39;</span>), ((<span class="dv">0</span>, <span class="op">-</span><span class="dv">1</span>), <span class="ch">&#39;B&#39;</span>), ((<span class="dv">1</span>, <span class="op">-</span><span class="dv">1</span>), <span class="ch">&#39;C&#39;</span>)],</span> 114 + <span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a> [((<span class="dv">0</span>, <span class="op">-</span><span class="dv">2</span>), <span class="ch">&#39;D&#39;</span>)]</span> 115 + <span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a> ]</span> 116 + <span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a></span> 117 + <span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>move <span class="ot">=</span> \<span class="kw">case</span></span> 118 + <span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;L&#39;</span> <span class="ot">-&gt;</span> (<span class="op">-</span><span class="dv">1</span>, <span class="dv">0</span>)</span> 119 + <span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;R&#39;</span> <span class="ot">-&gt;</span> (<span class="dv">1</span>, <span class="dv">0</span>)</span> 120 + <span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;U&#39;</span> <span class="ot">-&gt;</span> (<span class="dv">0</span>, <span class="dv">1</span>)</span> 121 + <span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a> <span class="ch">&#39;D&#39;</span> <span class="ot">-&gt;</span> (<span class="dv">0</span>, <span class="op">-</span><span class="dv">1</span>)</span> 122 + <span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a></span> 123 + <span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>mmove g pos d <span class="ot">=</span> <span class="kw">if</span> M.member npos g <span class="kw">then</span> npos <span class="kw">else</span> pos</span> 124 + <span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a> <span class="kw">where</span></span> 125 + <span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a> delta <span class="ot">=</span> move d</span> 126 + <span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a> npos <span class="ot">=</span> (<span class="fu">fst</span> pos <span class="op">+</span> <span class="fu">fst</span> delta, <span class="fu">snd</span> pos <span class="op">+</span> <span class="fu">snd</span> delta)</span> 127 + <span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a></span> 128 + <span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>p1 ns <span class="ot">=</span> <span class="fu">tail</span> <span class="op">$</span> <span class="fu">map</span> (grid <span class="op">M.!</span>) <span class="op">$</span> <span class="fu">scanl</span> (foldl&#39; (mmove grid)) (<span class="dv">0</span>, <span class="dv">0</span>) ns</span> 129 + <span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a></span> 130 + <span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>p2 ns <span class="ot">=</span> <span class="fu">tail</span> <span class="op">$</span> <span class="fu">map</span> (grid2 <span class="op">M.!</span>) <span class="op">$</span> <span class="fu">scanl</span> (foldl&#39; (mmove grid2)) (<span class="op">-</span><span class="dv">2</span>, <span class="dv">0</span>) ns</span> 131 + <span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a></span> 132 + <span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span> 133 + <span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a> n <span class="ot">&lt;-</span> <span class="fu">lines</span> <span class="op">&lt;$&gt;</span> <span class="fu">getContents</span></span> 134 + <span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span> <span class="op">$</span> p1 n</span> 135 + <span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span> <span class="op">$</span> p2 n</span></code></pre></div> 141 136 <div class="row"> 142 137 <p>import qualified Data.List as L import Data.List.Split 143 138 (chunksOf, splitOn) import qualified Data.Text as T import
+1 -1
out/2-section-1.html
··· 43 43 <span class="navlink-label">Previous:</span> <a href="1.2-day-2.html" accesskey="p" rel="previous">Day 2</a> 44 44 </span> 45 45 <span class="navlink"> 46 - <span class="navlink-label">Next:</span> <a href="2.1-day-2-1.html" accesskey="n" rel="next">Day 2</a> 46 + <span class="navlink-label">Next:</span> <a href="2.1-day-1-1.html" accesskey="n" rel="next">Day 1</a> 47 47 </span> 48 48 </div> 49 49 </nav>
+170
out/2.1-day-1-1.html
··· 1 + <!DOCTYPE html> 2 + <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> 3 + <head> 4 + <meta charset="utf-8" /> 5 + <meta name="generator" content="pandoc" /> 6 + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> 7 + <meta name="author" content="@oppi.li" /> 8 + <title>Day 1</title> 9 + <style> 10 + code{white-space: pre-wrap;} 11 + span.smallcaps{font-variant: small-caps;} 12 + div.columns{display: flex; gap: min(4vw, 1.5em);} 13 + div.column{flex: auto; overflow-x: auto;} 14 + div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} 15 + /* The extra [class] is a hack that increases specificity enough to 16 + override a similar rule in reveal.js */ 17 + ul.task-list[class]{list-style: none;} 18 + ul.task-list li input[type="checkbox"] { 19 + font-size: inherit; 20 + width: 0.8em; 21 + margin: 0 0.8em 0.2em -1.6em; 22 + vertical-align: middle; 23 + } 24 + .display.math{display: block; text-align: center; margin: 0.5rem auto;} 25 + /* CSS for syntax highlighting */ 26 + html { -webkit-text-size-adjust: 100%; } 27 + pre > code.sourceCode { white-space: pre; position: relative; } 28 + pre > code.sourceCode > span { display: inline-block; line-height: 1.25; } 29 + pre > code.sourceCode > span:empty { height: 1.2em; } 30 + .sourceCode { overflow: visible; } 31 + code.sourceCode > span { color: inherit; text-decoration: inherit; } 32 + div.sourceCode { margin: 1em 0; } 33 + pre.sourceCode { margin: 0; } 34 + @media screen { 35 + div.sourceCode { overflow: auto; } 36 + } 37 + @media print { 38 + pre > code.sourceCode { white-space: pre-wrap; } 39 + pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; } 40 + } 41 + pre.numberSource code 42 + { counter-reset: source-line 0; } 43 + pre.numberSource code > span 44 + { position: relative; left: -4em; counter-increment: source-line; } 45 + pre.numberSource code > span > a:first-child::before 46 + { content: counter(source-line); 47 + position: relative; left: -1em; text-align: right; vertical-align: baseline; 48 + border: none; display: inline-block; 49 + -webkit-touch-callout: none; -webkit-user-select: none; 50 + -khtml-user-select: none; -moz-user-select: none; 51 + -ms-user-select: none; user-select: none; 52 + padding: 0 4px; width: 4em; 53 + } 54 + pre.numberSource { margin-left: 3em; padding-left: 4px; } 55 + div.sourceCode 56 + { } 57 + @media screen { 58 + pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } 59 + } 60 + code span.al { font-weight: bold; } /* Alert */ 61 + code span.an { font-style: italic; } /* Annotation */ 62 + code span.cf { font-weight: bold; } /* ControlFlow */ 63 + code span.co { font-style: italic; } /* Comment */ 64 + code span.cv { font-style: italic; } /* CommentVar */ 65 + code span.do { font-style: italic; } /* Documentation */ 66 + code span.dt { color: #8f4e8b; } /* DataType */ 67 + code span.er { font-weight: bold; } /* Error */ 68 + code span.in { font-style: italic; } /* Information */ 69 + code span.kw { font-weight: bold; } /* Keyword */ 70 + code span.pp { font-weight: bold; } /* Preprocessor */ 71 + code span.wa { font-style: italic; } /* Warning */ 72 + </style> 73 + <link rel="stylesheet" href="style.css" /> 74 + <link rel="preconnect" href="https://fonts.googleapis.com"> 75 + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 76 + <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&family=Libre+Baskerville:ital,wght@0,400..700;1,400..700&display=swap" rel="stylesheet"> 77 + </head> 78 + <body> 79 + <nav id="sitenav"> 80 + <div class="sitenav"> 81 + <span class="navlink"> 82 + <span class="navlink-label">Up:</span> <a href="2-section-1.html" accesskey="u" rel="up">2025</a> 83 + </span> 84 + <span class="navlink"> 85 + <span class="navlink-label">Top:</span> <a href="index.html" accesskey="t" rel="top">The Book of Solves</a> 86 + </span> 87 + </div> 88 + <div class="sitenav"> 89 + <span class="navlink"> 90 + <span class="navlink-label">Previous:</span> <a href="2-section-1.html" accesskey="p" rel="previous">2025</a> 91 + </span> 92 + <span class="navlink"> 93 + <span class="navlink-label">Next:</span> <a href="2.2-day-2-1.html" accesskey="n" rel="next">Day 2</a> 94 + </span> 95 + </div> 96 + </nav> 97 + 98 + <h2 data-number="2.1" id="day-1-1">Day 1</h2> 99 + <div class="row"> 100 + <p>Parse the input:</p> 101 + <div class="code"> 102 + <div class="sourceCode" id="cb1"><pre 103 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">parse ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>]</span> 104 + <span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>parse <span class="ot">=</span> <span class="fu">map</span> f <span class="op">.</span> <span class="fu">lines</span></span> 105 + <span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> <span class="kw">where</span> f (<span class="ch">&#39;L&#39;</span><span class="op">:</span>r) <span class="ot">=</span> <span class="fu">negate</span> (<span class="fu">read</span> r)</span> 106 + <span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> f (<span class="ch">&#39;R&#39;</span><span class="op">:</span>r) <span class="ot">=</span> <span class="fu">read</span> r</span></code></pre></div> 107 + </div> 108 + </div> 109 + <h3 data-number="2.1.1" id="part-1-2">Part 1</h3> 110 + <div class="row"> 111 + <p>Rotate the dial starting at 50, and count the number of times 112 + we stop at zero on the way. Of note is that the dial cycles back 113 + to zero after 100, so our check mustn’t just be <code>== 0</code> 114 + but rather, <code>mod n 100 == 0</code>:</p> 115 + <div class="code"> 116 + <div class="sourceCode" id="cb2"><pre 117 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">count ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Int</span></span> 118 + <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>count <span class="fu">pred</span> <span class="ot">=</span> <span class="fu">length</span> <span class="op">.</span> <span class="fu">filter</span> <span class="fu">pred</span></span> 119 + <span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span> 120 + <span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="ot">clicks ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span> 121 + <span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>clicks <span class="ot">=</span> count ((<span class="op">==</span> <span class="dv">0</span>) <span class="op">.</span> (<span class="ot">`mod`</span> <span class="dv">100</span>)) <span class="op">.</span> <span class="fu">scanl</span> (<span class="op">+</span>) <span class="dv">50</span></span></code></pre></div> 122 + </div> 123 + </div> 124 + <div class="row"> 125 + <p>Thus, the solution to the first part is given by:</p> 126 + <div class="code"> 127 + <div class="sourceCode" id="cb3"><pre 128 + 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">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span> 129 + <span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>p1 <span class="ot">=</span> clicks</span></code></pre></div> 130 + </div> 131 + </div> 132 + <h3 data-number="2.1.2" id="part-2-1">Part 2</h3> 133 + <div class="row"> 134 + <p>This part is ever so slightly different, instead of the number 135 + of times we <em>stop</em> are zero, we are required to 136 + additionally calculate the number of times we <em>pass</em> 137 + through zero.</p> 138 + <div class="code"> 139 + 140 + </div> 141 + </div> 142 + <div class="row"> 143 + <p>To think of this a bit differently, the first part has lower 144 + degree of precision: we only perform the check after the dial is 145 + fully rotated. The second part requires us to perform the check 146 + with higher degree of precision: after each movement by 1. Thus, 147 + if we modify our list to change one rotation of size N into N 148 + rotations of size 1, we will be able to reuse our 149 + <code>clicks</code> method:</p> 150 + <div class="code"> 151 + <div class="sourceCode" id="cb4"><pre 152 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">transform ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>]</span> 153 + <span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>transform n <span class="ot">=</span> <span class="fu">replicate</span> (<span class="fu">abs</span> n) (<span class="fu">signum</span> n)</span> 154 + <span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span> 155 + <span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="ot">p2 ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span> 156 + <span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>p2 <span class="ot">=</span> clicks <span class="op">.</span> <span class="fu">concatMap</span> transform</span></code></pre></div> 157 + </div> 158 + </div> 159 + <div class="row"> 160 + <p>Finally, a main function to wrap it all up:</p> 161 + <div class="code"> 162 + <div class="sourceCode" id="cb5"><pre 163 + class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span> 164 + <span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> n <span class="ot">&lt;-</span> parse <span class="op">&lt;$&gt;</span> <span class="fu">getContents</span></span> 165 + <span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span> <span class="op">$</span> p1 n</span> 166 + <span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="fu">print</span> <span class="op">$</span> p2 n</span></code></pre></div> 167 + </div> 168 + </div> 169 + </body> 170 + </html>
+5 -5
out/2.1-day-2-1.html out/2.2-day-2-1.html
··· 87 87 </div> 88 88 <div class="sitenav"> 89 89 <span class="navlink"> 90 - <span class="navlink-label">Previous:</span> <a href="2-section-1.html" accesskey="p" rel="previous">2025</a> 90 + <span class="navlink-label">Previous:</span> <a href="2.1-day-1-1.html" accesskey="p" rel="previous">Day 1</a> 91 91 </span> 92 92 <span class="navlink"> 93 - <span class="navlink-label">Next:</span> <a href="2.2-day-4.html" accesskey="n" rel="next">Day 4</a> 93 + <span class="navlink-label">Next:</span> <a href="2.3-day-4.html" accesskey="n" rel="next">Day 4</a> 94 94 </span> 95 95 </div> 96 96 </nav> 97 97 98 - <h2 data-number="2.1" id="day-2-1">Day 2</h2> 98 + <h2 data-number="2.2" id="day-2-1">Day 2</h2> 99 99 <div class="row"> 100 100 <p>Starting with the parse step, the input is of the form 101 101 <code>11-22,15-17,...</code>. So we first split on commas, for ··· 116 116 117 117 </div> 118 118 </div> 119 - <h3 data-number="2.1.1" id="part-1-2">Part 1</h3> 119 + <h3 data-number="2.2.1" id="part-1-3">Part 1</h3> 120 120 <div class="row"> 121 121 <p>The check for invalidity for an integer in Part 1 requires us 122 122 to simply split the string in half and ensure that the two halves ··· 143 143 <span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>p1 i <span class="ot">=</span> <span class="fu">sum</span> <span class="op">$</span> <span class="fu">concatMap</span> (<span class="fu">filter</span> invalid <span class="op">.</span> <span class="fu">range</span>) i</span></code></pre></div> 144 144 </div> 145 145 </div> 146 - <h3 data-number="2.1.2" id="part-2-1">Part 2</h3> 146 + <h3 data-number="2.2.2" id="part-2-2">Part 2</h3> 147 147 <div class="row"> 148 148 <p>This part requires a slight modification to the invalidity 149 149 check. We now need to check for any number of repeating
+5 -5
out/2.2-day-4.html out/2.3-day-4.html
··· 87 87 </div> 88 88 <div class="sitenav"> 89 89 <span class="navlink"> 90 - <span class="navlink-label">Previous:</span> <a href="2.1-day-2-1.html" accesskey="p" rel="previous">Day 2</a> 90 + <span class="navlink-label">Previous:</span> <a href="2.2-day-2-1.html" accesskey="p" rel="previous">Day 2</a> 91 91 </span> 92 92 <span class="navlink"> 93 - <span class="navlink-label">Next:</span> <a href="2.3-day-5.html" accesskey="n" rel="next">Day 5</a> 93 + <span class="navlink-label">Next:</span> <a href="2.4-day-5.html" accesskey="n" rel="next">Day 5</a> 94 94 </span> 95 95 </div> 96 96 </nav> 97 97 98 - <h2 data-number="2.2" id="day-4">Day 4</h2> 98 + <h2 data-number="2.3" id="day-4">Day 4</h2> 99 99 <div class="row"> 100 100 <p>As always, we start by parsing the input into something more 101 101 manageable:</p> ··· 134 134 135 135 </div> 136 136 </div> 137 - <h3 data-number="2.2.1" id="part-1-3">Part 1</h3> 137 + <h3 data-number="2.3.1" id="part-1-4">Part 1</h3> 138 138 <div class="row"> 139 139 <p>This part requires us to first calculate all points adjacent to 140 140 a roll, if there are more than 4 rolls at these adjacent ··· 177 177 class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>p1 <span class="ot">=</span> size <span class="op">.</span> liftable</span></code></pre></div> 178 178 </div> 179 179 </div> 180 - <h3 data-number="2.2.2" id="part-2-2">Part 2</h3> 180 + <h3 data-number="2.3.2" id="part-2-3">Part 2</h3> 181 181 <div class="row"> 182 182 <p>This part is very similar to the previous part. We need to 183 183 sequentially remove liftable rolls until we can lift no more. A
+5 -5
out/2.3-day-5.html out/2.4-day-5.html
··· 87 87 </div> 88 88 <div class="sitenav"> 89 89 <span class="navlink"> 90 - <span class="navlink-label">Previous:</span> <a href="2.2-day-4.html" accesskey="p" rel="previous">Day 4</a> 90 + <span class="navlink-label">Previous:</span> <a href="2.3-day-4.html" accesskey="p" rel="previous">Day 4</a> 91 91 </span> 92 92 <span class="navlink"> 93 - <span class="navlink-label">Next:</span> <a href="2.4-day-6.html" accesskey="n" rel="next">Day 6</a> 93 + <span class="navlink-label">Next:</span> <a href="2.5-day-6.html" accesskey="n" rel="next">Day 6</a> 94 94 </span> 95 95 </div> 96 96 </nav> 97 97 98 - <h2 data-number="2.3" id="day-5">Day 5</h2> 98 + <h2 data-number="2.4" id="day-5">Day 5</h2> 99 99 <div class="row"> 100 100 <p>As always, we start by parsing the input into something more 101 101 manageable.</p> ··· 132 132 <span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>contains e [start, end] <span class="ot">=</span> e <span class="op">&gt;=</span> start <span class="op">&amp;&amp;</span> e <span class="op">&lt;=</span> end</span></code></pre></div> 133 133 </div> 134 134 </div> 135 - <h3 data-number="2.3.1" id="part-1-4">Part 1</h3> 135 + <h3 data-number="2.4.1" id="part-1-5">Part 1</h3> 136 136 <div class="row"> 137 137 <p>For part one, we need to count how many of the available 138 138 ingredient IDs are fresh. An ID is fresh if it falls within ··· 143 143 <span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>p1 is <span class="ot">=</span> <span class="fu">length</span> <span class="op">.</span> <span class="fu">filter</span> (\p <span class="ot">-&gt;</span> <span class="fu">any</span> (contains p) is)</span></code></pre></div> 144 144 </div> 145 145 </div> 146 - <h3 data-number="2.3.2" id="part-2-3">Part 2</h3> 146 + <h3 data-number="2.4.2" id="part-2-4">Part 2</h3> 147 147 <div class="row"> 148 148 <p>For part two, we need to count the total number of unique 149 149 ingredient IDs covered by all the fresh ranges. The methodology
+5 -5
out/2.4-day-6.html out/2.5-day-6.html
··· 87 87 </div> 88 88 <div class="sitenav"> 89 89 <span class="navlink"> 90 - <span class="navlink-label">Previous:</span> <a href="2.3-day-5.html" accesskey="p" rel="previous">Day 5</a> 90 + <span class="navlink-label">Previous:</span> <a href="2.4-day-5.html" accesskey="p" rel="previous">Day 5</a> 91 91 </span> 92 92 <span class="navlink"> 93 - <span class="navlink-label">Next:</span> <a href="2.5-day-9.html" accesskey="n" rel="next">Day 9</a> 93 + <span class="navlink-label">Next:</span> <a href="2.6-day-9.html" accesskey="n" rel="next">Day 9</a> 94 94 </span> 95 95 </div> 96 96 </nav> 97 97 98 - <h2 data-number="2.4" id="day-6">Day 6</h2> 98 + <h2 data-number="2.5" id="day-6">Day 6</h2> 99 99 <div class="row"> 100 100 <p>This day is largely string munging, which is quite boring, but 101 101 also quite easy to do with Haskell!</p> ··· 103 103 104 104 </div> 105 105 </div> 106 - <h3 data-number="2.4.1" id="part-1-5">Part 1</h3> 106 + <h3 data-number="2.5.1" id="part-1-6">Part 1</h3> 107 107 <div class="row"> 108 108 <p>This part needs us to consider each operation on a column. 109 109 <code>Data.List.transpose</code> fortunately makes this very ··· 158 158 </div> 159 159 </div> 160 160 <pre><code>[[&quot;+&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;], [&quot;*&quot;, &quot;4&quot;, &quot;5&quot;, &quot;6&quot;]]</code></pre> 161 - <h3 data-number="2.4.2" id="part-2-4">Part 2</h3> 161 + <h3 data-number="2.5.2" id="part-2-5">Part 2</h3> 162 162 <div class="row"> 163 163 <p>We are now tasked with lining up the digits in a columnar 164 164 fashion to form a number:</p>
+4 -4
out/2.5-day-9.html out/2.6-day-9.html
··· 87 87 </div> 88 88 <div class="sitenav"> 89 89 <span class="navlink"> 90 - <span class="navlink-label">Previous:</span> <a href="2.4-day-6.html" accesskey="p" rel="previous">Day 6</a> 90 + <span class="navlink-label">Previous:</span> <a href="2.5-day-6.html" accesskey="p" rel="previous">Day 6</a> 91 91 </span> 92 92 <span class="navlink"> 93 93 </span> 94 94 </div> 95 95 </nav> 96 96 97 - <h2 data-number="2.5" id="day-9">Day 9</h2> 97 + <h2 data-number="2.6" id="day-9">Day 9</h2> 98 98 <div class="row"> 99 99 <p>This day’s problem is based on simple coordinate geometry.</p> 100 100 <div class="code"> ··· 120 120 121 121 </div> 122 122 </div> 123 - <h3 data-number="2.5.1" id="part-1-6">Part 1</h3> 123 + <h3 data-number="2.6.1" id="part-1-7">Part 1</h3> 124 124 <div class="row"> 125 125 <p>This part requires us to simply find a rectangle with the 126 126 largest area among the points given to us, so first write a method ··· 142 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> 143 143 </div> 144 144 </div> 145 - <h3 data-number="2.5.2" id="part-2-5">Part 2</h3> 145 + <h3 data-number="2.6.2" id="part-2-6">Part 2</h3> 146 146 <div class="row"> 147 147 <p>This part is a whole lot trickier. We now require only 148 148 rectangles that fall <em>within</em> the polygon. Rectangles that
+6 -5
out/index.html
··· 60 60 </ul></li> 61 61 <li><a href="2-section-1.html#section-1" id="toc-section-1">2025</a> 62 62 <ul> 63 - <li><a href="2.1-day-2-1.html#day-2-1" id="toc-day-2-1">Day 2</a></li> 64 - <li><a href="2.2-day-4.html#day-4" id="toc-day-4">Day 4</a></li> 65 - <li><a href="2.3-day-5.html#day-5" id="toc-day-5">Day 5</a></li> 66 - <li><a href="2.4-day-6.html#day-6" id="toc-day-6">Day 6</a></li> 67 - <li><a href="2.5-day-9.html#day-9" id="toc-day-9">Day 9</a></li> 63 + <li><a href="2.1-day-1-1.html#day-1-1" id="toc-day-1-1">Day 1</a></li> 64 + <li><a href="2.2-day-2-1.html#day-2-1" id="toc-day-2-1">Day 2</a></li> 65 + <li><a href="2.3-day-4.html#day-4" id="toc-day-4">Day 4</a></li> 66 + <li><a href="2.4-day-5.html#day-5" id="toc-day-5">Day 5</a></li> 67 + <li><a href="2.5-day-6.html#day-6" id="toc-day-6">Day 6</a></li> 68 + <li><a href="2.6-day-9.html#day-9" id="toc-day-9">Day 9</a></li> 68 69 </ul></li> 69 70 </ul> 70 71 </nav>
+1 -1
out/sitemap.json
··· 1 - {"section":{"id":"","level":"0","number":null,"path":"index.html","title":"The Book of Solves"},"subsections":[{"section":{"id":"section","level":"1","number":"1","path":"1-section.html#section","title":"2016"},"subsections":[{"section":{"id":"day-1","level":"2","number":"1.1","path":"1.1-day-1.html#day-1","title":"Day 1"},"subsections":[{"section":{"id":"part-1","level":"3","number":"1.1.1","path":"1.1-day-1.html#part-1","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2","level":"3","number":"1.1.2","path":"1.1-day-1.html#part-2","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-2","level":"2","number":"1.2","path":"1.2-day-2.html#day-2","title":"Day 2"},"subsections":[{"section":{"id":"part-1-1","level":"3","number":"1.2.1","path":"1.2-day-2.html#part-1-1","title":"Part 1"},"subsections":[]}]}]},{"section":{"id":"section-1","level":"1","number":"2","path":"2-section-1.html#section-1","title":"2025"},"subsections":[{"section":{"id":"day-2-1","level":"2","number":"2.1","path":"2.1-day-2-1.html#day-2-1","title":"Day 2"},"subsections":[{"section":{"id":"part-1-2","level":"3","number":"2.1.1","path":"2.1-day-2-1.html#part-1-2","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-1","level":"3","number":"2.1.2","path":"2.1-day-2-1.html#part-2-1","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-4","level":"2","number":"2.2","path":"2.2-day-4.html#day-4","title":"Day 4"},"subsections":[{"section":{"id":"part-1-3","level":"3","number":"2.2.1","path":"2.2-day-4.html#part-1-3","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-2","level":"3","number":"2.2.2","path":"2.2-day-4.html#part-2-2","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-5","level":"2","number":"2.3","path":"2.3-day-5.html#day-5","title":"Day 5"},"subsections":[{"section":{"id":"part-1-4","level":"3","number":"2.3.1","path":"2.3-day-5.html#part-1-4","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-3","level":"3","number":"2.3.2","path":"2.3-day-5.html#part-2-3","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-6","level":"2","number":"2.4","path":"2.4-day-6.html#day-6","title":"Day 6"},"subsections":[{"section":{"id":"part-1-5","level":"3","number":"2.4.1","path":"2.4-day-6.html#part-1-5","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-4","level":"3","number":"2.4.2","path":"2.4-day-6.html#part-2-4","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-9","level":"2","number":"2.5","path":"2.5-day-9.html#day-9","title":"Day 9"},"subsections":[{"section":{"id":"part-1-6","level":"3","number":"2.5.1","path":"2.5-day-9.html#part-1-6","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-5","level":"3","number":"2.5.2","path":"2.5-day-9.html#part-2-5","title":"Part 2"},"subsections":[]}]}]}]} 1 + {"section":{"id":"","level":"0","number":null,"path":"index.html","title":"The Book of Solves"},"subsections":[{"section":{"id":"section","level":"1","number":"1","path":"1-section.html#section","title":"2016"},"subsections":[{"section":{"id":"day-1","level":"2","number":"1.1","path":"1.1-day-1.html#day-1","title":"Day 1"},"subsections":[{"section":{"id":"part-1","level":"3","number":"1.1.1","path":"1.1-day-1.html#part-1","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2","level":"3","number":"1.1.2","path":"1.1-day-1.html#part-2","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-2","level":"2","number":"1.2","path":"1.2-day-2.html#day-2","title":"Day 2"},"subsections":[{"section":{"id":"part-1-1","level":"3","number":"1.2.1","path":"1.2-day-2.html#part-1-1","title":"Part 1"},"subsections":[]}]}]},{"section":{"id":"section-1","level":"1","number":"2","path":"2-section-1.html#section-1","title":"2025"},"subsections":[{"section":{"id":"day-1-1","level":"2","number":"2.1","path":"2.1-day-1-1.html#day-1-1","title":"Day 1"},"subsections":[{"section":{"id":"part-1-2","level":"3","number":"2.1.1","path":"2.1-day-1-1.html#part-1-2","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-1","level":"3","number":"2.1.2","path":"2.1-day-1-1.html#part-2-1","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-2-1","level":"2","number":"2.2","path":"2.2-day-2-1.html#day-2-1","title":"Day 2"},"subsections":[{"section":{"id":"part-1-3","level":"3","number":"2.2.1","path":"2.2-day-2-1.html#part-1-3","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-2","level":"3","number":"2.2.2","path":"2.2-day-2-1.html#part-2-2","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-4","level":"2","number":"2.3","path":"2.3-day-4.html#day-4","title":"Day 4"},"subsections":[{"section":{"id":"part-1-4","level":"3","number":"2.3.1","path":"2.3-day-4.html#part-1-4","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-3","level":"3","number":"2.3.2","path":"2.3-day-4.html#part-2-3","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-5","level":"2","number":"2.4","path":"2.4-day-5.html#day-5","title":"Day 5"},"subsections":[{"section":{"id":"part-1-5","level":"3","number":"2.4.1","path":"2.4-day-5.html#part-1-5","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-4","level":"3","number":"2.4.2","path":"2.4-day-5.html#part-2-4","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-6","level":"2","number":"2.5","path":"2.5-day-6.html#day-6","title":"Day 6"},"subsections":[{"section":{"id":"part-1-6","level":"3","number":"2.5.1","path":"2.5-day-6.html#part-1-6","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-5","level":"3","number":"2.5.2","path":"2.5-day-6.html#part-2-5","title":"Part 2"},"subsections":[]}]},{"section":{"id":"day-9","level":"2","number":"2.6","path":"2.6-day-9.html#day-9","title":"Day 9"},"subsections":[{"section":{"id":"part-1-7","level":"3","number":"2.6.1","path":"2.6-day-9.html#part-1-7","title":"Part 1"},"subsections":[]},{"section":{"id":"part-2-6","level":"3","number":"2.6.2","path":"2.6-day-9.html#part-2-6","title":"Part 2"},"subsections":[]}]}]}]}
+55
src/2025/01.lhs
··· 1 + # 2025 2 + 3 + ## Day 1 4 + 5 + Parse the input: 6 + 7 + ```haskell 8 + parse :: String -> [Int] 9 + parse = map f . lines 10 + where f ('L':r) = negate (read r) 11 + f ('R':r) = read r 12 + ``` 13 + 14 + ### Part 1 15 + 16 + Rotate the dial starting at 50, and count the number of times we stop at zero on the way. Of note is that the dial cycles back to zero after 100, so our check mustn't just be `== 0` but rather, `mod n 100 == 0`: 17 + 18 + ```haskell 19 + count :: (a -> Bool) -> [a] -> Int 20 + count pred = length . filter pred 21 + 22 + clicks :: [Int] -> Int 23 + clicks = count ((== 0) . (`mod` 100)) . scanl (+) 50 24 + ``` 25 + 26 + Thus, the solution to the first part is given by: 27 + 28 + ```haskell 29 + p1 :: [Int] -> Int 30 + p1 = clicks 31 + ``` 32 + 33 + ### Part 2 34 + 35 + This part is ever so slightly different, instead of the number of times we *stop* are zero, we are required to additionally calculate the number of times we *pass* through zero. 36 + 37 + To think of this a bit differently, the first part has lower degree of precision: we only perform the check after the dial is fully rotated. The second part requires us to perform the check with higher degree of precision: after each movement by 1. Thus, if we modify our list to change one rotation of size N into N rotations of size 1, we will be able to reuse our `clicks` method: 38 + 39 + ```haskell 40 + transform :: Int -> [Int] 41 + transform n = replicate (abs n) (signum n) 42 + 43 + p2 :: [Int] -> Int 44 + p2 = clicks . concatMap transform 45 + ``` 46 + 47 + Finally, a main function to wrap it all up: 48 + 49 + ```haskell 50 + main = do 51 + n <- parse <$> getContents 52 + print $ p1 n 53 + print $ p2 n 54 + ``` 55 +