From: Neil Smith <NeilNjae@users.noreply.github.com> Date: Sun, 1 Dec 2024 17:24:47 +0000 (+0000) Subject: Added README X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=38516e72ee1f9c93ba68747c9eafc0b572534f42;p=advent-of-code-24.git Added README --- diff --git a/README.html b/README.html new file mode 100644 index 0000000..b096a26 --- /dev/null +++ b/README.html @@ -0,0 +1,225 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> +<head> + <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 2023</title> + <style> + code{white-space: pre-wrap;} + span.smallcaps{font-variant: small-caps;} + 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;} + /* The extra [class] is a hack that increases specificity enough to + override a similar rule in reveal.js */ + ul.task-list[class]{list-style: none;} + ul.task-list li input[type="checkbox"] { + font-size: inherit; + width: 0.8em; + margin: 0 0.8em 0.2em -1.6em; + vertical-align: middle; + } + .display.math{display: block; text-align: center; margin: 0.5rem auto;} + /* CSS for syntax highlighting */ + pre > code.sourceCode { white-space: pre; position: relative; } + pre > code.sourceCode > span { line-height: 1.25; } + pre > code.sourceCode > span:empty { height: 1.2em; } + .sourceCode { overflow: visible; } + code.sourceCode > span { color: inherit; text-decoration: inherit; } + div.sourceCode { margin: 1em 0; } + pre.sourceCode { margin: 0; } + @media screen { + div.sourceCode { overflow: auto; } + } + @media print { + pre > code.sourceCode { white-space: pre-wrap; } + pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; } + } + pre.numberSource code + { counter-reset: source-line 0; } + pre.numberSource code > span + { position: relative; left: -4em; counter-increment: source-line; } + pre.numberSource code > span > a:first-child::before + { content: counter(source-line); + position: relative; left: -1em; text-align: right; vertical-align: baseline; + border: none; display: inline-block; + -webkit-touch-callout: none; -webkit-user-select: none; + -khtml-user-select: none; -moz-user-select: none; + -ms-user-select: none; user-select: none; + padding: 0 4px; width: 4em; + color: #aaaaaa; + } + pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; } + div.sourceCode + { } + @media screen { + pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; } + } + code span.al { color: #ff0000; font-weight: bold; } /* Alert */ + 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 { 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.co { color: #60a0b0; font-style: italic; } /* Comment */ + code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */ + code span.do { color: #ba2121; font-style: italic; } /* Documentation */ + code span.dt { color: #902000; } /* DataType */ + code span.dv { color: #40a070; } /* DecVal */ + code span.er { color: #ff0000; font-weight: bold; } /* Error */ + code span.ex { } /* Extension */ + code span.fl { color: #40a070; } /* Float */ + code span.fu { color: #06287e; } /* Function */ + 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 */ + code span.ot { color: #007020; } /* Other */ + code span.pp { color: #bc7a00; } /* Preprocessor */ + code span.sc { color: #4070a0; } /* SpecialChar */ + code span.ss { color: #bb6688; } /* SpecialString */ + code span.st { color: #4070a0; } /* String */ + code span.va { color: #19177c; } /* Variable */ + code span.vs { color: #4070a0; } /* VerbatimString */ + code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ + </style> + <link rel="stylesheet" href="modest.css" /> +</head> +<body> +<header id="title-block-header"> +<h1 class="title">Advent of Code 2023</h1> +</header> +<p>Code to solve the <a href="http://adventofcode.com/2024/">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>Create the basic <code>cabal</code> project.</p> +<pre><code>cabal init</code></pre> +<p>Modify the <code>advent-of-code24.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>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> +<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> +<pre><code>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 + -rtsopts "-with-rtsopts=-N -p -s -hT"</code></pre> +<p>then running</p> +<pre><code>cabal run advent01prof --enable-profiling</code></pre> +<p>Generate the profile graph with</p> +<pre><code>hp2ps -M advent01.hp</code></pre> +<p>To generate an eventlog (used for tracking multi-core performance), +pass in the <code>-l</code> RTS flag:</p> +<pre><code>cabal run advent01 --enable-profiling -- +RTS -N -p -s -hT -l</code></pre> +<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> +</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>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>).</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)</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> +</body> +</html> diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb6b897 --- /dev/null +++ b/README.md @@ -0,0 +1,134 @@ +--- +title: "Advent of Code 2023" +output: html_document +css: modest.css +--- +Code to solve the [Advent of Code](http://adventofcode.com/2024/) 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-code24.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 +``` + +## 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 + -rtsopts "-with-rtsopts=-N -p -s -hT" +``` + +then running + +``` +cabal run advent01prof --enable-profiling +``` + + +Generate the profile graph with +``` +hp2ps -M advent01.hp +``` + +To generate an eventlog (used for tracking multi-core performance), pass in the `-l` RTS flag: + +``` +cabal run advent01 --enable-profiling -- +RTS -N -p -s -hT -l +``` + +# 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)). +* [RWS](https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-RWS-Lazy.html) (Reader-Writer-State monad stack) +* [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).)