<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
- <title>Advent of Code 2022</title>
+ <title>Advent of Code 2023</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
- span.underline{text-decoration: underline;}
- div.column{display: inline-block; vertical-align: top; width: 50%;}
+ div.columns{display: flex; gap: min(4vw, 1.5em);}
+ div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
+ ul.task-list li input[type="checkbox"] {
+ width: 0.8em;
+ margin: 0 0.8em 0.2em -1.6em;
+ vertical-align: middle;
+ }
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
- code span.bu { } /* BuiltIn */
+ code span.bu { color: #008000; } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
- code span.im { } /* Import */
+ code span.im { color: #008000; font-weight: bold; } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
</head>
<body>
<header id="title-block-header">
-<h1 class="title">Advent of Code 2022</h1>
+<h1 class="title">Advent of Code 2023</h1>
</header>
-<p>Code to solve the <a href="http://adventofcode.com/2022/">Advent of Code</a> puzzles. This year, I’m using the puzzles to develop my skills in <a href="https://wiki.haskell.org/Haskell">Haskell</a>. I’m writing up a <a href="https://work.njae.me.uk/tag/advent-of-code/">commentary on these puzzles and my solutions</a> on my blog.</p>
-<p><a href="http://learnyouahaskell.com/chapters">Learn you a Haskell</a>, <a href="https://www.haskell.org/tutorial/index.html">Introduction to Haskell 98</a>, and <a href="https://hackage.haskell.org/">Hackage</a> are good resources.</p>
-<p>The <a href="https://cabal.readthedocs.io/en/latest/index.html">Cabal user guide</a> and <a href="http://howistart.org/posts/haskell/1/">How I Start: Haskell</a> are good sources of using the tools.</p>
+<p>Code to solve the <a href="http://adventofcode.com/2023/">Advent of
+Code</a> puzzles. This year, I’m using the puzzles to develop my skills
+in <a href="https://wiki.haskell.org/Haskell">Haskell</a>. I’m writing
+up a <a href="https://work.njae.me.uk/tag/advent-of-code/">commentary on
+these puzzles and my solutions</a> on my blog.</p>
+<p><a href="http://learnyouahaskell.com/chapters">Learn you a
+Haskell</a>, <a
+href="https://www.haskell.org/tutorial/index.html">Introduction to
+Haskell 98</a>, and <a href="https://hackage.haskell.org/">Hackage</a>
+are good resources.</p>
+<p>The <a href="https://cabal.readthedocs.io/en/latest/index.html">Cabal
+user guide</a> and <a href="http://howistart.org/posts/haskell/1/">How I
+Start: Haskell</a> are good sources of using the tools.</p>
<h1 id="toolchain">Toolchain</h1>
-<p>Install Ghcup following <a href="https://www.haskell.org/ghcup/install/#installation">the instructions</a>, making sure to load the updated environment with</p>
-<div class="sourceCode" id="cb1"><pre 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>
-<p>and then set the default GHC to use with <code>ghcup set ghc 9.0.1</code> .</p>
-<p>Install <a href="https://haskell-language-server.readthedocs.io/en/latest/configuration.html">Haskell Language Server</a> for Sublime Text</p>
-<h2 id="creating-the-repository-and-project">Creating the repository and project</h2>
-<p>Create the repository as normal: create the project in Gitolite, clone it, and insert the <code>.gitignore</code> and <code>README.md</code> files.</p>
-<p>There’s one package per day, with the code for each package in sub-directories of the root directory.</p>
+<p>Install Ghcup following <a
+href="https://www.haskell.org/ghcup/install/#installation">the
+instructions</a>, making sure to load the updated environment with</p>
+<div class="sourceCode" id="cb1"><pre
+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>
+<p>and then set the default GHC to use with
+<code>ghcup set ghc 9.0.1</code> .</p>
+<p>Install <a
+href="https://haskell-language-server.readthedocs.io/en/latest/configuration.html">Haskell
+Language Server</a> for Sublime Text</p>
+<h2 id="creating-the-repository-and-project">Creating the repository and
+project</h2>
+<p>Create the repository as normal: create the project in Gitolite,
+clone it, and insert the <code>.gitignore</code> and
+<code>README.md</code> files.</p>
+<p>There’s one package per day, with the code for each package in
+sub-directories of the root directory.</p>
<p>Create the basic <code>cabal</code> project.</p>
<pre><code>cabal init</code></pre>
-<p>Modify the <code>advent-of-code21.cabal</code> file as needed, such as updating the Cabal version and writing the <code>common</code> stanzas.</p>
+<p>Modify the <code>advent-of-code21.cabal</code> file as needed, such
+as updating the Cabal version and writing the <code>common</code>
+stanzas.</p>
<h2 id="creating-subsequent-days">Creating subsequent days</h2>
-<p>Each day lives in a separate directory, with code in the <code>src</code> directory.</p>
+<p>Each day lives in a separate directory, with code in the
+<code>src</code> directory.</p>
<p>Compile with</p>
<pre><code>cabal build</code></pre>
<p>or</p>
<pre><code>cabal build advent01</code></pre>
<p>Run with</p>
<pre><code>cabal run advent01</code></pre>
-<p>If you want to pass in additional RTS parameters, do it like this:</p>
+<p>If you want to pass in additional RTS parameters, do it like
+this:</p>
<pre><code>cabal run advent01 -- +RTS -K0 -RTS</code></pre>
<p>Run interactively with</p>
<pre><code>cabal repl advent01</code></pre>
<h2 id="profiling">Profiling</h2>
<p>To profile, use</p>
<pre><code>cabal run advent01 --enable-profiling -- +RTS -N -p -s -hT</code></pre>
-<p>Or, you can simplify the RTS options by adding them to a new stanza in the cabal file:</p>
+<p>Or, you can simplify the RTS options by adding them to a new stanza
+in the cabal file:</p>
<pre><code>executable advent01prof
import: common-extensions, build-directives
main-is: advent01/Main.hs
ghc-options: -O2
-Wall
-threaded
+ -eventlog
-rtsopts "-with-rtsopts=-N -p -s -hT"</code></pre>
+<p>Only include the <code>-eventlog</code> directive if you want to use
+Threadscope to investigate parallel behaviour.</p>
<p>then running</p>
<pre><code>cabal run advent01prof --enable-profiling</code></pre>
<p>Generate the profile graph with</p>
<h1 id="packages">Packages</h1>
<p>Packages I used a lot:</p>
<ul>
-<li><a href="https://hackage.haskell.org/package/containers">Containers</a> (and some <a href="https://haskell-containers.readthedocs.io/en/latest/intro.html">better documentation</a>); <a href="https://hackage.haskell.org/package/unordered-containers">Unordered containers</a> is a mostly-equivalent alternative.</li>
-<li><a href="https://hackage.haskell.org/package/attoparsec">Attoparsec</a> (and <a href="https://hackage.haskell.org/package/megaparsec">Megaparsec</a>, and <a href="https://hackage.haskell.org/package/base-4.14.1.0/docs/Text-ParserCombinators-ReadP.html">ReadP</a> once).</li>
+<li><a
+href="https://hackage.haskell.org/package/containers">Containers</a>
+(and some <a
+href="https://haskell-containers.readthedocs.io/en/latest/intro.html">better
+documentation</a>); <a
+href="https://hackage.haskell.org/package/unordered-containers">Unordered
+containers</a> is a mostly-equivalent alternative.</li>
+<li><a
+href="https://hackage.haskell.org/package/attoparsec">Attoparsec</a>
+(and <a
+href="https://hackage.haskell.org/package/megaparsec">Megaparsec</a>,
+and <a
+href="https://hackage.haskell.org/package/base-4.14.1.0/docs/Text-ParserCombinators-ReadP.html">ReadP</a>
+once).</li>
</ul>
-<p>There are somewhat decent <a href="https://markkarpov.com/tutorial/megaparsec.html">tutorials on Megaparsec</a> and <a href="https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec">Attoparsec</a>.</p>
+<p>There are somewhat decent <a
+href="https://markkarpov.com/tutorial/megaparsec.html">tutorials on
+Megaparsec</a> and <a
+href="https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec">Attoparsec</a>.</p>
<p>Packages I didn’t use much, but need to remember:</p>
<ul>
-<li><a href="https://hackage.haskell.org/package/arithmoi">Arithmoi</a> for number theory</li>
-<li><a href="https://hackage.haskell.org/package/pointedlist-0.6.1">Pointed List</a> for zipper lists (sometimes circular)</li>
-<li><a href="https://hackage.haskell.org/package/vector">Vector</a> for array-like things</li>
-<li><a href="https://hackage.haskell.org/package/linear">Linear</a> for coordinate-vector like things</li>
-<li><a href="https://hackage.haskell.org/package/grid">Grid</a> for 2-d grids</li>
-<li><a href="https://hackage.haskell.org/package/graph-wrapper">Graph-wrapper</a> for graphs</li>
-<li><a href="https://hackage.haskell.org/package/lens">Lens</a> (and a <a href="https://github.com/ekmett/lens/wiki/Operators">summary of operators</a>). I didn’t use these much this year, but did a lot last year.</li>
-<li><a href="https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-RWS-Lazy.html">RWS</a> (Reader-Writer-State monad stack); again, used a lot last year but not this year</li>
-<li><a href="https://hackage.haskell.org/package/monad-loops-0.4.3/docs/Control-Monad-Loops.html">Monad loops</a>, and <a href="https://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/">a description</a></li>
-<li><a href="https://github.com/jamesdbrock/replace-megaparsec">Replace-Megaparsec</a>, for using Mpc for all sorts of things traditionally done with regex substitutions.</li>
+<li><a href="https://hackage.haskell.org/package/arithmoi">Arithmoi</a>
+for number theory</li>
+<li><a
+href="https://hackage.haskell.org/package/pointedlist-0.6.1">Pointed
+List</a> for zipper lists (sometimes circular)</li>
+<li><a href="https://hackage.haskell.org/package/vector">Vector</a> for
+array-like things</li>
+<li><a href="https://hackage.haskell.org/package/linear">Linear</a> for
+coordinate-vector like things</li>
+<li><a href="https://hackage.haskell.org/package/grid">Grid</a> for 2-d
+grids</li>
+<li><a
+href="https://hackage.haskell.org/package/graph-wrapper">Graph-wrapper</a>
+for graphs</li>
+<li><a href="https://hackage.haskell.org/package/lens">Lens</a> (and a
+<a href="https://github.com/ekmett/lens/wiki/Operators">summary of
+operators</a>). I didn’t use these much this year, but did a lot last
+year.</li>
+<li><a
+href="https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-RWS-Lazy.html">RWS</a>
+(Reader-Writer-State monad stack); again, used a lot last year but not
+this year</li>
+<li><a
+href="https://hackage.haskell.org/package/monad-loops-0.4.3/docs/Control-Monad-Loops.html">Monad
+loops</a>, and <a
+href="https://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/">a
+description</a></li>
+<li><a
+href="https://github.com/jamesdbrock/replace-megaparsec">Replace-Megaparsec</a>,
+for using Mpc for all sorts of things traditionally done with regex
+substitutions.</li>
</ul>
<h1 id="readme">Readme</h1>
<p>Build this readme file wth</p>
<pre><code>pandoc -s README.md > README.html</code></pre>
-<p>(Using the <a href="https://github.com/markdowncss/modest">Modest style</a>.)</p>
+<p>(Using the <a href="https://github.com/markdowncss/modest">Modest
+style</a>.)</p>
</body>
</html>
--- /dev/null
+---
+title: "Advent of Code 2023"
+output: html_document
+css: modest.css
+---
+Code to solve the [Advent of Code](http://adventofcode.com/2023/) puzzles. This year, I'm using the puzzles to develop my skills in [Haskell](https://wiki.haskell.org/Haskell). I'm writing up a [commentary on these puzzles and my solutions](https://work.njae.me.uk/tag/advent-of-code/) on my blog.
+
+[Learn you a Haskell](http://learnyouahaskell.com/chapters), [Introduction to Haskell 98](https://www.haskell.org/tutorial/index.html), and [Hackage](https://hackage.haskell.org/) are good resources.
+
+The [Cabal user guide](https://cabal.readthedocs.io/en/latest/index.html) and [How I Start: Haskell](http://howistart.org/posts/haskell/1/) are good sources of using the tools.
+
+# Toolchain
+
+Install Ghcup following [the instructions](https://www.haskell.org/ghcup/install/#installation), making sure to load the updated environment with
+
+```bash
+source /home/neil/.ghcup/env
+```
+
+and then set the default GHC to use with `ghcup set ghc 9.0.1` .
+
+Install [Haskell Language Server](https://haskell-language-server.readthedocs.io/en/latest/configuration.html) for Sublime Text
+
+
+## Creating the repository and project
+Create the repository as normal: create the project in Gitolite, clone it, and insert the `.gitignore` and `README.md` files.
+
+There's one package per day, with the code for each package in sub-directories of the root directory.
+
+Create the basic `cabal` project.
+
+```
+cabal init
+```
+
+Modify the `advent-of-code21.cabal` file as needed, such as updating the Cabal version and writing the `common` stanzas.
+
+## Creating subsequent days
+
+Each day lives in a separate directory, with code in the `src` directory.
+
+Compile with
+```
+cabal build
+```
+or
+```
+cabal build advent01
+```
+
+Run with
+```
+cabal run advent01
+```
+
+If you want to pass in additional RTS parameters, do it like this:
+```
+cabal run advent01 -- +RTS -K0 -RTS
+```
+
+Run interactively with
+```
+cabal repl advent01
+```
+or
+```
+stack ghci advent01:exe:advent01
+```
+if the first form is ambiguous.
+
+## Profiling
+
+To profile, use
+
+```
+cabal run advent01 --enable-profiling -- +RTS -N -p -s -hT
+```
+
+Or, you can simplify the RTS options by adding them to a new stanza in the cabal file:
+
+```
+executable advent01prof
+ import: common-extensions, build-directives
+ main-is: advent01/Main.hs
+ build-depends: text, containers, linear, array, pqueue, mtl, lens
+ ghc-options: -O2
+ -Wall
+ -threaded
+ -eventlog
+ -rtsopts "-with-rtsopts=-N -p -s -hT"
+```
+
+Only include the `-eventlog` directive if you want to use Threadscope to investigate parallel behaviour.
+
+then running
+
+```
+cabal run advent01prof --enable-profiling
+```
+
+
+Generate the profile graph with
+```
+hp2ps -M advent01.hp
+```
+
+
+# Packages
+
+Packages I used a lot:
+
+* [Containers](https://hackage.haskell.org/package/containers) (and some [better documentation](https://haskell-containers.readthedocs.io/en/latest/intro.html)); [Unordered containers](https://hackage.haskell.org/package/unordered-containers) is a mostly-equivalent alternative.
+* [Attoparsec](https://hackage.haskell.org/package/attoparsec) (and [Megaparsec](https://hackage.haskell.org/package/megaparsec), and [ReadP](https://hackage.haskell.org/package/base-4.14.1.0/docs/Text-ParserCombinators-ReadP.html) once).
+
+There are somewhat decent [tutorials on Megaparsec](https://markkarpov.com/tutorial/megaparsec.html) and [Attoparsec](https://www.schoolofhaskell.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/attoparsec).
+
+Packages I didn't use much, but need to remember:
+
+* [Arithmoi](https://hackage.haskell.org/package/arithmoi) for number theory
+* [Pointed List](https://hackage.haskell.org/package/pointedlist-0.6.1) for zipper lists (sometimes circular)
+* [Vector](https://hackage.haskell.org/package/vector) for array-like things
+* [Linear](https://hackage.haskell.org/package/linear) for coordinate-vector like things
+* [Grid](https://hackage.haskell.org/package/grid) for 2-d grids
+* [Graph-wrapper](https://hackage.haskell.org/package/graph-wrapper) for graphs
+* [Lens](https://hackage.haskell.org/package/lens) (and a [summary of operators](https://github.com/ekmett/lens/wiki/Operators)). I didn't use these much this year, but did a lot last year.
+* [RWS](https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-RWS-Lazy.html) (Reader-Writer-State monad stack); again, used a lot last year but not this year
+* [Monad loops](https://hackage.haskell.org/package/monad-loops-0.4.3/docs/Control-Monad-Loops.html), and [a description](https://conscientiousprogrammer.com/blog/2015/12/11/24-days-of-hackage-2015-day-11-monad-loops-avoiding-writing-recursive-functions-by-refactoring/)
+* [Replace-Megaparsec](https://github.com/jamesdbrock/replace-megaparsec), for using Mpc for all sorts of things traditionally done with regex substitutions.
+
+# Readme
+
+Build this readme file wth
+```
+pandoc -s README.md > README.html
+```
+
+(Using the [Modest style](https://github.com/markdowncss/modest).)