diff --git a/Makefile b/Makefile index fc19469..b90b91a 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ $(wildcard _src/gap/$(1)/$(2).nw) \ $(wildcard _src/haskell/$(1)/$(2).nw) years := \ -2018 2019 2021 +2015 2018 2019 2021 days := \ 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @@ -25,6 +25,7 @@ NW_SRCS := $(foreach year,${years},$(call year_srcs,${year})) GAP_SRCS := $(patsubst _src/gap/%.nw,src/Day%.g,$(filter _src/gap/%.nw,${NW_SRCS})) HS_SRCS := \ +$(patsubst _src/2015/haskell/%.nw,src/AdventOfCode/Year2015/Day%.hs,$(filter _src/2015/haskell/%.nw,${NW_SRCS})) \ $(patsubst _src/2018/haskell/%.nw,src/AdventOfCode/Year2018/Day%.hs,$(filter _src/2018/haskell/%.nw,${NW_SRCS})) \ $(patsubst _src/2019/haskell/%.nw,src/AdventOfCode/Year2019/Day%.hs,$(filter _src/2019/haskell/%.nw,${NW_SRCS})) \ $(patsubst _src/2021/haskell/%.nw,src/AdventOfCode/Year2021/Day%.hs,$(filter _src/2021/haskell/%.nw,${NW_SRCS})) @@ -52,6 +53,9 @@ build: flake.nix $(wildcard src/**.hs) $(wildcard app/**.hs) escape_underscores := 'sed "/^@use /s/_/\\\\_/g;/^@defn /s/_/\\\\_/g"' +_src/tex/2015.tex: $(call year_srcs,2015) + noweave -filter ${escape_underscores} -n -index $^ ${cpif} $@ + _src/tex/2018.tex: $(call year_srcs,2018) noweave -filter ${escape_underscores} -n -index $^ ${cpif} $@ @@ -76,6 +80,11 @@ src/Day%.g: _src/gap/%.nw notangle -R'$(@F)' $< ${cpif} $@ +src/AdventOfCode/Year2015/Day%.hs: _src/2015/haskell/%.nw + @ mkdir -p $(@D) + notangle -R'$(@F)' $< ${cpif} $@ + + src/AdventOfCode/Year2018/Day%.hs: _src/2018/haskell/%.nw @ mkdir -p $(@D) notangle -R'$(@F)' $< ${cpif} $@ diff --git a/VERSION b/VERSION index 2ec3d9b..62de270 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2023.6.2.12 \ No newline at end of file +2023.6.2.13 \ No newline at end of file diff --git a/_src/2015/day/25.nw b/_src/2015/day/25.nw new file mode 100644 index 0000000..15ebeb7 --- /dev/null +++ b/_src/2015/day/25.nw @@ -0,0 +1,97 @@ +\newpage +\section{Day 25: Let It Snow} +\marginnote{\url{https://adventofcode.com/2015/day/25}} + +Merry Christmas! Santa is booting up his weather machine; looks like you might +get a \href{https://adventofcode.com/2015/day/1}{white Christmas} after all. + +The weather machine beeps! On the console of the machine is a copy protection +message asking you to +\href{https://en.wikipedia.org/wiki/Copy_protection\#Early_video_games}{enter a + code from the instruction manual}. Apparently, it refuses to run unless you +give it that code. No problem; you'll just look up the code in the-- + +``Ho ho ho'', Santa ponders aloud. ``I can't seem to find the manual.'' + +You look up the support number for the manufacturer and give them a call. Good +thing, too - that 49th star wasn't going to earn itself. + +``Oh, that machine is quite old!'', they tell you. ``That model went out of +support six minutes ago, and we just finished shredding all of the manuals. I +bet we can find you the code generation algorithm, though.'' + +After putting you on hold for twenty minutes (your call is \textbf{very} +important to them, it reminded you repeatedly), they finally find an engineer +that remembers how the code system works. + +The codes are printed on an infinite sheet of paper\marginnote{The paper is very + thin so it can be folded up neatly into the manual.}, starting in the top-left +corner. The codes are filled in by diagonals: starting with the first row with +an empty first box, the codes are filled in diagonally up and to the right. This +process repeats until the +\href{https://en.wikipedia.org/wiki/Cantor's_diagonal_argument}{infinite paper + is covered}. So, the first few codes are filled in in this order: + +\begin{table}[h] + \centering + \begin{tabular}{r|rrrrrr} + & 1 & 2 & 3 & 4 & 5 & 6 \\ + \midrule + 1 & 1 & 3 & 6 & 10 & 15 & 21 \\ + 2 & 2 & 5 & 9 & 14 & 20 \\ + 3 & 4 & 8 & 13 & 19 \\ + 4 & 7 & 12 & 18 \\ + 5 & 11 & 17 \\ + 6 & 16 + \end{tabular} +\end{table} + +For example, the 12th code would be written to row \hs{4}, column \hs{2}; the +15th code would be written to row \hs{1}, column \hs{5}. + +The voice on the other end of the phone continues with how the codes are +actually generated. The first code is \hs{20151125}. After that, each code is +generated by taking the previous one, multiplying it by \hs{252533}, and then +keeping the remainder from dividing that value by \hs{33554393}. + +So, to find the second code (which ends up in row \hs{2}, column \hs{1}), start +with the previous value, \hs{20151125}. Multiply it by \hs{252533} to get +\hs{5088824049625}. Then, divide that by \hs{33554393}, which leaves a remainder +of \hs{31916031}. That remainder is the second code. + +``Oh!'', says the voice. ``It looks like we missed a scrap from one of the +manuals. Let me read it to you.'' You write down his numbers: + +\begin{table}[h] + \centering + \begin{tabular}{r|rrrrrr} + & 1 & 2 & 3 & 4 & 5 & 6 \\ + \midrule + 1 & 20151125 & 18749137 & 17289845 & 30943339 & 10071777 & 33511524 \\ + 2 & 31916031 & 21629792 & 16929656 & 7726640 & 15514188 & 4041754 \\ + 3 &16080970 & 8057251 & 1601130 & 7981243 & 11661866 & 16474243 \\ + 4 & 24592653 & 32451966 & 21345942 & 9380097 & 10600672 & 31527494 \\ + 5 & 77061 & 17552253 & 28094349 & 6899651 & 9250759 & 31663883 \\ + 6 & 33071741 & 6796745 & 25397450 & 24659492 & 1534922 & 27995004 + \end{tabular} +\end{table} + +\newpage + +``Now remember'', the voice continues, ``that's not even all of the first few +numbers; for example, you're missing the one at 7,1 that would come before +6,2. But, it should be enough to let your-- oh, it's time for lunch! Bye!'' The +call disconnects. + +Santa looks nervous. Your puzzle input contains the message on the machine's +console. \textbf{What code do you give the machine?} + +\newthought{Part Two} + +The machine springs to life, then falls silent again. It beeps. ``Insufficient +fuel'', the console reads. ``\textbf{Fifty stars} are required before +proceeding. \textbf{One star} is available.'' + +...``one star is available''? You check the fuel tank; sure enough, a lone star +sits at the bottom, awaiting its friends. Looks like you need to provide 49 +yourself. diff --git a/_src/2015/haskell/25.nw b/_src/2015/haskell/25.nw new file mode 100644 index 0000000..b5441a3 --- /dev/null +++ b/_src/2015/haskell/25.nw @@ -0,0 +1,155 @@ +\subsection{Haskell solution} + +Rather than try to generate the codes sequentially, which can quickly result in +a stack overflow, make some observations. + +\newthought{The positions in first column} are the +\hrefootnote{https://en.wikipedia.org/wiki/Lazy_caterer's_sequence}{lazy + caterer's sequence}, i.e. \hrefootnote{https://oeis.org/A000124}{A000124 in + The Online Encyclopedia of Integer Sequences}. + +\begin{equation} + a(n) = n \times (n - 1) / 2 + 1 +\end{equation} + +Or equivalently in Haskell: + +<>= +a000124 :: (Integral a) => a -> a +a000124 n = n * (n - 1) `div` 2 + 1 +@ %def a000124 + +Since this problem might involve some rather large numbers, specialize the +polymorphic [[a000124]] to Haskell's arbitrary precision \hs{Integer}, and +ensure the compiler inlines it. + +<>= +{-# SPECIALIZE INLINE a000124 :: Integer -> Integer #-} +@ + +\newthought{Then to calculate the distance} from that position to that of +another column $c$ in the same row $r$, simply subtract the $r$th +\hrefootnote{https://en.wikipedia.org/wiki/Triangular_number}{triangular number} +from the $(c + r - 1)$th. The triangular numbers are known as +\hrefootnote{https://oeis.org/A000217}{A000217 in The Online Encyclopedia of + Integer Sequences}. + +\begin{equation} + T(n) = n \times (n + 1) / 2 +\end{equation} + +Or equivalently in Haskell: + +<>= +a000217 :: (Integral a) => a -> a +a000217 n = n * (n + 1) `div` 2 +@ %def a000217 + +Just as before, specialize to \hs{Integer} and inline. + +<>= +{-# SPECIALIZE INLINE a000217 :: Integer -> Integer #-} +@ + +So, to find the position in the sequence of codes from a given column and row: + +<>= +position = a000124 row + a000217 (column + row - 1) - a000217 row +@ + +\newthought{The generating function} for the sequence is as follows, where $n +\in \mathbb{N}$ is the position. + +\begin{equation} + f(n) = + \begin{cases} + 20151125, & \text{for } n=0 \\ + f(n - 1) \times 252533 \pmod{33554393}, & \text{otherwise} + \end{cases} +\end{equation} + +That recursive definition can be rewritten as a closed formula. + +\begin{equation} + f(n) = 20151125 \times 252533^{n-1} \pmod{33554393} +\end{equation} + +Or equivalently in Haskell: + +<>= +20151125 * (252533 ^ (position - 1)) `mod` 33554393 +@ + +Thus, Part One can be solved by implementing a function that takes a coordinate +pair and returns the specified code. + +<>= +partOne :: Coordinates -> Integer +partOne (column, row) = <> + where + <> +@ %def partOne + +There is nothing to solve for Part Two. + +\newthought{To parse the input}, write a silly, overly explicit \hs{Parser}. + +<>= +import Control.Monad (void) +import Text.Trifecta (Parser, comma, natural, symbol) +@ + +<>= +coordinates :: Parser Coordinates +coordinates = + do + void $ symbol "To continue, please consult the code grid in the manual." + row <- symbol "Enter the code at row" *> natural <* comma + column <- symbol "column" *> natural + pure (column, row) +@ %def coordinates + +[[Coordinates]] is just a two-tuple of \hs{Integer}s. + +<>= +type Coordinates = (Integer, Integer) +@ %def Coordinates + +Define the usual [[getInput]]. + +<>= +import AdventOfCode.Input (parseInput) +import AdventOfCode.TH (inputFilePath) +@ + +<>= +getInput :: IO Coordinates +getInput = parseInput coordinates $(inputFilePath) +@ %def getInput + +\newthought{Bring it} all together. + +<>= +module AdventOfCode.Year2015.Day25 where + +<> +<> + +<> + +main :: IO () +main = + do + putStr "Part One: " + print . partOne =<< getInput + +<> + +<> + +<> + +<> + +<> +@ diff --git a/_src/tex/2015.tex b/_src/tex/2015.tex new file mode 100644 index 0000000..d53153c --- /dev/null +++ b/_src/tex/2015.tex @@ -0,0 +1,272 @@ +\nwfilename{_src/2015/day/25.nw}\nwbegindocs{0}\newpage% ===> this file was generated automatically by noweave --- better not edit it +\section{Day 25: Let It Snow} +\marginnote{\url{https://adventofcode.com/2015/day/25}} + +Merry Christmas! Santa is booting up his weather machine; looks like you might +get a \href{https://adventofcode.com/2015/day/1}{white Christmas} after all. + +The weather machine beeps! On the console of the machine is a copy protection +message asking you to +\href{https://en.wikipedia.org/wiki/Copy_protection\#Early_video_games}{enter a + code from the instruction manual}. Apparently, it refuses to run unless you +give it that code. No problem; you'll just look up the code in the-- + +``Ho ho ho'', Santa ponders aloud. ``I can't seem to find the manual.'' + +You look up the support number for the manufacturer and give them a call. Good +thing, too - that 49th star wasn't going to earn itself. + +``Oh, that machine is quite old!'', they tell you. ``That model went out of +support six minutes ago, and we just finished shredding all of the manuals. I +bet we can find you the code generation algorithm, though.'' + +After putting you on hold for twenty minutes (your call is \textbf{very} +important to them, it reminded you repeatedly), they finally find an engineer +that remembers how the code system works. + +The codes are printed on an infinite sheet of paper\marginnote{The paper is very + thin so it can be folded up neatly into the manual.}, starting in the top-left +corner. The codes are filled in by diagonals: starting with the first row with +an empty first box, the codes are filled in diagonally up and to the right. This +process repeats until the +\href{https://en.wikipedia.org/wiki/Cantor's_diagonal_argument}{infinite paper + is covered}. So, the first few codes are filled in in this order: + +\begin{table}[h] + \centering + \begin{tabular}{r|rrrrrr} + & 1 & 2 & 3 & 4 & 5 & 6 \\ + \midrule + 1 & 1 & 3 & 6 & 10 & 15 & 21 \\ + 2 & 2 & 5 & 9 & 14 & 20 \\ + 3 & 4 & 8 & 13 & 19 \\ + 4 & 7 & 12 & 18 \\ + 5 & 11 & 17 \\ + 6 & 16 + \end{tabular} +\end{table} + +For example, the 12th code would be written to row \hs{4}, column \hs{2}; the +15th code would be written to row \hs{1}, column \hs{5}. + +The voice on the other end of the phone continues with how the codes are +actually generated. The first code is \hs{20151125}. After that, each code is +generated by taking the previous one, multiplying it by \hs{252533}, and then +keeping the remainder from dividing that value by \hs{33554393}. + +So, to find the second code (which ends up in row \hs{2}, column \hs{1}), start +with the previous value, \hs{20151125}. Multiply it by \hs{252533} to get +\hs{5088824049625}. Then, divide that by \hs{33554393}, which leaves a remainder +of \hs{31916031}. That remainder is the second code. + +``Oh!'', says the voice. ``It looks like we missed a scrap from one of the +manuals. Let me read it to you.'' You write down his numbers: + +\begin{table}[h] + \centering + \begin{tabular}{r|rrrrrr} + & 1 & 2 & 3 & 4 & 5 & 6 \\ + \midrule + 1 & 20151125 & 18749137 & 17289845 & 30943339 & 10071777 & 33511524 \\ + 2 & 31916031 & 21629792 & 16929656 & 7726640 & 15514188 & 4041754 \\ + 3 &16080970 & 8057251 & 1601130 & 7981243 & 11661866 & 16474243 \\ + 4 & 24592653 & 32451966 & 21345942 & 9380097 & 10600672 & 31527494 \\ + 5 & 77061 & 17552253 & 28094349 & 6899651 & 9250759 & 31663883 \\ + 6 & 33071741 & 6796745 & 25397450 & 24659492 & 1534922 & 27995004 + \end{tabular} +\end{table} + +\newpage + +``Now remember'', the voice continues, ``that's not even all of the first few +numbers; for example, you're missing the one at 7,1 that would come before +6,2. But, it should be enough to let your-- oh, it's time for lunch! Bye!'' The +call disconnects. + +Santa looks nervous. Your puzzle input contains the message on the machine's +console. \textbf{What code do you give the machine?} + +\newthought{Part Two} + +The machine springs to life, then falls silent again. It beeps. ``Insufficient +fuel'', the console reads. ``\textbf{Fifty stars} are required before +proceeding. \textbf{One star} is available.'' + +...``one star is available''? You check the fuel tank; sure enough, a lone star +sits at the bottom, awaiting its friends. Looks like you need to provide 49 +yourself. +\nwenddocs{}\nwfilename{_src/2015/haskell/25.nw}\nwbegindocs{0}\subsection{Haskell solution} + +Rather than try to generate the codes sequentially, which can quickly result in +a stack overflow, make some observations. + +\newthought{The positions in first column} are the +\hrefootnote{https://en.wikipedia.org/wiki/Lazy_caterer's_sequence}{lazy + caterer's sequence}, i.e. \hrefootnote{https://oeis.org/A000124}{A000124 in + The Online Encyclopedia of Integer Sequences}. + +\begin{equation} + a(n) = n \times (n - 1) / 2 + 1 +\end{equation} + +Or equivalently in Haskell: + +\nwenddocs{}\nwbegincode{1}\sublabel{NW22O72u-2mhKol-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-2mhKol-1}}}\moddef{Define a000124~{\nwtagstyle{}\subpageref{NW22O72u-2mhKol-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwprevnextdefs{\relax}{NW22O72u-2mhKol-2}\nwenddeflinemarkup +\nwlinkedidentc{a000124}{NW22O72u-2mhKol-1} :: (Integral a) => a -> a +\nwlinkedidentc{a000124}{NW22O72u-2mhKol-1} n = n * (n - 1) `div` 2 + 1 +\nwindexdefn{\nwixident{a000124}}{a000124}{NW22O72u-2mhKol-1}\eatline +\nwalsodefined{\\{NW22O72u-2mhKol-2}}\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentdefs{\\{{\nwixident{a000124}}{a000124}}}\nwendcode{}\nwbegindocs{2}\nwdocspar +Since this problem might involve some rather large numbers, specialize the +polymorphic {\Tt{}\nwlinkedidentq{a000124}{NW22O72u-2mhKol-1}\nwendquote} to Haskell's arbitrary precision \hs{Integer}, and +ensure the compiler inlines it. + +\nwenddocs{}\nwbegincode{3}\sublabel{NW22O72u-2mhKol-2}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-2mhKol-2}}}\moddef{Define a000124~{\nwtagstyle{}\subpageref{NW22O72u-2mhKol-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwprevnextdefs{NW22O72u-2mhKol-1}{\relax}\nwenddeflinemarkup +\{-# SPECIALIZE INLINE \nwlinkedidentc{a000124}{NW22O72u-2mhKol-1} :: Integer -> Integer #-\} +\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentuses{\\{{\nwixident{a000124}}{a000124}}}\nwindexuse{\nwixident{a000124}}{a000124}{NW22O72u-2mhKol-2}\nwendcode{}\nwbegindocs{4}\nwdocspar + +\newthought{Then to calculate the distance} from that position to that of +another column $c$ in the same row $r$, simply subtract the $r$th +\hrefootnote{https://en.wikipedia.org/wiki/Triangular_number}{triangular number} +from the $(c + r - 1)$th. The triangular numbers are known as +\hrefootnote{https://oeis.org/A000217}{A000217 in The Online Encyclopedia of + Integer Sequences}. + +\begin{equation} + T(n) = n \times (n + 1) / 2 +\end{equation} + +Or equivalently in Haskell: + +\nwenddocs{}\nwbegincode{5}\sublabel{NW22O72u-QCx5X-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-QCx5X-1}}}\moddef{Define a000217~{\nwtagstyle{}\subpageref{NW22O72u-QCx5X-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwprevnextdefs{\relax}{NW22O72u-QCx5X-2}\nwenddeflinemarkup +\nwlinkedidentc{a000217}{NW22O72u-QCx5X-1} :: (Integral a) => a -> a +\nwlinkedidentc{a000217}{NW22O72u-QCx5X-1} n = n * (n + 1) `div` 2 +\nwindexdefn{\nwixident{a000217}}{a000217}{NW22O72u-QCx5X-1}\eatline +\nwalsodefined{\\{NW22O72u-QCx5X-2}}\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentdefs{\\{{\nwixident{a000217}}{a000217}}}\nwendcode{}\nwbegindocs{6}\nwdocspar +Just as before, specialize to \hs{Integer} and inline. + +\nwenddocs{}\nwbegincode{7}\sublabel{NW22O72u-QCx5X-2}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-QCx5X-2}}}\moddef{Define a000217~{\nwtagstyle{}\subpageref{NW22O72u-QCx5X-1}}}\plusendmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwprevnextdefs{NW22O72u-QCx5X-1}{\relax}\nwenddeflinemarkup +\{-# SPECIALIZE INLINE \nwlinkedidentc{a000217}{NW22O72u-QCx5X-1} :: Integer -> Integer #-\} +\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentuses{\\{{\nwixident{a000217}}{a000217}}}\nwindexuse{\nwixident{a000217}}{a000217}{NW22O72u-QCx5X-2}\nwendcode{}\nwbegindocs{8}\nwdocspar + +So, to find the position in the sequence of codes from a given column and row: + +\nwenddocs{}\nwbegincode{9}\sublabel{NW22O72u-6ilA0-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-6ilA0-1}}}\moddef{Find the position~{\nwtagstyle{}\subpageref{NW22O72u-6ilA0-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-2c4Gzh-1}}\nwenddeflinemarkup +position = \nwlinkedidentc{a000124}{NW22O72u-2mhKol-1} row + \nwlinkedidentc{a000217}{NW22O72u-QCx5X-1} (column + row - 1) - \nwlinkedidentc{a000217}{NW22O72u-QCx5X-1} row +\nwused{\\{NW22O72u-2c4Gzh-1}}\nwidentuses{\\{{\nwixident{a000124}}{a000124}}\\{{\nwixident{a000217}}{a000217}}}\nwindexuse{\nwixident{a000124}}{a000124}{NW22O72u-6ilA0-1}\nwindexuse{\nwixident{a000217}}{a000217}{NW22O72u-6ilA0-1}\nwendcode{}\nwbegindocs{10}\nwdocspar + +\newthought{The generating function} for the sequence is as follows, where $n +\in \mathbb{N}$ is the position. + +\begin{equation} + f(n) = + \begin{cases} + 20151125, & \text{for } n=0 \\ + f(n - 1) \times 252533 \pmod{33554393}, & \text{otherwise} + \end{cases} +\end{equation} + +That recursive definition can be rewritten as a closed formula. + +\begin{equation} + f(n) = 20151125 \times 252533^{n-1} \pmod{33554393} +\end{equation} + +Or equivalently in Haskell: + +\nwenddocs{}\nwbegincode{11}\sublabel{NW22O72u-3sqonN-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-3sqonN-1}}}\moddef{Find the code at a given position~{\nwtagstyle{}\subpageref{NW22O72u-3sqonN-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-2c4Gzh-1}}\nwenddeflinemarkup +20151125 * (252533 ^ (position - 1)) `mod` 33554393 +\nwused{\\{NW22O72u-2c4Gzh-1}}\nwendcode{}\nwbegindocs{12}\nwdocspar + +Thus, Part One can be solved by implementing a function that takes a coordinate +pair and returns the specified code. + +\nwenddocs{}\nwbegincode{13}\sublabel{NW22O72u-2c4Gzh-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-2c4Gzh-1}}}\moddef{Define partOne~{\nwtagstyle{}\subpageref{NW22O72u-2c4Gzh-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwenddeflinemarkup +\nwlinkedidentc{partOne}{NW22O72u-2c4Gzh-1} :: \nwlinkedidentc{Coordinates}{NW22O72u-14h5MM-1} -> Integer +\nwlinkedidentc{partOne}{NW22O72u-2c4Gzh-1} (column, row) = \LA{}Find the code at a given position~{\nwtagstyle{}\subpageref{NW22O72u-3sqonN-1}}\RA{} + where + \LA{}Find the position~{\nwtagstyle{}\subpageref{NW22O72u-6ilA0-1}}\RA{} +\nwindexdefn{\nwixident{partOne}}{partOne}{NW22O72u-2c4Gzh-1}\eatline +\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentdefs{\\{{\nwixident{partOne}}{partOne}}}\nwidentuses{\\{{\nwixident{Coordinates}}{Coordinates}}}\nwindexuse{\nwixident{Coordinates}}{Coordinates}{NW22O72u-2c4Gzh-1}\nwendcode{}\nwbegindocs{14}\nwdocspar +There is nothing to solve for Part Two. + +\newthought{To parse the input}, write a silly, overly explicit \hs{Parser}. + +\nwenddocs{}\nwbegincode{15}\sublabel{NW22O72u-4Uy8SS-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-4Uy8SS-1}}}\moddef{Import tools for parsing the input~{\nwtagstyle{}\subpageref{NW22O72u-4Uy8SS-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwenddeflinemarkup +import Control.Monad (void) +import Text.Trifecta (Parser, comma, natural, symbol) +\nwused{\\{NW22O72u-1XqXnB-1}}\nwendcode{}\nwbegindocs{16}\nwdocspar + +\nwenddocs{}\nwbegincode{17}\sublabel{NW22O72u-3dpu5v-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-3dpu5v-1}}}\moddef{Define coordinates~{\nwtagstyle{}\subpageref{NW22O72u-3dpu5v-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwenddeflinemarkup +\nwlinkedidentc{coordinates}{NW22O72u-3dpu5v-1} :: Parser \nwlinkedidentc{Coordinates}{NW22O72u-14h5MM-1} +\nwlinkedidentc{coordinates}{NW22O72u-3dpu5v-1} = + do + void $ symbol "To continue, please consult the code grid in the manual." + row <- symbol "Enter the code at row" *> natural <* comma + column <- symbol "column" *> natural + pure (column, row) +\nwindexdefn{\nwixident{coordinates}}{coordinates}{NW22O72u-3dpu5v-1}\eatline +\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentdefs{\\{{\nwixident{coordinates}}{coordinates}}}\nwidentuses{\\{{\nwixident{Coordinates}}{Coordinates}}}\nwindexuse{\nwixident{Coordinates}}{Coordinates}{NW22O72u-3dpu5v-1}\nwendcode{}\nwbegindocs{18}\nwdocspar +{\Tt{}\nwlinkedidentq{Coordinates}{NW22O72u-14h5MM-1}\nwendquote} is just a two-tuple of \hs{Integer}s. + +\nwenddocs{}\nwbegincode{19}\sublabel{NW22O72u-14h5MM-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-14h5MM-1}}}\moddef{Define Coordinates~{\nwtagstyle{}\subpageref{NW22O72u-14h5MM-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwenddeflinemarkup +type \nwlinkedidentc{Coordinates}{NW22O72u-14h5MM-1} = (Integer, Integer) +\nwindexdefn{\nwixident{Coordinates}}{Coordinates}{NW22O72u-14h5MM-1}\eatline +\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentdefs{\\{{\nwixident{Coordinates}}{Coordinates}}}\nwendcode{}\nwbegindocs{20}\nwdocspar +Define the usual {\Tt{}\nwlinkedidentq{getInput}{NW22O72u-2tfAyb-1}\nwendquote}. + +\nwenddocs{}\nwbegincode{21}\sublabel{NW22O72u-17Bmws-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-17Bmws-1}}}\moddef{Import some common utilities~{\nwtagstyle{}\subpageref{NW22O72u-17Bmws-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwenddeflinemarkup +import AdventOfCode.Input (parseInput) +import AdventOfCode.TH (inputFilePath) +\nwused{\\{NW22O72u-1XqXnB-1}}\nwendcode{}\nwbegindocs{22}\nwdocspar + +\nwenddocs{}\nwbegincode{23}\sublabel{NW22O72u-2tfAyb-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-2tfAyb-1}}}\moddef{Define getInput~{\nwtagstyle{}\subpageref{NW22O72u-2tfAyb-1}}}\endmoddef\nwstartdeflinemarkup\nwusesondefline{\\{NW22O72u-1XqXnB-1}}\nwenddeflinemarkup +\nwlinkedidentc{getInput}{NW22O72u-2tfAyb-1} :: IO \nwlinkedidentc{Coordinates}{NW22O72u-14h5MM-1} +\nwlinkedidentc{getInput}{NW22O72u-2tfAyb-1} = parseInput \nwlinkedidentc{coordinates}{NW22O72u-3dpu5v-1} $(inputFilePath) +\nwindexdefn{\nwixident{getInput}}{getInput}{NW22O72u-2tfAyb-1}\eatline +\nwused{\\{NW22O72u-1XqXnB-1}}\nwidentdefs{\\{{\nwixident{getInput}}{getInput}}}\nwidentuses{\\{{\nwixident{Coordinates}}{Coordinates}}\\{{\nwixident{coordinates}}{coordinates}}}\nwindexuse{\nwixident{Coordinates}}{Coordinates}{NW22O72u-2tfAyb-1}\nwindexuse{\nwixident{coordinates}}{coordinates}{NW22O72u-2tfAyb-1}\nwendcode{}\nwbegindocs{24}\nwdocspar +\newthought{Bring it} all together. + +\nwenddocs{}\nwbegincode{25}\sublabel{NW22O72u-1XqXnB-1}\nwmargintag{{\nwtagstyle{}\subpageref{NW22O72u-1XqXnB-1}}}\moddef{Day25.hs~{\nwtagstyle{}\subpageref{NW22O72u-1XqXnB-1}}}\endmoddef\nwstartdeflinemarkup\nwenddeflinemarkup +module AdventOfCode.Year2015.Day25 where + +\LA{}Import some common utilities~{\nwtagstyle{}\subpageref{NW22O72u-17Bmws-1}}\RA{} +\LA{}Import tools for parsing the input~{\nwtagstyle{}\subpageref{NW22O72u-4Uy8SS-1}}\RA{} + +\LA{}Define Coordinates~{\nwtagstyle{}\subpageref{NW22O72u-14h5MM-1}}\RA{} + +main :: IO () +main = + do + putStr "Part One: " + print . \nwlinkedidentc{partOne}{NW22O72u-2c4Gzh-1} =<< \nwlinkedidentc{getInput}{NW22O72u-2tfAyb-1} + +\LA{}Define partOne~{\nwtagstyle{}\subpageref{NW22O72u-2c4Gzh-1}}\RA{} + +\LA{}Define getInput~{\nwtagstyle{}\subpageref{NW22O72u-2tfAyb-1}}\RA{} + +\LA{}Define coordinates~{\nwtagstyle{}\subpageref{NW22O72u-3dpu5v-1}}\RA{} + +\LA{}Define a000124~{\nwtagstyle{}\subpageref{NW22O72u-2mhKol-1}}\RA{} + +\LA{}Define a000217~{\nwtagstyle{}\subpageref{NW22O72u-QCx5X-1}}\RA{} +\nwnotused{Day25.hs}\nwidentuses{\\{{\nwixident{getInput}}{getInput}}\\{{\nwixident{partOne}}{partOne}}}\nwindexuse{\nwixident{getInput}}{getInput}{NW22O72u-1XqXnB-1}\nwindexuse{\nwixident{partOne}}{partOne}{NW22O72u-1XqXnB-1}\nwendcode{}\nwbegindocs{26}\nwdocspar +\nwenddocs{} + +\nwixlogsorted{c}{{Day25.hs}{NW22O72u-1XqXnB-1}{\nwixd{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Define a000124}{NW22O72u-2mhKol-1}{\nwixd{NW22O72u-2mhKol-1}\nwixd{NW22O72u-2mhKol-2}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Define a000217}{NW22O72u-QCx5X-1}{\nwixd{NW22O72u-QCx5X-1}\nwixd{NW22O72u-QCx5X-2}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Define Coordinates}{NW22O72u-14h5MM-1}{\nwixd{NW22O72u-14h5MM-1}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Define coordinates}{NW22O72u-3dpu5v-1}{\nwixd{NW22O72u-3dpu5v-1}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Define getInput}{NW22O72u-2tfAyb-1}{\nwixd{NW22O72u-2tfAyb-1}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Define partOne}{NW22O72u-2c4Gzh-1}{\nwixd{NW22O72u-2c4Gzh-1}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Find the code at a given position}{NW22O72u-3sqonN-1}{\nwixd{NW22O72u-3sqonN-1}\nwixu{NW22O72u-2c4Gzh-1}}}% +\nwixlogsorted{c}{{Find the position}{NW22O72u-6ilA0-1}{\nwixd{NW22O72u-6ilA0-1}\nwixu{NW22O72u-2c4Gzh-1}}}% +\nwixlogsorted{c}{{Import some common utilities}{NW22O72u-17Bmws-1}{\nwixd{NW22O72u-17Bmws-1}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{c}{{Import tools for parsing the input}{NW22O72u-4Uy8SS-1}{\nwixd{NW22O72u-4Uy8SS-1}\nwixu{NW22O72u-1XqXnB-1}}}% +\nwixlogsorted{i}{{\nwixident{a000124}}{a000124}}% +\nwixlogsorted{i}{{\nwixident{a000217}}{a000217}}% +\nwixlogsorted{i}{{\nwixident{Coordinates}}{Coordinates}}% +\nwixlogsorted{i}{{\nwixident{coordinates}}{coordinates}}% +\nwixlogsorted{i}{{\nwixident{getInput}}{getInput}}% +\nwixlogsorted{i}{{\nwixident{partOne}}{partOne}}% + diff --git a/_src/tex/2018.tex b/_src/tex/2018.tex index 027efc0..79f8a40 100644 --- a/_src/tex/2018.tex +++ b/_src/tex/2018.tex @@ -173,3 +173,4 @@ \section{Day 2: Inventory Management System} \nwixlogsorted{i}{{\nwixident{FrequencyChange}}{FrequencyChange}}% \nwixlogsorted{i}{{\nwixident{partOne}}{partOne}}% \nwixlogsorted{i}{{\nwixident{partTwo}}{partTwo}}% + diff --git a/_src/tex/2019.tex b/_src/tex/2019.tex index 7e305d8..dda1285 100644 --- a/_src/tex/2019.tex +++ b/_src/tex/2019.tex @@ -307,3 +307,4 @@ \section{Day 8: }\todor{Add missing title} \nwixlogsorted{i}{{\nwixident{Transparent}}{Transparent}}% \nwixlogsorted{i}{{\nwixident{transparentLayer}}{transparentLayer}}% \nwixlogsorted{i}{{\nwixident{White}}{White}}% + diff --git a/_src/tex/2021.tex b/_src/tex/2021.tex index b19f1a5..37a57f9 100644 --- a/_src/tex/2021.tex +++ b/_src/tex/2021.tex @@ -351,3 +351,4 @@ \subsection{Haskell solution} \nwixlogsorted{i}{{\nwixident{partTwo}}{partTwo}}% \nwixlogsorted{i}{{\nwixident{solve}}{solve}}% \nwixlogsorted{i}{{\nwixident{up}}{up}}% + diff --git a/_src/tex/aoc.tex b/_src/tex/aoc.tex index d8ccddc..5cd9900 100644 --- a/_src/tex/aoc.tex +++ b/_src/tex/aoc.tex @@ -13,6 +13,9 @@ \mainmatter \newpage +\chapter{2015} +\input{2015} + \chapter{2018} \input{2018} diff --git a/_src/tex/preamble.tex b/_src/tex/preamble.tex index eebf2d9..1c1e414 100644 --- a/_src/tex/preamble.tex +++ b/_src/tex/preamble.tex @@ -105,4 +105,7 @@ %% \usepackage{tikz} +\usepackage{booktabs} + + \author{Eric Bailey} diff --git a/docs/aoc.pdf b/docs/aoc.pdf index e26a761..6197992 100644 Binary files a/docs/aoc.pdf and b/docs/aoc.pdf differ diff --git a/nix/noweb.nix b/nix/noweb.nix index 261c2bd..d1098cd 100644 --- a/nix/noweb.nix +++ b/nix/noweb.nix @@ -14,6 +14,7 @@ inherit (final) noweb; # Packages for Noweb inherit (prev.texlive) + booktabs braket catchfile datatool diff --git a/src/AdventOfCode/Year2015/Day25.hs b/src/AdventOfCode/Year2015/Day25.hs index 9bab352..6b59e5f 100644 --- a/src/AdventOfCode/Year2015/Day25.hs +++ b/src/AdventOfCode/Year2015/Day25.hs @@ -14,9 +14,9 @@ main = print . partOne =<< getInput partOne :: Coordinates -> Integer -partOne (column, row) = 20151125 * (252533 ^ (n - 1)) `mod` 33554393 +partOne (column, row) = 20151125 * (252533 ^ (position - 1)) `mod` 33554393 where - n = a000124 row + a000217 (column + row - 1) - a000217 row + position = a000124 row + a000217 (column + row - 1) - a000217 row getInput :: IO Coordinates getInput = parseInput coordinates $(inputFilePath) @@ -29,14 +29,10 @@ coordinates = column <- symbol "column" *> natural pure (column, row) --- https://oeis.org/A000124 --- https://en.wikipedia.org/wiki/Lazy_caterer's_sequence a000124 :: (Integral a) => a -> a a000124 n = n * (n - 1) `div` 2 + 1 {-# SPECIALIZE INLINE a000124 :: Integer -> Integer #-} --- https://oeis.org/A000217 --- https://en.wikipedia.org/wiki/Triangular_number a000217 :: (Integral a) => a -> a a000217 n = n * (n + 1) `div` 2 {-# SPECIALIZE INLINE a000217 :: Integer -> Integer #-}