Initial attempt at optimising day 23
[advent-of-code-23.git] / README.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 <title>Advent of Code 2023</title>
8 <style>
9 code{white-space: pre-wrap;}
10 span.smallcaps{font-variant: small-caps;}
11 div.columns{display: flex; gap: min(4vw, 1.5em);}
12 div.column{flex: auto; overflow-x: auto;}
13 div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
14 ul.task-list{list-style: none;}
15 ul.task-list li input[type="checkbox"] {
16 width: 0.8em;
17 margin: 0 0.8em 0.2em -1.6em;
18 vertical-align: middle;
19 }
20 pre > code.sourceCode { white-space: pre; position: relative; }
21 pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
22 pre > code.sourceCode > span:empty { height: 1.2em; }
23 .sourceCode { overflow: visible; }
24 code.sourceCode > span { color: inherit; text-decoration: inherit; }
25 div.sourceCode { margin: 1em 0; }
26 pre.sourceCode { margin: 0; }
27 @media screen {
28 div.sourceCode { overflow: auto; }
29 }
30 @media print {
31 pre > code.sourceCode { white-space: pre-wrap; }
32 pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
33 }
34 pre.numberSource code
35 { counter-reset: source-line 0; }
36 pre.numberSource code > span
37 { position: relative; left: -4em; counter-increment: source-line; }
38 pre.numberSource code > span > a:first-child::before
39 { content: counter(source-line);
40 position: relative; left: -1em; text-align: right; vertical-align: baseline;
41 border: none; display: inline-block;
42 -webkit-touch-callout: none; -webkit-user-select: none;
43 -khtml-user-select: none; -moz-user-select: none;
44 -ms-user-select: none; user-select: none;
45 padding: 0 4px; width: 4em;
46 color: #aaaaaa;
47 }
48 pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
49 div.sourceCode
50 { }
51 @media screen {
52 pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
53 }
54 code span.al { color: #ff0000; font-weight: bold; } /* Alert */
55 code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
56 code span.at { color: #7d9029; } /* Attribute */
57 code span.bn { color: #40a070; } /* BaseN */
58 code span.bu { color: #008000; } /* BuiltIn */
59 code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
60 code span.ch { color: #4070a0; } /* Char */
61 code span.cn { color: #880000; } /* Constant */
62 code span.co { color: #60a0b0; font-style: italic; } /* Comment */
63 code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
64 code span.do { color: #ba2121; font-style: italic; } /* Documentation */
65 code span.dt { color: #902000; } /* DataType */
66 code span.dv { color: #40a070; } /* DecVal */
67 code span.er { color: #ff0000; font-weight: bold; } /* Error */
68 code span.ex { } /* Extension */
69 code span.fl { color: #40a070; } /* Float */
70 code span.fu { color: #06287e; } /* Function */
71 code span.im { color: #008000; font-weight: bold; } /* Import */
72 code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
73 code span.kw { color: #007020; font-weight: bold; } /* Keyword */
74 code span.op { color: #666666; } /* Operator */
75 code span.ot { color: #007020; } /* Other */
76 code span.pp { color: #bc7a00; } /* Preprocessor */
77 code span.sc { color: #4070a0; } /* SpecialChar */
78 code span.ss { color: #bb6688; } /* SpecialString */
79 code span.st { color: #4070a0; } /* String */
80 code span.va { color: #19177c; } /* Variable */
81 code span.vs { color: #4070a0; } /* VerbatimString */
82 code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
83 .display.math{display: block; text-align: center; margin: 0.5rem auto;}
84 </style>
85 <link rel="stylesheet" href="modest.css" />
86 <!--[if lt IE 9]>
87 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
88 <![endif]-->
89 </head>
90 <body>
91 <header id="title-block-header">
92 <h1 class="title">Advent of Code 2023</h1>
93 </header>
94 <p>Code to solve the <a href="http://adventofcode.com/2023/">Advent of
95 Code</a> puzzles. This year, I’m using the puzzles to develop my skills
96 in <a href="https://wiki.haskell.org/Haskell">Haskell</a>. I’m writing
97 up a <a href="https://work.njae.me.uk/tag/advent-of-code/">commentary on
98 these puzzles and my solutions</a> on my blog.</p>
99 <p><a href="http://learnyouahaskell.com/chapters">Learn you a
100 Haskell</a>, <a
101 href="https://www.haskell.org/tutorial/index.html">Introduction to
102 Haskell 98</a>, and <a href="https://hackage.haskell.org/">Hackage</a>
103 are good resources.</p>
104 <p>The <a href="https://cabal.readthedocs.io/en/latest/index.html">Cabal
105 user guide</a> and <a href="http://howistart.org/posts/haskell/1/">How I
106 Start: Haskell</a> are good sources of using the tools.</p>
107 <h1 id="toolchain">Toolchain</h1>
108 <p>Install Ghcup following <a
109 href="https://www.haskell.org/ghcup/install/#installation">the
110 instructions</a>, making sure to load the updated environment with</p>
111 <div class="sourceCode" id="cb1"><pre
112 class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="bu">source</span> /home/neil/.ghcup/env</span></code></pre></div>
113 <p>and then set the default GHC to use with
114 <code>ghcup set ghc 9.0.1</code> .</p>
115 <p>Install <a
116 href="https://haskell-language-server.readthedocs.io/en/latest/configuration.html">Haskell
117 Language Server</a> for Sublime Text</p>
118 <h2 id="creating-the-repository-and-project">Creating the repository and
119 project</h2>
120 <p>Create the repository as normal: create the project in Gitolite,
121 clone it, and insert the <code>.gitignore</code> and
122 <code>README.md</code> files.</p>
123 <p>There’s one package per day, with the code for each package in
124 sub-directories of the root directory.</p>
125 <p>Create the basic <code>cabal</code> project.</p>
126 <pre><code>cabal init</code></pre>
127 <p>Modify the <code>advent-of-code21.cabal</code> file as needed, such
128 as updating the Cabal version and writing the <code>common</code>
129 stanzas.</p>
130 <h2 id="creating-subsequent-days">Creating subsequent days</h2>
131 <p>Each day lives in a separate directory, with code in the
132 <code>src</code> directory.</p>
133 <p>Compile with</p>
134 <pre><code>cabal build</code></pre>
135 <p>or</p>
136 <pre><code>cabal build advent01</code></pre>
137 <p>Run with</p>
138 <pre><code>cabal run advent01</code></pre>
139 <p>If you want to pass in additional RTS parameters, do it like
140 this:</p>
141 <pre><code>cabal run advent01 -- +RTS -K0 -RTS</code></pre>
142 <p>Run interactively with</p>
143 <pre><code>cabal repl advent01</code></pre>
144 <p>or</p>
145 <pre><code>stack ghci advent01:exe:advent01</code></pre>
146 <p>if the first form is ambiguous.</p>
147 <h2 id="profiling">Profiling</h2>
148 <p>To profile, use</p>
149 <pre><code>cabal run advent01 --enable-profiling -- +RTS -N -p -s -hT</code></pre>
150 <p>Or, you can simplify the RTS options by adding them to a new stanza
151 in the cabal file:</p>
152 <pre><code>executable advent01prof
153 import: common-extensions, build-directives
154 main-is: advent01/Main.hs
155 build-depends: text, containers, linear, array, pqueue, mtl, lens
156 ghc-options: -O2
157 -Wall
158 -threaded
159 -eventlog
160 -rtsopts &quot;-with-rtsopts=-N -p -s -hT&quot;</code></pre>
161 <p>Only include the <code>-eventlog</code> directive if you want to use
162 Threadscope to investigate parallel behaviour.</p>
163 <p>then running</p>
164 <pre><code>cabal run advent01prof --enable-profiling</code></pre>
165 <p>Generate the profile graph with</p>
166 <pre><code>hp2ps -M advent01.hp</code></pre>
167 <h1 id="packages">Packages</h1>
168 <p>Packages I used a lot:</p>
169 <ul>
170 <li><a
171 href="https://hackage.haskell.org/package/containers">Containers</a>
172 (and some <a
173 href="https://haskell-containers.readthedocs.io/en/latest/intro.html">better
174 documentation</a>); <a
175 href="https://hackage.haskell.org/package/unordered-containers">Unordered
176 containers</a> is a mostly-equivalent alternative.</li>
177 <li><a
178 href="https://hackage.haskell.org/package/attoparsec">Attoparsec</a>
179 (and <a
180 href="https://hackage.haskell.org/package/megaparsec">Megaparsec</a>,
181 and <a
182 href="https://hackage.haskell.org/package/base-4.14.1.0/docs/Text-ParserCombinators-ReadP.html">ReadP</a>
183 once).</li>
184 </ul>
185 <p>There are somewhat decent <a
186 href="https://markkarpov.com/tutorial/megaparsec.html">tutorials on
187 Megaparsec</a> and <a
188 href="https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec">Attoparsec</a>.</p>
189 <p>Packages I didn’t use much, but need to remember:</p>
190 <ul>
191 <li><a href="https://hackage.haskell.org/package/arithmoi">Arithmoi</a>
192 for number theory</li>
193 <li><a
194 href="https://hackage.haskell.org/package/pointedlist-0.6.1">Pointed
195 List</a> for zipper lists (sometimes circular)</li>
196 <li><a href="https://hackage.haskell.org/package/vector">Vector</a> for
197 array-like things</li>
198 <li><a href="https://hackage.haskell.org/package/linear">Linear</a> for
199 coordinate-vector like things</li>
200 <li><a href="https://hackage.haskell.org/package/grid">Grid</a> for 2-d
201 grids</li>
202 <li><a
203 href="https://hackage.haskell.org/package/graph-wrapper">Graph-wrapper</a>
204 for graphs</li>
205 <li><a href="https://hackage.haskell.org/package/lens">Lens</a> (and a
206 <a href="https://github.com/ekmett/lens/wiki/Operators">summary of
207 operators</a>). I didn’t use these much this year, but did a lot last
208 year.</li>
209 <li><a
210 href="https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-RWS-Lazy.html">RWS</a>
211 (Reader-Writer-State monad stack); again, used a lot last year but not
212 this year</li>
213 <li><a
214 href="https://hackage.haskell.org/package/monad-loops-0.4.3/docs/Control-Monad-Loops.html">Monad
215 loops</a>, and <a
216 href="https://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/">a
217 description</a></li>
218 <li><a
219 href="https://github.com/jamesdbrock/replace-megaparsec">Replace-Megaparsec</a>,
220 for using Mpc for all sorts of things traditionally done with regex
221 substitutions.</li>
222 </ul>
223 <h1 id="readme">Readme</h1>
224 <p>Build this readme file wth</p>
225 <pre><code>pandoc -s README.md &gt; README.html</code></pre>
226 <p>(Using the <a href="https://github.com/markdowncss/modest">Modest
227 style</a>.)</p>
228 </body>
229 </html>