├── .gitignore ├── LICENSE ├── README.md ├── Setup.hs ├── aoc2017.cabal ├── app ├── Day11Main.hs ├── Day14Main.hs └── Main.lhs ├── bench └── Main.hs ├── colormaps.yaml ├── day1.txt ├── day10.txt ├── day11.txt ├── day12.txt ├── day13.txt ├── day14.txt ├── day15.txt ├── day16.txt ├── day17.txt ├── day18.txt ├── day19.txt ├── day2.txt ├── day20.txt ├── day21.txt ├── day22.txt ├── day23.txt ├── day24.txt ├── day25.txt ├── day3.txt ├── day4.txt ├── day5.txt ├── day6.txt ├── day7.txt ├── day8.txt ├── day9.txt ├── packages ├── growarray │ ├── growarray.cabal │ ├── src │ │ └── GrowArray.hs │ └── test │ │ ├── GrowArraySpec.hs │ │ └── Main.hs ├── lcg │ ├── bench │ │ └── Main.hs │ ├── lcg.cabal │ ├── src │ │ ├── LCGMatches.hs │ │ └── LinearCongruentialGenerator.hs │ └── test │ │ ├── LinearCongruentialGeneratorSpec.hs │ │ └── Main.hs └── morton │ ├── morton.cabal │ ├── src │ └── Morton.hs │ └── test │ ├── Main.hs │ └── MortonSpec.hs ├── src ├── Day1.hs ├── Day10.hs ├── Day11.hs ├── Day12.hs ├── Day13.hs ├── Day14.hs ├── Day15.hs ├── Day16.hs ├── Day17.hs ├── Day18.hs ├── Day19.hs ├── Day2.hs ├── Day20.hs ├── Day21.hs ├── Day22.hs ├── Day23.hs ├── Day24.hs ├── Day25.hs ├── Day3.hs ├── Day4.hs ├── Day5.hs ├── Day6.hs ├── Day7.hs ├── Day8.hs └── Day9.hs ├── stack.yaml └── test ├── Day10Spec.hs ├── Day11Spec.hs ├── Day12Spec.hs ├── Day13Spec.hs ├── Day14Spec.hs ├── Day15Spec.hs ├── Day16Spec.hs ├── Day17Spec.hs ├── Day18Spec.hs ├── Day19Spec.hs ├── Day1Spec.hs ├── Day20Spec.hs ├── Day21Spec.hs ├── Day22Spec.hs ├── Day24Spec.hs ├── Day25Spec.hs ├── Day2Spec.hs ├── Day3Spec.hs ├── Day4Spec.hs ├── Day5Spec.hs ├── Day6Spec.hs ├── Day7Spec.hs ├── Day8Spec.hs ├── Day9Spec.hs └── Main.hs /.gitignore: -------------------------------------------------------------------------------- 1 | **/.stack-work 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Daniel Lin (c) 2017 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Daniel Lin nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | app/Main.lhs -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /aoc2017.cabal: -------------------------------------------------------------------------------- 1 | name: aoc2017 2 | version: 0.1.0.0 3 | synopsis: Advent of Code 2017 - my answers 4 | homepage: https://github.com/ephemient/aoc2017#readme 5 | license: BSD3 6 | license-file: LICENSE 7 | author: Daniel Lin 8 | maintainer: ephemient@gmail.com 9 | build-type: Simple 10 | extra-source-files: README.md 11 | data-files: day1.txt, day2.txt, day3.txt, day4.txt, day5.txt, day6.txt, day7.txt, day8.txt, day9.txt, day10.txt, day11.txt, day12.txt, day13.txt, day14.txt, day15.txt, day16.txt, day17.txt, day18.txt, day19.txt, day20.txt, day21.txt, day22.txt, day23.txt, day24.txt, day25.txt 12 | , colormaps.yaml 13 | cabal-version: >=1.10 14 | 15 | -- To avoid duplicated efforts in documentation and dealing with the 16 | -- complications of embedding Haddock markup inside cabal files, it is 17 | -- common to point users to the README.md file. 18 | description: Please see the README on Github at 19 | 20 | library 21 | hs-source-dirs: src 22 | exposed-modules: Day1, Day2, Day3, Day4, Day5, Day6, Day7, Day8, Day9, Day10, Day11, Day12, Day13, Day14, Day15, Day16, Day17, Day18, Day19, Day20, Day21, Day22, Day23, Day24, Day25 23 | build-depends: base >= 4.7 && < 5 24 | , growarray 25 | , lcg 26 | , morton 27 | , arithmoi 28 | , array 29 | , containers 30 | , mtl 31 | , parallel 32 | , primitive 33 | , split 34 | , vector 35 | default-language: Haskell2010 36 | 37 | executable aoc2017-exe 38 | hs-source-dirs: app 39 | main-is: Main.lhs 40 | ghc-options: -threaded -rtsopts -with-rtsopts=-N -pgmL markdown-unlit 41 | build-depends: base 42 | , markdown-unlit 43 | , aoc2017 44 | other-modules: Paths_aoc2017 45 | default-language: Haskell2010 46 | 47 | executable aoc2017-day11 48 | hs-source-dirs: app 49 | main-is: Day11Main.hs 50 | ghc-options: -threaded -rtsopts -with-rtsopts=-N -main-is Day11Main 51 | build-depends: base 52 | , aoc2017 53 | , JuicyPixels 54 | , primitive 55 | , unordered-containers 56 | , scientific 57 | , vector 58 | , yaml 59 | other-modules: Paths_aoc2017 60 | default-language: Haskell2010 61 | 62 | executable aoc2017-day14 63 | hs-source-dirs: app 64 | main-is: Day14Main.hs 65 | ghc-options: -threaded -rtsopts -with-rtsopts=-N -main-is Day14Main 66 | build-depends: base 67 | , aoc2017 68 | , JuicyPixels 69 | , array 70 | , unordered-containers 71 | , scientific 72 | , vector 73 | , yaml 74 | other-modules: Paths_aoc2017 75 | default-language: Haskell2010 76 | other-modules: Paths_aoc2017 77 | default-language: Haskell2010 78 | 79 | test-suite aoc2017-test 80 | type: exitcode-stdio-1.0 81 | hs-source-dirs: test 82 | main-is: Main.hs 83 | build-depends: base 84 | , aoc2017 85 | , hspec 86 | other-modules: Day1Spec, Day2Spec, Day3Spec, Day4Spec, Day5Spec, Day6Spec, Day7Spec, Day8Spec, Day9Spec, Day10Spec, Day11Spec, Day12Spec, Day13Spec, Day14Spec, Day15Spec, Day16Spec, Day17Spec, Day18Spec, Day19Spec, Day20Spec, Day21Spec, Day22Spec, Day24Spec, Day25Spec 87 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 88 | default-language: Haskell2010 89 | 90 | benchmark aoc2017-bench 91 | type: exitcode-stdio-1.0 92 | hs-source-dirs: bench 93 | main-is: Main.hs 94 | build-depends: base 95 | , aoc2017 96 | , criterion 97 | other-modules: Paths_aoc2017 98 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 99 | default-language: Haskell2010 100 | 101 | source-repository head 102 | type: git 103 | location: https://github.com/ephemient/aoc2017 104 | -------------------------------------------------------------------------------- /app/Day11Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings, RecordWildCards #-} 2 | module Day11Main (main) where 3 | 4 | import Codec.Picture (writePng) 5 | import Codec.Picture.Types (MutableImage, Pixel, Pixel8, PixelRGB8(..), createMutableImage, freezeImage, writePixel) 6 | import Control.Monad (forM_) 7 | import Control.Monad.Primitive (PrimMonad, PrimState) 8 | import qualified Data.HashMap.Lazy as M ((!)) 9 | import Data.Scientific (toRealFloat) 10 | import qualified Data.Vector as V ((!), length) 11 | import Data.Yaml (Value(..), decodeFileEither, prettyPrintParseException) 12 | import Day11 (Chart(..), chart) 13 | import Paths_aoc2017 (getDataFileName) 14 | import Text.Printf (printf) 15 | 16 | hexagonSpacing, hexagonRadius :: Double 17 | hexagonSpacing = 1 18 | hexagonRadius = 8 19 | 20 | background :: (Pixel px, PrimMonad m) => 21 | ((Int, Int), (Int, Int)) -> px -> m (MutableImage (PrimState m) px) 22 | background ((minX, minY), (maxX, maxY)) = createMutableImage width height where 23 | xSpan = fromIntegral $ maxX - minX 24 | ySpan = fromIntegral $ maxY - minY 25 | width = ceiling $ xSpan * sqrt 3 * hexagonSpacing + 2 * hexagonRadius 26 | height = ceiling $ ySpan * hexagonSpacing + 2 * hexagonRadius 27 | 28 | drawHexagon :: (Pixel px, PrimMonad m) => MutableImage (PrimState m) px -> 29 | ((Int, Int), (Int, Int)) -> (Int, Int) -> px -> m () 30 | drawHexagon image ((minX, minY), (maxX, maxY)) (x, y) color = 31 | let dx = fromIntegral $ x - minX 32 | dy = fromIntegral $ maxY - y 33 | cx = dx * sqrt 3 * hexagonSpacing + hexagonRadius 34 | cy = dy * hexagonSpacing + hexagonRadius 35 | in sequence_ 36 | [ writePixel image i j color 37 | | i <- [ceiling (cx - hexagonRadius) .. floor (cx + hexagonRadius)] 38 | , let h = sqrt $ hexagonRadius ^ 2 - (cx - fromIntegral i) ^ 2 39 | , j <- [ceiling (cy - h) .. floor (cy + h)] 40 | ] 41 | 42 | main :: IO () 43 | main = do 44 | let getViridis (Object colormaps) = colormaps M.! "viridis" 45 | Array colors <- getDataFileName "colormaps.yaml" >>= 46 | fmap (either (error . prettyPrintParseException) getViridis) . 47 | decodeFileEither 48 | Chart {..} <- getDataFileName "day11.txt" >>= fmap chart . readFile 49 | image <- background bounds $ PixelRGB8 maxBound maxBound maxBound 50 | let colorIx d = fromIntegral d / fromIntegral maxDistance * 51 | fromIntegral (V.length colors) 52 | color d = PixelRGB8 (part 0) (part 1) (part 2) where 53 | idx = max 0 . min (V.length colors - 1) . floor $ colorIx d 54 | Array rgb = colors V.! idx 55 | part c = floor $ toRealFloat n * fromIntegral (maxBound :: Pixel8) 56 | where Number n = rgb V.! c 57 | writeImage i = freezeImage image >>= 58 | writePng (printf "day11-%04d.png" (i :: Int)) 59 | forM_ (zip [0..] path) $ \(idx, (pos, d)) -> 60 | drawHexagon image bounds pos (color d) >> writeImage idx 61 | -------------------------------------------------------------------------------- /app/Day14Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | module Day14Main (main) where 3 | 4 | import Codec.Picture (writePng) 5 | import Codec.Picture.Types (Image, Pixel, Pixel8, PixelRGB8(..), createMutableImage, freezeImage, writePixel) 6 | import Control.Monad (zipWithM_) 7 | import Control.Monad.ST (runST) 8 | import Data.Array.IArray (listArray) 9 | import Data.Array.Unboxed (UArray) 10 | import qualified Data.HashMap.Lazy as M ((!)) 11 | import Data.List (scanl', sortOn, transpose) 12 | import Data.Maybe (isJust) 13 | import Data.Scientific (toRealFloat) 14 | import Data.Tuple (swap) 15 | import qualified Data.Vector as V ((!), length) 16 | import Data.Word (Word8) 17 | import Data.Yaml (Value(..), decodeFileEither, prettyPrintParseException) 18 | import Day10 (deriveKey, knotRanges, reverseRange, xorEach) 19 | import Day14 (groupedBits) 20 | import Paths_aoc2017 (getDataFileName) 21 | import Text.Printf (printf) 22 | 23 | scale :: Int 24 | scale = 4 25 | 26 | drawImage :: (Pixel px) => 27 | px -> (Int -> Int -> px) -> [[(Int, Int)]] -> Image px 28 | drawImage bg color groups = runST $ do 29 | image <- createMutableImage (128 * scale) (128 * scale) bg 30 | sequence_ $ do 31 | (d, group) <- zip [0 :: Int ..] $ sortOn (minimum . map swap) groups 32 | (x, y) <- group 33 | writePixel image <$> [x * scale .. (x + 1) * scale - 1] <*> 34 | [y * scale .. (y + 1) * scale - 1] <*> [color d $ length groups - 1] 35 | freezeImage image 36 | 37 | main :: IO () 38 | main = do 39 | let getViridis (Object colormaps) = colormaps M.! "viridis" 40 | Array colors <- getDataFileName "colormaps.yaml" >>= 41 | fmap (either (error . prettyPrintParseException) getViridis) . 42 | decodeFileEither 43 | input <- getDataFileName "day14.txt" >>= readFile 44 | let white = PixelRGB8 255 255 255 45 | color d n = PixelRGB8 (part 0) (part 1) (part 2) where 46 | idx = max 0 . min (V.length colors - 1) . floor $ 47 | fromIntegral d / fromIntegral n * fromIntegral (V.length colors) 48 | Array rgb = colors V.! idx 49 | part c = floor $ toRealFloat n * fromIntegral (maxBound :: Pixel8) 50 | where Number n = rgb V.! c 51 | keys = [deriveKey $ input ++ "-" ++ show i | i <- [0..127]] 52 | ranges = takeWhile (any isJust) $ transpose 53 | [knotRanges (0, 255) key ++ repeat Nothing | key <- keys] 54 | empty = replicate 128 $ listArray (0, 255) [0..] :: [UArray Int Word8] 55 | states = scanl' (zipWith $ maybe <*> reverseRange) empty ranges 56 | zipWithM_ writePng (printf "day14-%04d.png" <$> [0 :: Int ..]) $ 57 | drawImage white color . groupedBits . map (xorEach 16) <$> states 58 | -------------------------------------------------------------------------------- /app/Main.lhs: -------------------------------------------------------------------------------- 1 | # [Advent of Code 2017](http://adventofcode.com/2017) 2 | ### my answers in [Haskell](https://www.haskell.org/) 3 | 4 | This project builds with [The Haskell Tool Stack](https://haskellstack.org/). 5 | 6 | Setup: 7 | 8 | ```sh 9 | curl -sSL https://get.haskellstack.org/ | sh -s - 10 | stack setup 11 | ``` 12 | 13 | > If you encounter 14 | > [linker errors](https://github.com/commercialhaskell/stack/issues/2712) with 15 | > the commands below, try `stack setup --ghc-build=nopie` or adding 16 | > 17 | > ```yaml 18 | > ghc-build: nopie 19 | > ``` 20 | > 21 | > to `~/.stack/config.yaml`. 22 | 23 | Run the [HSpec](https://hspec.github.io/) test suite: 24 | 25 | ```sh 26 | stack test aoc2017:test:aoc2017-test 27 | ``` 28 | 29 | Run [criterion](http://www.serpentine.com/criterion/) benchmarks: 30 | 31 | ```sh 32 | stack bench aoc2017:bench:aoc2017-bench 33 | ``` 34 | 35 | Print solutions for the inputs provided in local data files: 36 | 37 | ```sh 38 | stack build aoc2017:exe:aoc2017-exe 39 | stack exec aoc2017-exe 40 | ``` 41 | 42 | Animate the Day 11 path (rendered at 43 | [Gyfcat](https://gfycat.com/UnnaturalSourFiddlercrab)): 44 | 45 | ```sh 46 | stack build aoc2017:exe:aoc2017-day11 47 | stack exec aoc2017-day11 48 | ffmpeg -vf lavfi -i nullsrc=s=$(identify day11-0000.png | cut -d' ' -f3):d=30 -framerate 300 -i 'day11-%04d.png' -vf '[0:v][1:v]overlay[video]' -map '[video]' -r 60 -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level 3.0 -movflags +faststart -y day11.mp4 49 | ``` 50 | 51 | Animate the Day 14 grid (rendered at 52 | [Gyfcat](https://gfycat.com/AdventurousUnconsciousKarakul)): 53 | 54 | ```sh 55 | stack build aoc2017:exe:aoc2017-day14 56 | stack exec aoc2017-day14 57 | ffmpeg -framerate 60 -i 'day11-%04d.png' -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level 3.0 -movflags +faststart -y day11.mp4 58 | ``` 59 | 60 | Generate [Haddock](https://www.haskell.org/haddock/) API documentation 61 | (rendered at [ephemient.github.io/aoc2017](https://ephemient.github.io/aoc2017)): 62 | 63 | ```sh 64 | stack haddock aoc2017:lib 65 | ``` 66 | 67 | --- 68 | 69 | 75 | 76 | ## [Day 1: Inverse Captcha](/src/Day1.hs) 77 | ```haskell 78 | import Day1 (day1a, day1b) 79 | ``` 80 | ## [Day 2: Corruption Checksum](/src/Day2.hs) 81 | ```haskell 82 | import Day2 (day2a, day2b) 83 | ``` 84 | ## [Day 3: Spiral Memory](/src/Day3.hs) 85 | ```haskell 86 | import Day3 (day3a, day3b) 87 | ``` 88 | ## [Day 4: High-Entropy Passphrases](/src/Day4.hs) 89 | ```haskell 90 | import Day4 (day4a, day4b) 91 | ``` 92 | ## [Day 5: A Maze of Twisty Trampolines, All Alike](/src/Day5.hs) 93 | ```haskell 94 | import Day5 (day5a, day5b) 95 | ``` 96 | ## [Day 6: Memory Reallocation](/src/Day6.hs) 97 | ```haskell 98 | import Day6 (day6a, day6b) 99 | ``` 100 | ## [Day 7: Recursive Circus](/src/Day7.hs) 101 | ```haskell 102 | import Day7 (day7a, day7b) 103 | ``` 104 | ## [Day 8: I Heard You Like Registers](/src/Day8.hs) 105 | ```haskell 106 | import Day8 (day8a, day8b) 107 | ``` 108 | ## [Day 9: Stream Processing](/src/Day9.hs) 109 | ```haskell 110 | import Day9 (day9a, day9b) 111 | ``` 112 | ## [Day 10: Knot Hash](/src/Day10.hs) 113 | ```haskell 114 | import Day10 (day10a, day10b) 115 | ``` 116 | ## [Day 11: Hex Ed](/src/Day11.hs) 117 | ```haskell 118 | import Day11 (day11a, day11b) 119 | ``` 120 | ## [Day 12: Digital Plumber](/src/Day12.hs) 121 | ```haskell 122 | import Day12 (day12a, day12b) 123 | ``` 124 | ## [Day 13: Packet Scanners](/src/Day13.hs) 125 | ```haskell 126 | import Day13 (day13a, day13b) 127 | ``` 128 | ## [Day 14: Disk Defragmentation](/src/Day14.hs) 129 | ```haskell 130 | import Day14 (day14a, day14b) 131 | ``` 132 | ## [Day 15: Dueling Generators](/src/Day15.hs) 133 | ```haskell 134 | import Day15 (day15a, day15b) 135 | ``` 136 | ## [Day 16: Permutation Promenade](/src/Day16.hs) 137 | ```haskell 138 | import Day16 (day16a, day16b) 139 | ``` 140 | ## [Day 17: Spinlock](/src/Day17.hs) 141 | ```haskell 142 | import Day17 (day17a, day17b) 143 | ``` 144 | ## [Day 18: Duet](/src/Day18.hs) 145 | ```haskell 146 | import Day18 (day18a, day18b) 147 | ``` 148 | ## [Day 19: A Series of Tubes](/src/Day19.hs) 149 | ```haskell 150 | import Day19 (day19a, day19b) 151 | ``` 152 | ## [Day 20: Particle Swarm](/src/Day20.hs) 153 | ```haskell 154 | import Day20 (day20a, day20b) 155 | ``` 156 | ## [Day 21: Fractal Art](/src/Day21.hs) 157 | ```haskell 158 | import Day21 (day21a, day21b) 159 | ``` 160 | ## [Day 22: Sporifica Virus](/src/Day22.hs) 161 | ```haskell 162 | import Day22 (day22a, day22b) 163 | ``` 164 | ## [Day 23: Coprocessor Conflagration](/src/Day23.hs) 165 | ```haskell 166 | import Day23 (day23a, day23b) 167 | ``` 168 | ## [Day 24: Electromagnetic Moat](/src/Day24.hs) 169 | ```haskell 170 | import Day24 (day24a, day24b) 171 | ``` 172 | ## [Day 25: The Halting Problem](/src/Day25.hs) 173 | ```haskell 174 | import Day25 (day25) 175 | ``` 176 | 177 | --- 178 | 179 | ```haskell 180 | import Control.Monad (when) 181 | import Data.Maybe (mapMaybe) 182 | import Paths_aoc2017 (getDataFileName) 183 | import System.Environment (getArgs) 184 | import Text.Read (readMaybe) 185 | 186 | getDayInput :: Int -> IO String 187 | getDayInput i = getDataFileName ("day" ++ show i ++ ".txt") >>= readFile 188 | 189 | readDayInput :: (Read a) => Int -> IO a 190 | readDayInput = fmap read . getDayInput 191 | 192 | maybeBottom :: (a -> String) -> Maybe a -> String 193 | maybeBottom = maybe "(⊥)" 194 | 195 | showError :: (Show a) => (b -> String) -> Either a b -> String 196 | showError = either (\err -> "(" ++ show err ++ ")") 197 | 198 | run :: Int -> (Int -> IO a) -> (b -> IO ()) -> [a -> b] -> IO () 199 | run day readIO showIO funcs = do 200 | days <- mapMaybe readMaybe <$> getArgs 201 | when (null days || day `elem` days) $ do 202 | putStrLn $ "Day " ++ show day 203 | contents <- readIO day 204 | mapM_ (showIO . ($ contents)) funcs 205 | putStrLn "" 206 | 207 | main :: IO () 208 | main = do 209 | run 1 getDayInput print [day1a, day1b] 210 | run 2 getDayInput print [day2a, day2b] 211 | run 3 readDayInput print [day3a, day3b] 212 | run 4 getDayInput print [day4a, day4b] 213 | run 5 getDayInput print [day5a, day5b] 214 | run 6 getDayInput (putStrLn . maybeBottom show) [day6a, day6b] 215 | run 7 getDayInput (putStrLn . maybeBottom id) [day7a, fmap show . day7b] 216 | run 8 getDayInput print [day8a, day8b] 217 | run 9 getDayInput print [day9a, day9b] 218 | run 10 getDayInput putStrLn [show . day10a 256, day10b] 219 | run 11 getDayInput print [day11a, day11b] 220 | run 12 getDayInput print [day12a, day12b] 221 | run 13 getDayInput print [day13a, day13b] 222 | run 14 getDayInput print [day14a, day14b] 223 | run 15 getDayInput print [day15a, day15b] 224 | run 16 getDayInput putStrLn [day16a 16, day16b 16 1000000000] 225 | run 17 readDayInput print [day17a, day17b] 226 | run 18 getDayInput print [fromIntegral . day18a, day18b] 227 | run 19 getDayInput putStrLn [day19a, show . day19b] 228 | run 20 getDayInput print [day20a, length . day20b] 229 | run 21 getDayInput print [day21a, day21b] 230 | run 22 getDayInput print [day22a, day22b] 231 | run 23 getDayInput print [day23a, day23b] 232 | run 24 getDayInput print [day24a, day24b] 233 | run 25 getDayInput print [day25] 234 | ``` 235 | -------------------------------------------------------------------------------- /bench/Main.hs: -------------------------------------------------------------------------------- 1 | module Main (main) where 2 | 3 | import Criterion.Main (bench, bgroup, defaultMain, env, nf) 4 | import Day1 (day1a, day1b) 5 | import Day2 (day2a, day2b) 6 | import Day3 (day3a, day3b) 7 | import Day4 (day4a, day4b) 8 | import Day5 (day5a, day5b) 9 | import Day6 (day6a, day6b) 10 | import Day7 (day7a, day7b) 11 | import Day8 (day8a, day8b) 12 | import Day9 (day9a, day9b) 13 | import Day10 (day10a, day10b) 14 | import Day11 (day11a, day11b) 15 | import Day12 (day12a, day12b) 16 | import Day13 (day13a, day13b) 17 | import Day14 (day14a, day14b) 18 | import Day15 (day15a, day15b) 19 | import Day16 (day16a, day16b) 20 | import Day17 (day17a, day17b) 21 | import Day18 (day18a, day18b) 22 | import Day19 (day19a, day19b) 23 | import Day20 (day20a, day20b) 24 | import Day21 (day21a, day21b) 25 | import Day22 (day22a, day22b) 26 | import Day23 (day23a, day23b) 27 | import Day24 (day24a, day24b) 28 | import Day25 (day25) 29 | import Paths_aoc2017 (getDataFileName) 30 | 31 | getDayInput :: Int -> IO String 32 | getDayInput i = getDataFileName ("day" ++ show i ++ ".txt") >>= readFile 33 | 34 | readDayInput :: (Read a) => Int -> IO a 35 | readDayInput = fmap read . getDayInput 36 | 37 | main :: IO () 38 | main = defaultMain 39 | [ env (getDayInput 1) $ \input -> bgroup "Day 1" 40 | [ bench "part 1" $ nf day1a input 41 | , bench "part 2" $ nf day1b input 42 | ] 43 | , env (getDayInput 2) $ \input -> bgroup "Day 2" 44 | [ bench "part 1" $ nf day2a input 45 | , bench "part 2" $ nf day2b input 46 | ] 47 | , env (readDayInput 3) $ \input -> bgroup "Day 3" 48 | [ bench "part 1" $ nf day3a input 49 | , bench "part 2" $ nf day3b input 50 | ] 51 | , env (getDayInput 4) $ \input -> bgroup "Day 4" 52 | [ bench "part 1" $ nf day4a input 53 | , bench "part 2" $ nf day4b input 54 | ] 55 | , env (getDayInput 5) $ \input -> bgroup "Day 5" 56 | [ bench "part 1" $ nf day5a input 57 | , bench "part 2" $ nf day5b input 58 | ] 59 | , env (getDayInput 6) $ \input -> bgroup "Day 6" 60 | [ bench "part 1" $ nf day6a input 61 | , bench "part 2" $ nf day6b input 62 | ] 63 | , env (getDayInput 7) $ \input -> bgroup "Day 7" 64 | [ bench "part 1" $ nf day7a input 65 | , bench "part 2" $ nf day7b input 66 | ] 67 | , env (getDayInput 8) $ \input -> bgroup "Day 8" 68 | [ bench "part 1" $ nf day8a input 69 | , bench "part 2" $ nf day8b input 70 | ] 71 | , env (getDayInput 9) $ \input -> bgroup "Day 9" 72 | [ bench "part 1" $ nf day9a input 73 | , bench "part 2" $ nf day9b input 74 | ] 75 | , env (getDayInput 10) $ \input -> bgroup "Day 10" 76 | [ bench "part 1" $ nf (day10a 256) input 77 | , bench "part 2" $ nf day10b input 78 | ] 79 | , env (getDayInput 11) $ \input -> bgroup "Day 11" 80 | [ bench "part 1" $ nf day11a input 81 | , bench "part 2" $ nf day11b input 82 | ] 83 | , env (getDayInput 12) $ \input -> bgroup "Day 12" 84 | [ bench "part 1" $ nf day12a input 85 | , bench "part 2" $ nf day12b input 86 | ] 87 | , env (getDayInput 13) $ \input -> bgroup "Day 13" 88 | [ bench "part 1" $ nf day13a input 89 | , bench "part 2" $ nf day13b input 90 | ] 91 | , env (getDayInput 14) $ \input -> bgroup "Day 14" 92 | [ bench "part 1" $ nf day14a input 93 | , bench "part 2" $ nf day14b input 94 | ] 95 | , env (getDayInput 15) $ \input -> bgroup "Day 15" 96 | [ bench "part 1" $ nf day15a input 97 | , bench "part 2" $ nf day15b input 98 | ] 99 | , env (getDayInput 16) $ \input -> bgroup "Day 16" 100 | [ bench "part 1" $ nf (day16a 16) input 101 | , bench "part 2" $ nf (day16b 16 1000000000) input 102 | ] 103 | , env (readDayInput 17) $ \input -> bgroup "Day 17" 104 | [ bench "part 1" $ nf day17a input 105 | , bench "part 2" $ nf day17b input 106 | ] 107 | , env (getDayInput 18) $ \input -> bgroup "Day 18" 108 | [ bench "part 1" $ nf day18a input 109 | , bench "part 2" $ nf day18b input 110 | ] 111 | , env (getDayInput 19) $ \input -> bgroup "Day 19" 112 | [ bench "part 1" $ nf day19a input 113 | , bench "part 2" $ nf day19b input 114 | ] 115 | , env (getDayInput 20) $ \input -> bgroup "Day 20" 116 | [ bench "part 1" $ nf day20a input 117 | , bench "part 2" $ nf (length . day20b) input 118 | ] 119 | , env (getDayInput 21) $ \input -> bgroup "Day 21" 120 | [ bench "part 1" $ nf day21a input 121 | , bench "part 2" $ nf day21b input 122 | ] 123 | , env (getDayInput 22) $ \input -> bgroup "Day 22" 124 | [ bench "part 1" $ nf day22a input 125 | , bench "part 2" $ nf day22b input 126 | ] 127 | , env (getDayInput 23) $ \input -> bgroup "Day 23" 128 | [ bench "part 1" $ nf day23a input 129 | , bench "part 2" $ nf day23b input 130 | ] 131 | , env (getDayInput 24) $ \input -> bgroup "Day 24" 132 | [ bench "part 1" $ nf day24a input 133 | , bench "part 2" $ nf day24b input 134 | ] 135 | , env (getDayInput 25) $ \input -> bench "Day 25" $ nf day25 input 136 | ] 137 | -------------------------------------------------------------------------------- /day1.txt: -------------------------------------------------------------------------------- 1 | 181445682966897848665963472661939865313976877194312684993521259486517527961396717561854825453963181134379574918373213732184697746668399631642622373684425326112585283946462323363991753895647177797691214784149215198715986947573668987188746878678399624533792551651335979847131975965677957755571358934665327487287312467771187981424785514785421781781976477326712674311994735947987383516699897916595433228294198759715959469578766739518475118771755787196238772345762941477359483456641194685333528329581113788599843621326313592354167846466415943566183192946217689936174884493199368681514958669615226362538622898367728662941275658917124167353496334664239539753835439929664552886538885727235662548783529353611441231681613535447417941911479391558481443933134283852879511395429489152435996669232681215627723723565872291296878528334773391626672491878762288953597499218397146685679387438634857358552943964839321464529237533868734473777756775687759355878519113426969197211824325893376812556798483325994128743242544899625215765851923959798197562831313891371735973761384464685316273343541852758525318144681364492173465174512856618292785483181956548813344752352933634979165667651165776587656468598791994573513652324764687515345959621493346623821965554755615219855842969932269414839446887613738174567989512857785566352285988991946436148652839391593178736624957214917527759574235133666461988355855613377789115472297915429318142824465141688559333787512328799783539285826471818279818457674417354335454395644435889386297695625378256613558911695145397779576526397241795181294322797687168326696497256684943829666672341162656479563522892141714998477865114944671225898297338685958644728534192317628618817551492975251364233974374724968483637518876583946828819994321129556511537619253381981544394112184655586964655164192552352534626295996968762388827294873362719636616182786976922445125551927969267591395292198155775434997827738862786341543524544822321112131815475829945625787561369956264826651461575948462782869972654343749617939132353399334744265286151177931594514857563664329299713436914721119746932159456287267887878779218815883191236858656959258484139254446341 2 | -------------------------------------------------------------------------------- /day10.txt: -------------------------------------------------------------------------------- 1 | 83,0,193,1,254,237,187,40,88,27,2,255,149,29,42,100 2 | -------------------------------------------------------------------------------- /day11.txt: -------------------------------------------------------------------------------- 1 | s,sw,s,ne,s,se,s,s,s,se,se,se,se,ne,ne,n,ne,ne,ne,ne,ne,s,ne,ne,ne,ne,n,n,n,n,n,n,se,n,n,n,se,s,ne,n,n,nw,n,n,n,nw,n,s,n,n,n,n,s,s,nw,se,nw,s,n,nw,nw,nw,nw,ne,sw,nw,nw,nw,n,se,nw,nw,n,s,n,sw,sw,nw,sw,nw,nw,nw,se,ne,sw,n,sw,sw,sw,n,sw,sw,sw,ne,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,se,nw,sw,sw,s,sw,s,s,s,s,sw,sw,sw,se,s,sw,s,n,sw,ne,s,s,n,nw,s,s,s,s,s,s,se,s,sw,s,sw,sw,s,s,s,s,s,s,s,nw,s,se,se,s,se,s,s,s,se,n,nw,se,s,se,s,s,n,se,ne,s,s,s,s,s,s,ne,se,s,nw,se,s,s,nw,s,s,se,s,s,se,se,se,se,se,s,se,se,se,s,s,se,se,s,se,se,se,se,se,s,se,se,s,se,se,s,s,se,s,se,se,s,se,n,s,sw,se,se,se,se,se,ne,se,se,sw,nw,ne,se,se,ne,se,se,ne,ne,se,ne,se,se,ne,se,s,se,ne,se,se,ne,n,se,se,sw,ne,se,se,se,ne,se,ne,nw,ne,nw,se,ne,se,se,se,se,se,nw,se,ne,s,nw,se,ne,ne,ne,ne,n,se,s,nw,ne,se,ne,se,ne,ne,ne,ne,ne,ne,ne,nw,ne,ne,ne,ne,ne,n,se,sw,ne,se,se,ne,s,se,ne,ne,ne,ne,ne,ne,ne,s,ne,ne,n,ne,ne,ne,ne,ne,ne,ne,ne,sw,ne,n,ne,n,ne,ne,sw,n,ne,ne,ne,s,ne,ne,ne,ne,ne,ne,ne,n,ne,ne,n,sw,s,ne,n,ne,ne,nw,ne,ne,se,n,n,ne,n,ne,ne,ne,ne,n,nw,ne,ne,ne,ne,ne,n,ne,n,n,ne,sw,n,ne,ne,ne,n,n,n,sw,n,n,se,ne,n,ne,n,sw,n,n,ne,n,ne,n,n,n,ne,ne,nw,nw,ne,nw,s,se,n,n,n,n,n,ne,n,nw,n,n,sw,sw,se,se,ne,n,se,nw,sw,ne,n,nw,ne,n,n,n,se,se,ne,s,n,nw,n,se,n,ne,ne,se,ne,n,n,sw,ne,ne,n,n,n,n,n,se,sw,n,n,n,n,n,nw,n,n,n,n,s,n,sw,n,n,n,n,n,nw,sw,n,n,n,n,n,n,ne,n,ne,s,n,n,n,n,n,n,se,n,n,n,se,n,n,n,se,s,n,n,n,nw,n,n,n,n,n,nw,sw,n,n,n,n,n,n,nw,n,n,nw,n,nw,n,n,nw,se,n,sw,n,nw,nw,s,se,nw,nw,nw,nw,nw,sw,se,nw,n,nw,n,nw,n,nw,nw,n,nw,n,s,nw,s,n,nw,n,n,nw,n,n,nw,n,sw,n,nw,nw,n,nw,n,n,n,nw,n,nw,s,n,nw,n,sw,nw,n,nw,se,ne,nw,n,nw,n,nw,se,n,n,nw,se,nw,nw,n,s,n,n,nw,nw,sw,nw,nw,ne,nw,nw,n,nw,nw,nw,nw,nw,nw,n,n,nw,nw,nw,nw,ne,sw,nw,n,s,nw,nw,n,n,sw,nw,n,nw,s,s,n,n,nw,nw,nw,s,nw,nw,nw,s,nw,nw,nw,n,nw,n,nw,nw,nw,nw,nw,nw,ne,nw,se,nw,se,nw,nw,n,nw,nw,ne,nw,nw,se,sw,sw,s,nw,nw,nw,nw,nw,nw,nw,nw,nw,sw,nw,nw,nw,sw,nw,nw,s,nw,nw,nw,nw,ne,nw,nw,ne,s,nw,nw,nw,sw,nw,n,ne,nw,nw,sw,nw,nw,ne,nw,sw,sw,nw,nw,ne,sw,se,nw,nw,nw,n,nw,nw,sw,nw,s,sw,sw,nw,nw,nw,nw,nw,n,nw,nw,ne,sw,sw,nw,sw,nw,se,sw,nw,nw,nw,nw,nw,sw,nw,sw,nw,nw,sw,sw,nw,nw,nw,sw,nw,sw,sw,sw,ne,nw,nw,n,nw,sw,n,nw,ne,nw,s,nw,nw,sw,nw,n,nw,sw,nw,nw,sw,n,nw,sw,ne,sw,s,sw,sw,sw,sw,sw,nw,nw,nw,nw,se,sw,nw,sw,nw,sw,nw,nw,nw,sw,ne,nw,nw,nw,sw,nw,nw,ne,se,sw,nw,nw,nw,sw,sw,sw,nw,sw,sw,nw,sw,nw,sw,nw,nw,nw,nw,nw,s,sw,nw,nw,se,n,se,se,sw,nw,nw,nw,sw,nw,ne,nw,nw,sw,sw,n,nw,s,sw,sw,s,nw,sw,sw,nw,nw,sw,sw,nw,nw,nw,sw,ne,sw,se,ne,sw,nw,nw,sw,ne,sw,sw,sw,sw,se,sw,sw,sw,nw,sw,sw,nw,nw,sw,sw,sw,sw,se,sw,nw,sw,sw,n,sw,sw,nw,sw,sw,se,se,sw,sw,sw,sw,sw,sw,sw,sw,se,sw,sw,sw,s,sw,sw,se,sw,sw,sw,sw,sw,sw,sw,nw,sw,sw,sw,sw,sw,se,sw,sw,n,nw,sw,sw,sw,sw,s,sw,sw,sw,se,se,n,ne,sw,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,ne,ne,s,sw,sw,n,nw,sw,se,sw,sw,sw,sw,sw,sw,sw,sw,sw,nw,sw,n,sw,nw,sw,s,sw,sw,sw,sw,sw,s,sw,sw,sw,sw,sw,sw,sw,sw,sw,s,sw,sw,nw,s,s,se,sw,sw,sw,sw,n,n,sw,s,s,sw,se,s,sw,sw,sw,n,n,sw,sw,nw,ne,nw,nw,s,sw,s,s,sw,sw,sw,se,sw,s,sw,sw,sw,s,sw,s,ne,sw,sw,s,sw,sw,sw,sw,ne,s,s,s,n,s,se,sw,sw,s,sw,sw,s,s,sw,nw,sw,sw,se,ne,s,s,sw,sw,ne,sw,sw,se,sw,s,sw,sw,sw,sw,s,n,sw,ne,sw,sw,s,sw,sw,sw,sw,se,s,s,sw,s,s,sw,sw,n,s,sw,s,sw,ne,s,sw,sw,s,sw,sw,s,s,sw,sw,sw,s,sw,se,s,s,sw,s,s,se,sw,s,s,sw,s,sw,sw,sw,s,s,s,s,ne,s,sw,sw,nw,n,sw,sw,sw,s,sw,sw,sw,n,s,se,s,sw,s,s,sw,ne,sw,s,s,nw,sw,s,n,nw,sw,sw,s,sw,s,sw,s,s,s,s,s,sw,sw,s,s,sw,sw,se,s,sw,se,sw,s,se,n,s,se,s,s,sw,s,sw,s,ne,sw,s,ne,s,sw,sw,s,sw,s,s,s,sw,ne,s,se,s,nw,s,s,sw,s,s,ne,sw,s,s,sw,sw,s,se,s,sw,sw,sw,sw,s,s,sw,nw,n,n,n,sw,s,sw,se,s,s,s,s,sw,ne,sw,s,sw,nw,s,s,sw,s,s,s,nw,s,sw,s,s,s,s,s,s,s,s,s,s,se,se,se,s,s,sw,s,s,n,s,ne,s,nw,se,s,s,nw,nw,n,s,s,s,sw,se,s,s,s,s,n,s,s,s,s,s,sw,s,s,s,s,s,s,s,s,ne,s,nw,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,s,nw,s,s,s,s,s,nw,s,s,s,sw,s,s,s,n,sw,s,s,s,s,s,se,s,s,s,s,s,s,s,s,sw,s,s,s,se,s,n,s,nw,s,s,n,sw,s,se,s,se,s,sw,n,s,s,s,s,s,s,s,s,n,s,s,s,s,s,se,s,nw,se,se,s,s,se,s,se,s,s,s,s,s,s,s,se,s,s,s,n,se,nw,s,se,s,s,s,s,nw,se,s,s,s,se,se,s,s,nw,s,s,n,s,s,se,n,se,s,s,se,s,ne,s,s,s,s,s,s,se,s,s,s,se,s,se,s,s,ne,s,s,s,s,s,s,s,s,se,s,s,se,s,se,s,s,s,s,se,s,se,s,se,n,s,se,se,s,s,s,s,s,s,s,se,ne,s,s,s,se,s,s,se,se,s,se,se,n,ne,s,se,se,s,se,se,se,se,se,ne,s,se,s,se,sw,sw,n,se,s,s,se,se,s,se,nw,s,s,s,se,se,s,s,s,s,se,s,s,se,s,s,se,s,se,se,s,se,s,se,se,nw,s,ne,se,se,s,se,ne,se,ne,se,s,nw,se,se,se,s,se,s,s,s,se,ne,se,se,se,se,s,s,se,se,se,se,s,se,n,nw,s,n,s,se,se,se,se,s,nw,s,s,s,se,n,s,se,nw,s,s,ne,se,se,se,s,s,sw,s,s,s,s,nw,sw,se,se,s,se,nw,s,s,se,s,n,s,s,se,s,ne,s,s,se,se,s,se,se,sw,se,s,s,s,se,se,ne,se,se,s,se,nw,s,se,n,se,se,s,se,se,s,se,ne,nw,s,s,se,se,sw,s,n,s,s,se,s,se,se,s,sw,se,s,ne,s,se,se,s,se,se,s,se,nw,se,s,se,se,s,s,se,s,nw,se,n,n,se,sw,n,n,se,se,s,s,se,se,se,n,se,nw,se,s,se,s,s,se,ne,s,se,se,nw,se,s,sw,nw,s,ne,se,se,nw,se,s,s,se,se,s,ne,s,se,s,se,sw,ne,sw,s,s,s,n,se,se,se,se,se,se,nw,ne,se,se,se,sw,se,s,se,se,nw,se,se,nw,nw,se,se,se,se,se,s,se,nw,nw,se,se,se,se,se,se,se,se,se,se,sw,n,nw,se,se,nw,n,se,se,se,s,se,sw,s,se,se,se,sw,se,nw,n,s,se,n,n,nw,se,se,se,nw,se,se,se,n,se,se,se,ne,se,sw,s,se,se,se,se,se,se,se,se,se,se,n,se,se,se,n,s,s,n,se,se,se,se,se,se,se,se,s,n,se,se,se,se,se,sw,se,se,se,se,n,se,se,se,sw,se,ne,se,se,sw,se,se,se,n,sw,se,sw,se,ne,se,se,se,se,se,se,se,se,ne,se,sw,se,se,se,se,se,se,se,nw,ne,se,se,se,s,se,se,se,se,se,se,s,se,nw,nw,se,nw,se,nw,se,se,se,se,se,se,se,se,se,s,se,s,se,se,se,se,se,se,se,nw,se,sw,se,se,n,se,se,se,s,se,se,se,se,se,se,se,s,ne,se,se,ne,se,se,se,ne,se,se,se,se,se,se,se,se,se,se,sw,se,ne,ne,se,se,se,se,se,se,nw,se,se,se,se,se,nw,se,sw,ne,se,se,se,se,se,se,se,ne,se,se,se,se,ne,s,se,se,se,se,se,se,nw,se,se,ne,se,se,se,se,se,ne,s,se,ne,se,se,se,se,se,se,se,ne,nw,ne,se,se,se,se,se,se,nw,se,se,nw,se,se,n,se,se,ne,se,se,se,se,se,se,se,se,nw,ne,se,se,se,se,ne,se,se,ne,se,ne,se,n,se,se,se,se,s,se,se,se,nw,ne,se,se,se,ne,se,ne,se,n,ne,s,sw,s,se,ne,s,se,s,ne,se,n,se,se,n,se,se,ne,ne,se,se,se,s,ne,se,se,ne,se,se,se,ne,ne,se,se,se,ne,se,se,se,se,ne,ne,ne,se,ne,se,n,ne,se,se,sw,se,se,se,ne,se,s,se,se,se,ne,se,se,se,se,se,n,ne,s,se,se,se,se,s,ne,se,ne,se,se,n,ne,ne,ne,se,se,se,se,ne,se,se,ne,se,s,se,se,s,ne,ne,se,se,se,se,ne,ne,se,ne,se,se,sw,ne,se,ne,ne,se,s,ne,n,ne,se,ne,se,se,se,se,se,se,se,ne,ne,ne,se,ne,se,ne,se,se,se,se,ne,ne,ne,ne,se,ne,ne,se,ne,sw,ne,ne,ne,se,se,nw,ne,se,se,ne,ne,se,n,sw,ne,se,ne,ne,ne,ne,se,nw,nw,se,ne,ne,se,sw,ne,s,ne,se,ne,se,ne,se,se,ne,ne,se,se,sw,n,n,ne,se,se,n,n,ne,se,se,se,n,se,n,se,ne,se,nw,se,ne,s,se,ne,se,se,se,se,se,se,se,se,se,se,ne,ne,sw,ne,se,ne,se,ne,ne,se,n,se,ne,ne,se,se,ne,ne,ne,ne,se,se,ne,nw,se,ne,se,sw,s,se,nw,se,se,se,se,se,ne,ne,nw,se,se,se,se,sw,ne,ne,se,s,se,ne,sw,se,sw,ne,sw,ne,ne,ne,s,se,ne,ne,ne,n,ne,nw,se,ne,ne,se,se,ne,n,n,sw,ne,se,se,ne,sw,s,ne,se,ne,ne,ne,se,sw,ne,se,s,ne,ne,n,ne,ne,se,nw,ne,n,ne,ne,se,ne,ne,nw,s,sw,nw,se,sw,s,ne,ne,s,s,ne,ne,sw,sw,se,ne,ne,ne,ne,se,ne,ne,sw,ne,sw,ne,ne,se,se,s,se,ne,s,ne,ne,ne,ne,ne,ne,ne,s,se,se,sw,nw,n,se,se,ne,ne,ne,ne,sw,ne,ne,ne,se,se,s,nw,nw,n,se,ne,s,ne,ne,ne,ne,n,se,ne,se,ne,ne,ne,se,ne,sw,ne,se,nw,ne,n,sw,ne,sw,ne,s,ne,ne,nw,sw,ne,ne,ne,s,n,se,ne,ne,sw,nw,ne,ne,ne,ne,ne,ne,ne,se,ne,ne,sw,ne,se,ne,n,ne,se,se,sw,s,se,ne,se,ne,ne,se,ne,ne,ne,s,nw,ne,ne,ne,se,ne,se,ne,ne,ne,nw,se,ne,ne,nw,se,ne,ne,nw,se,ne,ne,nw,se,ne,n,ne,ne,ne,ne,s,ne,se,se,se,ne,n,ne,ne,ne,sw,ne,ne,ne,ne,ne,ne,nw,ne,ne,ne,ne,ne,sw,ne,se,se,ne,ne,n,ne,ne,s,ne,ne,ne,ne,ne,nw,ne,sw,s,ne,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,ne,n,ne,ne,ne,ne,ne,ne,nw,se,ne,se,ne,ne,se,se,nw,sw,ne,ne,ne,ne,ne,ne,ne,ne,ne,n,ne,ne,ne,s,n,ne,ne,ne,ne,ne,ne,sw,ne,ne,ne,ne,ne,se,ne,ne,ne,se,ne,nw,ne,ne,ne,nw,ne,ne,ne,ne,n,ne,sw,ne,ne,se,ne,n,ne,ne,ne,ne,se,ne,ne,sw,nw,n,ne,ne,nw,ne,ne,ne,ne,ne,ne,ne,ne,nw,ne,n,sw,ne,ne,ne,n,se,ne,ne,ne,ne,ne,ne,se,ne,n,ne,se,ne,n,n,ne,ne,ne,ne,ne,se,ne,ne,ne,nw,sw,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,se,n,s,ne,ne,sw,ne,ne,ne,se,ne,ne,ne,se,ne,se,s,ne,ne,ne,ne,n,n,nw,ne,ne,ne,ne,ne,ne,ne,ne,sw,ne,ne,s,n,ne,n,ne,ne,ne,ne,ne,ne,n,ne,ne,ne,sw,n,ne,n,ne,ne,sw,ne,ne,ne,n,ne,ne,n,ne,ne,ne,ne,ne,s,ne,n,ne,ne,ne,ne,n,n,ne,ne,ne,ne,ne,n,se,ne,n,n,ne,s,ne,ne,ne,ne,ne,ne,ne,s,ne,nw,s,ne,n,ne,n,n,n,ne,ne,ne,ne,n,ne,ne,n,ne,ne,n,ne,ne,n,ne,n,n,ne,ne,n,se,se,ne,n,ne,n,s,n,ne,nw,ne,ne,ne,ne,ne,ne,ne,ne,s,ne,n,n,n,ne,ne,ne,ne,ne,n,n,ne,n,ne,n,n,n,ne,ne,ne,ne,ne,ne,s,n,n,sw,n,n,ne,ne,ne,ne,n,ne,ne,n,ne,n,ne,ne,n,nw,ne,n,ne,ne,n,ne,ne,ne,n,n,ne,ne,ne,ne,n,ne,ne,nw,n,n,ne,ne,n,sw,n,ne,sw,s,ne,se,ne,nw,ne,n,ne,n,ne,ne,n,ne,n,ne,ne,ne,ne,ne,ne,nw,ne,nw,n,sw,n,ne,s,nw,se,ne,ne,sw,ne,sw,ne,ne,sw,ne,ne,ne,ne,n,n,ne,ne,n,ne,ne,n,sw,ne,n,ne,ne,n,n,s,sw,nw,n,ne,n,se,n,ne,ne,n,s,sw,n,ne,s,n,ne,ne,ne,se,se,ne,n,ne,n,ne,ne,ne,n,se,n,ne,ne,ne,ne,s,ne,n,n,n,n,ne,n,ne,n,ne,se,ne,sw,ne,s,n,ne,n,n,n,n,sw,n,sw,ne,n,ne,sw,ne,ne,se,ne,ne,ne,ne,n,s,n,se,ne,ne,n,n,sw,ne,ne,ne,n,ne,se,n,ne,ne,ne,ne,ne,sw,ne,ne,n,nw,ne,n,ne,n,n,n,n,ne,n,n,n,ne,ne,n,ne,ne,n,n,ne,n,ne,sw,n,ne,n,n,n,ne,ne,ne,ne,n,n,ne,ne,n,ne,se,n,n,ne,sw,n,n,ne,s,se,n,nw,sw,n,ne,ne,n,nw,ne,se,n,ne,ne,nw,ne,n,ne,ne,ne,n,n,n,s,ne,n,n,s,n,se,n,n,n,sw,ne,sw,n,n,n,ne,n,ne,n,n,nw,n,n,se,ne,n,n,n,n,n,n,ne,n,ne,n,n,n,ne,ne,n,n,ne,ne,n,s,n,n,n,n,n,ne,n,ne,sw,n,n,n,n,ne,n,ne,ne,ne,ne,n,s,n,ne,n,n,ne,s,n,ne,sw,n,ne,ne,n,ne,ne,sw,n,s,n,ne,n,ne,ne,n,ne,ne,sw,ne,ne,ne,nw,n,n,s,n,n,nw,n,sw,n,n,n,ne,sw,ne,ne,n,n,n,sw,n,n,n,sw,ne,s,s,n,ne,ne,n,n,se,n,ne,nw,s,ne,ne,n,n,n,n,n,n,n,sw,se,n,ne,n,ne,n,ne,nw,ne,n,n,n,n,n,s,n,n,n,ne,ne,n,sw,ne,nw,ne,n,n,n,sw,s,ne,ne,ne,ne,s,n,n,n,n,n,nw,ne,sw,n,ne,ne,ne,n,n,ne,sw,n,ne,n,n,sw,n,ne,n,se,n,n,n,ne,n,sw,n,n,n,n,n,n,n,ne,nw,n,s,n,se,ne,se,n,n,n,n,sw,n,n,n,ne,n,ne,ne,n,se,ne,n,ne,n,n,n,s,n,n,ne,n,ne,n,n,n,se,ne,ne,ne,ne,n,ne,ne,n,se,ne,s,n,ne,n,n,n,n,s,ne,n,se,ne,n,n,n,ne,n,n,n,n,n,n,n,n,n,n,n,n,n,n,ne,n,n,ne,ne,n,s,s,ne,n,n,ne,ne,ne,sw,sw,ne,n,nw,ne,n,n,ne,n,n,n,se,n,n,n,n,ne,n,n,n,se,n,nw,n,ne,n,sw,n,ne,ne,s,n,s,nw,ne,n,ne,sw,n,n,se,nw,n,se,n,se,n,ne,n,s,n,ne,n,ne,se,n,n,n,n,n,n,nw,ne,n,ne,n,n,n,ne,se,ne,ne,n,n,n,n,se,n,n,n,ne,n,ne,n,sw,n,n,n,n,sw,n,n,se,n,n,sw,n,n,n,se,n,n,n,ne,s,n,ne,ne,n,sw,n,n,n,n,n,ne,n,ne,n,n,n,n,ne,s,n,n,ne,sw,n,ne,n,s,n,ne,nw,s,ne,s,ne,sw,n,n,ne,n,ne,n,n,n,n,n,n,n,n,n,sw,n,s,n,n,n,sw,n,n,n,sw,n,n,ne,n,n,ne,n,n,se,n,n,n,n,n,n,n,se,nw,n,n,n,se,n,n,ne,nw,n,ne,n,n,n,n,n,n,n,ne,sw,n,n,ne,n,n,n,n,n,n,n,n,s,s,ne,n,n,n,ne,n,ne,n,ne,ne,n,sw,n,s,n,sw,sw,sw,n,nw,n,n,n,ne,n,n,n,n,nw,nw,n,ne,n,n,n,n,n,n,n,n,n,s,n,n,n,s,n,ne,n,ne,n,nw,n,n,nw,n,ne,sw,n,n,n,n,n,n,n,nw,n,n,se,n,n,se,n,n,n,n,n,nw,n,s,n,n,n,n,n,nw,n,n,s,n,n,n,n,ne,n,nw,n,n,n,n,n,n,nw,n,n,n,n,n,nw,n,n,n,n,n,sw,nw,n,n,n,n,n,nw,s,n,n,n,sw,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,se,nw,n,n,n,nw,n,n,n,ne,n,n,n,se,n,n,n,n,se,n,n,nw,nw,n,n,sw,n,nw,n,n,n,n,n,nw,n,n,n,n,nw,n,n,sw,ne,se,nw,n,s,n,n,sw,n,sw,n,n,n,nw,n,n,n,s,n,n,n,n,n,n,sw,n,nw,sw,sw,n,s,n,n,n,n,n,s,n,n,n,n,n,nw,n,sw,nw,se,n,n,n,n,ne,se,n,n,nw,n,n,n,n,n,n,se,n,n,n,s,n,se,nw,n,nw,n,nw,n,nw,n,n,n,n,ne,n,s,n,s,n,n,ne,n,n,sw,n,n,n,n,n,n,ne,nw,n,n,n,n,nw,ne,n,n,n,n,n,n,n,n,n,sw,sw,n,n,n,nw,sw,n,n,n,n,n,n,n,n,n,n,n,n,se,n,n,n,n,se,n,n,ne,n,n,ne,nw,n,n,n,nw,n,n,n,n,nw,nw,n,n,n,nw,nw,n,n,s,n,n,nw,nw,n,n,nw,n,n,nw,n,nw,se,n,nw,n,s,n,n,ne,n,sw,se,n,n,n,nw,n,n,n,ne,n,s,nw,n,ne,ne,n,n,s,n,n,s,n,n,n,nw,sw,n,nw,n,s,nw,nw,nw,nw,ne,n,n,n,n,n,n,n,nw,nw,n,n,s,n,n,nw,n,n,n,nw,n,n,se,nw,n,s,nw,n,nw,n,n,ne,n,n,n,n,n,n,n,n,n,nw,nw,se,n,n,ne,nw,n,n,n,n,n,n,nw,n,nw,n,se,n,n,n,n,s,ne,ne,nw,n,n,n,n,nw,n,nw,n,n,s,n,nw,nw,n,ne,n,n,ne,nw,sw,nw,n,s,n,nw,n,n,n,sw,n,n,n,n,s,n,n,nw,ne,n,nw,se,nw,n,s,n,n,sw,n,n,n,n,sw,nw,nw,n,n,n,n,n,n,n,n,nw,n,nw,n,n,se,ne,nw,se,n,sw,n,nw,sw,n,s,sw,nw,nw,n,n,nw,n,n,nw,n,n,n,n,n,n,se,nw,n,n,nw,nw,s,n,se,n,n,nw,n,nw,nw,nw,se,nw,n,n,n,ne,nw,n,sw,n,n,n,nw,nw,nw,ne,nw,nw,n,n,n,nw,ne,n,nw,nw,n,nw,se,n,n,nw,nw,n,n,n,nw,n,n,n,n,se,n,n,n,n,n,n,nw,nw,nw,n,n,n,sw,n,n,n,s,n,n,s,s,nw,nw,n,se,se,n,nw,n,n,nw,sw,s,n,nw,nw,n,sw,n,n,ne,n,sw,nw,n,n,s,nw,nw,n,s,nw,s,n,nw,nw,n,sw,nw,nw,n,n,n,nw,n,n,n,nw,n,n,n,n,n,nw,nw,s,nw,nw,n,n,se,n,n,nw,n,n,n,se,n,n,n,n,nw,ne,n,n,ne,n,n,n,n,n,nw,n,nw,se,n,nw,n,nw,n,nw,se,n,n,se,nw,n,n,n,nw,sw,n,s,n,nw,n,n,n,n,n,n,n,s,s,n,nw,se,nw,se,nw,se,n,nw,nw,n,sw,n,n,nw,sw,ne,n,nw,nw,s,s,n,n,sw,nw,se,nw,nw,sw,n,se,nw,ne,sw,nw,nw,sw,nw,n,n,n,n,n,n,nw,n,n,n,n,nw,nw,n,n,sw,n,nw,nw,n,se,se,nw,nw,n,n,n,se,nw,nw,n,nw,nw,nw,ne,n,nw,nw,n,s,se,n,n,nw,nw,n,nw,nw,n,n,nw,nw,nw,sw,se,n,n,n,s,n,nw,nw,sw,n,nw,n,n,n,s,ne,nw,nw,s,n,n,nw,n,n,s,se,n,n,n,nw,n,nw,nw,nw,nw,nw,nw,n,nw,n,sw,nw,ne,nw,nw,n,s,nw,n,nw,nw,ne,nw,ne,nw,n,nw,nw,sw,n,nw,nw,s,s,ne,sw,n,se,nw,n,nw,nw,sw,nw,n,n,n,nw,n,nw,nw,n,nw,n,s,n,s,n,n,n,n,nw,nw,n,ne,n,se,nw,nw,nw,nw,n,nw,n,nw,nw,n,n,n,se,nw,s,nw,ne,n,n,n,nw,nw,nw,nw,ne,n,n,nw,nw,ne,n,nw,nw,nw,se,nw,nw,se,nw,n,n,nw,nw,s,n,se,nw,n,n,n,nw,n,nw,nw,nw,nw,n,nw,se,se,ne,nw,n,nw,n,se,sw,n,nw,nw,nw,nw,nw,nw,nw,n,nw,se,nw,nw,nw,se,n,nw,n,nw,s,nw,nw,se,nw,ne,nw,nw,n,nw,n,nw,n,nw,se,nw,sw,nw,nw,n,nw,n,n,ne,nw,sw,nw,ne,n,nw,nw,se,nw,nw,ne,s,n,n,nw,se,nw,nw,se,n,sw,nw,nw,ne,n,nw,s,n,se,n,nw,nw,nw,nw,n,nw,s,ne,nw,nw,sw,nw,nw,s,nw,s,nw,n,n,nw,n,s,nw,nw,nw,nw,nw,n,nw,n,nw,n,nw,nw,sw,nw,nw,se,n,n,nw,nw,nw,nw,nw,s,n,n,n,n,s,n,n,nw,nw,sw,n,nw,s,sw,nw,n,nw,se,s,nw,nw,nw,s,nw,nw,se,nw,nw,n,nw,nw,n,s,nw,n,nw,nw,nw,nw,nw,sw,nw,sw,n,n,nw,n,nw,nw,nw,nw,n,n,nw,nw,n,s,nw,n,nw,nw,nw,nw,sw,nw,nw,n,ne,se,nw,n,nw,n,n,n,s,nw,n,nw,nw,nw,nw,ne,nw,n,nw,n,nw,nw,nw,n,nw,nw,nw,nw,se,nw,n,n,nw,nw,se,nw,nw,nw,n,nw,nw,s,n,nw,s,ne,nw,ne,n,n,s,n,n,nw,nw,nw,nw,nw,nw,n,n,nw,nw,nw,s,nw,ne,nw,n,n,nw,nw,nw,nw,n,se,nw,nw,n,n,n,nw,nw,nw,nw,nw,nw,n,sw,nw,nw,nw,nw,nw,n,n,nw,nw,n,n,se,nw,nw,nw,nw,nw,s,n,sw,se,nw,ne,nw,n,nw,se,s,nw,n,nw,se,sw,nw,n,se,n,nw,nw,sw,nw,se,nw,nw,nw,nw,n,nw,sw,nw,nw,nw,nw,n,n,nw,nw,nw,se,se,sw,nw,n,n,n,sw,se,ne,nw,nw,sw,nw,n,se,nw,nw,nw,nw,se,sw,nw,nw,nw,nw,n,nw,n,n,n,s,nw,nw,nw,nw,n,ne,nw,n,sw,se,sw,n,nw,nw,nw,nw,sw,nw,nw,nw,ne,nw,nw,n,sw,nw,nw,nw,sw,n,nw,nw,n,nw,n,nw,n,nw,nw,sw,sw,nw,nw,sw,se,s,nw,nw,nw,s,se,nw,nw,nw,n,nw,nw,nw,nw,sw,nw,sw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,n,nw,sw,nw,sw,n,n,n,s,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,s,nw,nw,nw,nw,nw,nw,n,nw,ne,nw,n,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,nw,n,nw,nw,nw,sw,nw,se,nw,nw,nw,nw,nw,nw,s,nw,se,nw,nw,nw,sw,nw,ne,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,sw,nw,nw,nw,nw,nw,nw,n,nw,nw,nw,nw,nw,sw,nw,s,nw,nw,nw,nw,nw,ne,nw,nw,n,nw,nw,nw,n,nw,nw,nw,nw,n,se,nw,nw,s,nw,sw,nw,nw,n,n,nw,nw,n,nw,nw,sw,nw,nw,nw,se,nw,nw,nw,se,nw,nw,sw,nw,nw,nw,sw,nw,nw,nw,n,n,nw,nw,nw,nw,nw,n,nw,nw,nw,nw,nw,nw,nw,nw,nw,nw,sw,se,nw,nw,nw,s,s,nw,nw,nw,nw,ne,nw,nw,nw,n,nw,ne,nw,se,se,se,s,s,s,s,s,s,s,sw,s,s,s,sw,n,sw,sw,sw,se,sw,n,sw,sw,sw,nw,sw,sw,nw,nw,n,nw,nw,sw,nw,nw,nw,nw,nw,n,nw,nw,n,nw,n,n,nw,sw,s,nw,ne,n,n,n,n,n,n,n,ne,n,n,n,n,n,n,ne,n,n,ne,ne,ne,n,ne,n,n,ne,ne,n,n,ne,n,s,ne,n,ne,ne,n,ne,ne,ne,ne,s,sw,ne,ne,n,sw,ne,ne,se,se,ne,ne,se,nw,ne,ne,ne,ne,ne,se,ne,se,ne,s,n,se,ne,se,sw,ne,ne,ne,s,se,se,se,se,se,se,se,se,se,se,se,se,sw,se,ne,ne,ne,se,se,se,sw,ne,se,se,se,se,se,sw,ne,se,se,n,se,se,n,se,n,sw,se,s,s,se,sw,se,nw,s,s,se,se,se,s,ne,s,s,se,se,se,s,s,s,n,se,se,s,nw,se,n,se,se,s,s,se,s,s,s,s,s,se,s,se,se,s,s,s,s,s,s,s,se,s,s,s,sw,s,s,sw,s,sw,s,n,se,s,nw,s,s,s,s,s,s,s,nw,nw,s,s,s,nw,s,s,sw,s,s,ne,sw,s,s,s,sw,s,s,s,s,s,s,s,s,sw,n,sw,s,sw,s,n,s,se,s,s,s,s,sw,n,se,s,s,sw,sw,s,nw,sw,sw,sw,s,sw,sw,s,sw,ne,sw,s,sw,sw,nw,sw,s,sw,sw,sw,s,nw,sw,sw,s,sw,s,s,sw,sw,s,sw,sw,se,n,s,sw,sw,sw,nw,sw,sw,sw,sw,sw,se,ne,sw,se,n,sw,sw,sw,se,nw,sw,se,sw,sw,sw,sw,nw,sw,nw,nw,sw,nw,sw,sw,nw,nw,n,sw,nw,sw,s,sw,sw,sw,sw,s,sw,sw,sw,sw,nw,sw,sw,nw,ne,sw,sw,sw,n,sw,sw,se,s,sw,sw,sw,sw,nw,sw,sw,nw,sw,sw,nw,nw,nw,se,sw,nw,nw,n,sw,nw,s,nw,nw,sw,sw,sw,sw,sw,s,nw,n,se,sw,sw,sw,nw,sw,nw,nw,nw,nw,sw,ne,sw,nw,nw,nw,n,sw,sw,nw,sw,nw,nw,nw,se,nw,ne,nw,nw,nw,nw,nw,nw,nw,nw,n,s,nw,nw,nw,nw,nw,nw,nw,nw,sw,nw,nw,sw,nw,nw,nw,nw,nw,se,s,nw,ne,nw,nw,nw,n,nw,n,nw,nw,nw,n,nw,nw,n,se,nw,se,nw,nw,s,nw,nw,nw,nw,s,nw,nw,n,s,sw,s,nw,nw,nw,nw,n,nw,ne,sw,nw,nw,n,nw,nw,n,n,nw,nw,s,nw,nw,nw,s,n,nw,nw,nw,se,sw,nw,nw,n,nw,nw,nw,n,ne,nw,n,nw,nw,s,n,nw,n,nw,nw,n,nw,n,ne,se,nw,n,nw,nw,n,ne,nw,s,n,nw,n,s,n,nw,s,nw,nw,nw,nw,nw,nw,n,n,nw,nw,nw,ne,n,se,nw,n,n,n,n,nw,se,nw,n,nw,nw,n,nw,sw,n,n,n,ne,s,sw,n,nw,n,s,nw,sw,nw,nw,n,nw,n,nw,n,nw,se,n,nw,n,n,n,n,n,nw,n,s,sw,n,n,n,s,n,ne,n,nw,n,se,n,n,n,s,n,nw,n,n,n,n,n,n,se,nw,nw,n,nw,n,n,n,n,n,ne,n,n,n,nw,nw,nw,n,s,n,n,n,nw,n,nw,n,n,n,n,nw,nw,n,n,se,nw,n,n,n,se,n,s,nw,n,n,n,n,sw,ne,nw,n,n,n,n,n,n,n,n,n,n,s,n,n,se,n,sw,se,n,n,se,n,n,n,se,n,n,n,n,n,se,n,nw,n,ne,sw,s,n,n,n,n,n,n,n,n,n,n,s,n,n,ne,n,n,n,se,ne,ne,n,n,nw,n,n,n,ne,ne,n,n,n,n,ne,n,se,n,ne,n,n,s,n,n,ne,ne,n,ne,n,ne,s,n,ne,ne,n,n,sw,n,s,ne,sw,n,ne,ne,se,ne,ne,n,n,ne,s,n,n,n,s,n,n,nw,n,n,ne,n,n,n,n,ne,se,ne,ne,n,n,n,ne,ne,ne,n,n,n,nw,ne,n,n,n,n,n,ne,n,ne,n,ne,n,ne,ne,n,n,ne,n,ne,n,ne,sw,nw,ne,ne,n,ne,n,n,n,n,ne,ne,ne,ne,ne,n,n,ne,sw,ne,sw,ne,ne,ne,ne,ne,sw,n,n,ne,ne,sw,sw,ne,ne,ne,ne,n,sw,ne,ne,ne,ne,se,ne,n,n,ne,n,sw,sw,n,ne,ne,ne,ne,ne,ne,ne,s,ne,s,ne,ne,ne,ne,s,n,n,ne,ne,ne,ne,ne,ne,se,s,n,ne,nw,s,n,s,ne,s,n,nw,ne,ne,ne,se,ne,ne,se,ne,ne,n,ne,n,s,ne,ne,ne,ne,ne,ne,ne,s,ne,ne,s,ne,ne,ne,ne,sw,sw,se,sw,ne,ne,sw,se,ne,s,ne,ne,ne,ne,ne,ne,ne,s,s,s,se,ne,ne,n,ne,ne,ne,n,sw,ne,nw,nw,ne,ne,ne,sw,sw,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,ne,n,s,n,ne,n,s,n,ne,ne,ne,ne,se,se,ne,se,ne,ne,ne,ne,sw,ne,ne,n,ne,se,ne,ne,ne,nw,ne,ne,ne,ne,ne,nw,ne,se,se,ne,ne,ne,ne,ne,se,ne,ne,se,ne,ne,ne,s,ne,se,ne,n,ne,ne,nw,nw,se,ne,s,se,ne,ne,ne,ne,sw,nw,se,ne,ne,ne,ne,se,se,ne,ne,ne,ne,ne,ne,ne,se,ne,n,se,ne,s,ne,se,se,ne,se,ne,ne,ne,se,nw,s,se,ne,ne,nw,se,ne,ne,ne,nw,ne,se,sw,ne,se,ne,n,se,se,nw,se,ne,ne,se,ne,se,se,se,sw,se,se,ne,n,ne,s,ne,ne,ne,ne,nw,n,sw,ne,s,ne,ne,se,s,ne,se,se,ne,ne,se,ne,n,ne,se,se,se,se,se,ne,ne,ne,se,ne,se,ne,se,se,se,se,se,ne,ne,s,ne,ne,se,se,se,se,nw,se,ne,ne,ne,ne,se,s,ne,ne,ne,nw,nw,se,ne,s,ne,se,se,ne,se,se,se,ne,se,se,se,se,ne,ne,se,ne,n,sw,se,se,ne,se,se,sw,se,s,nw,se,ne,ne,s,n,se,s,se,ne,se,se,n,se,se,ne,se,se,se,se,ne,nw,ne,nw,se,se,se,n,ne,se,se,se,se,se,n,se,se,sw,se,ne,se,nw,se,s,sw,se,se,s,ne,ne,se,se,se,se,ne,se,ne,se,ne,ne,se,se,se,se,sw,se,ne,ne,ne,se,se,ne,se,se,se,se,se,se,nw,nw,se,se,n,n,nw,ne,se,se,se,se,sw,se,se,se,se,se,se,n,se,se,se,se,se,se,se,se,s,se,se,se,ne,se,se,se,sw,se,se,se,se,se,s,se,se,se,s,s,se,se,se,se,nw,sw,n,se,se,se,se,se,se,se,se,se,se,ne,se,se,nw,se,se,s,se,se,se,se,sw,se,n,se,se,se,s,se,se,se,se,se,s,n,ne,sw,se,s,se,s,se,se,se,n,se,sw,n,se,se,se,n,se,nw,se,se,s,se,se,se,se,se,se,se,n,se,se,nw,se,se,se,se,sw,se,se,sw,se,nw,se,se,sw,se,se,se,sw,nw,se,se,sw,se,se,se,se,se,se,nw,se,se,ne,se,se,s,se,s,se,se,se,se,se,sw,s,se,se,se,s,se,se,s,se,s,se,ne,se,nw,s,s,se,s,se,se,se,s,se,se,s,se,s,se,se,se,ne,se,se,se,se,se,se,nw,s,se,ne,s,se,n,se,se,ne,se,se,se,se,nw,s,nw,n,ne,s,se,se,n,s,s,se,se,s,sw,se,se,sw,n,se,se,se,se,se,se,s,s,s,se,s,n,se,se,se,se,sw,n,se,se,s,nw,se,s,se,s,se,se,se,se,se,se,se,s,ne,s,se,ne,ne,n,se,n,s,se,se,se,ne,se,n,se,s,se,se,s,sw,s,se,s,s,s,n,s,se,se,n,ne,s,se,n,se,s,se,s,n,sw,nw,n,se,ne,se,se,s,s,s,se,s,ne,se,s,se,s,se,se,se,s,s,n,ne,se,s,s,s,se,ne,s,se,se,se,se,n,n,se,n,sw,se,se,nw,s,s,se,s,se,ne,s,ne,se,se,se,s,s,se,s,s,se,s,s,s,s,s,s,se,ne,s,se,s,s,se,ne,s,se,se,s,se,se,s,s,s,se,s,nw,sw,se,s,se,se,nw,s,s,s,se,s,s,s,s,s,s,nw,s,se,se,s,s,n,s,se,s,se,se,se,s,s,s,se,n,se,se,se,se,se,s,ne,n,ne,s,se,se,s,se,s,se,s,n,s,s,n,s,s,nw,n,s,s,ne,ne,ne,s,s,s,se,s,sw,s,s,se,s,se,se,se,s,ne,s,se,se,se,s,s,s,se,s,se,s,sw,s,s,s,n,s,s,s,se,s,s,s,s,s,se,n,s,se,se,s,s,ne,s,se,s,s,s,n,se,nw,nw,s,s,n,s,ne,s,s,nw,s,s,s,s,s,s,s,se,s,s,s,n,s,s,s,s,se,se,s,s,nw,s,ne,s,sw,s,s,s,n,s,nw,sw,s,s,s,s,s,sw,s,s,s,ne,s,se,s,s,s,s,s,s,s,s,s,nw,s,s,s,se,s,s,s,s,s,se,nw,se,nw,s,n,s,s,s,s,s,s,sw,s,s,s,s,s,s,s,n,s,s,ne,n,s,s,s,s,nw,ne,s,s,s,s,s,s,nw,s,s,ne,s,ne,s,s,s,se,s,s,s,s,s,s,s,s,s,s,s,n,nw,s,s,s,s,s,sw,s,nw,s,s,sw,s,s,s,s,s,se,s,s,s,s,s,s,s,sw,s,s,s,se,s,s,nw,s,s,s,s,s,n,s,nw,s,s,sw,n,s,n,s,s,s,s,sw,nw,se,s,s,s,nw,s,s,sw,s,s,s,s,n,s,sw,s,se,s,sw,s,s,s,sw,s,sw,s,s,s,s,s,s,sw,ne,s,s,s,n,sw,s,s,s,s,s,s,s,s,s,s,s,s,s,sw,s,s,s,s,s,sw,s,s,sw,s,s,ne,se,se,sw,n,s,s,s,s,s,s,s,s,nw,s,ne,sw,se,s,s,sw,s,s,nw,se,s,s,sw,ne,s,sw,s,se,s,s,nw,se,sw,s,s,s,s,sw,sw,se,sw,sw,sw,s,s,s,sw,s,ne,se,se,ne,s,s,s,sw,s,s,sw,sw,s,sw,s,sw,s,s,s,s,sw,s,nw,s,sw,s,s,s,s,s,sw,n,s,se,s,sw,sw,sw,s,sw,s,sw,s,s,nw,n,sw,s,s,s,s,sw,s,s,s,s,sw,s,s,sw,n,s,s,nw,sw,ne,nw,s,s,s,sw,s,n,nw,sw,s,s,s,sw,s,sw,s,s,s,sw,s,s,s,sw,s,ne,sw,ne,s,sw,s,s,s,s,s,ne,sw,se,s,sw,sw,sw,s,sw,s,s,s,s,se,s,sw,s,sw,sw,s,sw,sw,sw,s,s,s,s,n,se,s,sw,s,s,sw,s,s,s,sw,sw,sw,s,sw,s,sw,ne,ne,s,s,s,sw,s,nw,nw,se,sw,s,s,s,s,sw,s,s,sw,se,s,ne,s,n,s,sw,sw,s,sw,ne,se,sw,s,s,s,ne,sw,s,sw,s,sw,s,n,sw,sw,s,sw,sw,s,nw,ne,s,nw,sw,s,sw,sw,s,s,n,sw,sw,s,s,s,n,sw,s,s,nw,s,sw,sw,s,sw,sw,se,s,s,s,s,s,s,s,sw,nw,sw,sw,se,s,s,se,sw,s,sw,se,nw,nw,s,nw,s,sw,ne,s,s,ne,s,sw,s,s,s,sw,sw,s,se,sw,n,sw,s,sw,sw,s,sw,sw,sw,s,s,s,se,sw,s,s,s,s,s,sw,sw,s,sw,se,sw,s,sw,sw,se,sw,sw,s,sw,sw,s,s,s,s,s,s,s,s,sw,sw,sw,sw,ne,ne,ne,ne,s,nw,se,s,s,sw,s,s,s,s,s,sw,sw,sw,s,s,sw,s,s,s,sw,sw,s,s,sw,sw,sw,sw,s,sw,sw,sw,s,sw,sw,sw,ne,sw,ne,s,sw,sw,ne,sw,se,sw,sw,sw,s,s,s,sw,se,s,sw,sw,sw,nw,s,sw,se,sw,sw,s,se,sw,se,sw,s,sw,sw,sw,s,sw,sw,sw,s,se,sw,s,s,sw,sw,s,s,sw,sw,sw,s,sw,sw,s,s,s,sw,sw,sw,s,sw,s,ne,se,sw,s,sw,sw,s,sw,sw,sw,se,sw,sw,sw,sw,n,s,sw,sw,se,ne,sw,sw,sw,s,sw,sw,sw,sw,sw,n,sw,s,s,se,sw,sw,sw,sw,s,sw,sw,s,sw,s,s,s,sw,sw,nw,s,sw,sw,sw,sw,sw,n,sw,sw,sw,sw,s,sw,sw,sw,sw,ne,sw,sw,sw,s,ne,sw,sw,s,sw,sw,sw,ne,s,ne,sw,se,s,sw,sw,s,s,sw,sw,se,sw,nw,sw,sw,sw,sw,sw,n,sw,se,nw,sw,sw,sw,sw,sw,n,sw,sw,sw,s,sw,sw,sw,sw,sw,se,sw,sw,sw,sw,se,sw,sw,sw,sw,sw,s,se,sw,sw,sw,ne,sw,sw,se,sw,s,sw,sw,ne,sw,sw,sw,sw,ne,ne,sw,ne,sw,sw,sw,s,sw,sw,sw,s,s,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,sw,se,sw,sw,nw,sw,sw,sw,nw,nw,sw,sw,sw,sw,n,sw,ne,se,s,sw,sw,sw,se,ne,sw,ne,se,sw,sw,sw,sw,sw,nw,sw,sw,sw 2 | -------------------------------------------------------------------------------- /day13.txt: -------------------------------------------------------------------------------- 1 | 0: 4 2 | 1: 2 3 | 2: 3 4 | 4: 4 5 | 6: 8 6 | 8: 5 7 | 10: 8 8 | 12: 6 9 | 14: 6 10 | 16: 8 11 | 18: 6 12 | 20: 6 13 | 22: 12 14 | 24: 12 15 | 26: 10 16 | 28: 8 17 | 30: 12 18 | 32: 8 19 | 34: 12 20 | 36: 9 21 | 38: 12 22 | 40: 8 23 | 42: 12 24 | 44: 17 25 | 46: 14 26 | 48: 12 27 | 50: 10 28 | 52: 20 29 | 54: 12 30 | 56: 14 31 | 58: 14 32 | 60: 14 33 | 62: 12 34 | 64: 14 35 | 66: 14 36 | 68: 14 37 | 70: 14 38 | 72: 12 39 | 74: 14 40 | 76: 14 41 | 80: 14 42 | 84: 18 43 | 88: 14 44 | -------------------------------------------------------------------------------- /day14.txt: -------------------------------------------------------------------------------- 1 | oundnydw -------------------------------------------------------------------------------- /day15.txt: -------------------------------------------------------------------------------- 1 | Generator A starts with 722 2 | Generator B starts with 354 3 | -------------------------------------------------------------------------------- /day17.txt: -------------------------------------------------------------------------------- 1 | 348 -------------------------------------------------------------------------------- /day18.txt: -------------------------------------------------------------------------------- 1 | set i 31 2 | set a 1 3 | mul p 17 4 | jgz p p 5 | mul a 2 6 | add i -1 7 | jgz i -2 8 | add a -1 9 | set i 127 10 | set p 952 11 | mul p 8505 12 | mod p a 13 | mul p 129749 14 | add p 12345 15 | mod p a 16 | set b p 17 | mod b 10000 18 | snd b 19 | add i -1 20 | jgz i -9 21 | jgz a 3 22 | rcv b 23 | jgz b -1 24 | set f 0 25 | set i 126 26 | rcv a 27 | rcv b 28 | set p a 29 | mul p -1 30 | add p b 31 | jgz p 4 32 | snd a 33 | set a b 34 | jgz 1 3 35 | snd b 36 | set f 1 37 | add i -1 38 | jgz i -11 39 | snd a 40 | jgz f -16 41 | jgz a -19 42 | -------------------------------------------------------------------------------- /day2.txt: -------------------------------------------------------------------------------- 1 | 104 240 147 246 123 175 372 71 116 230 260 118 202 270 277 292 2 | 740 755 135 205 429 822 844 90 828 115 440 805 526 91 519 373 3 | 1630 991 1471 1294 52 1566 50 1508 1367 1489 55 547 342 512 323 51 4 | 1356 178 1705 119 1609 1409 245 292 1434 694 405 1692 247 193 1482 1407 5 | 2235 3321 3647 212 1402 3711 3641 1287 2725 692 1235 3100 123 144 104 101 6 | 1306 1224 1238 186 751 734 1204 1275 366 149 1114 166 1118 239 153 943 7 | 132 1547 1564 512 2643 2376 2324 2159 1658 107 1604 145 2407 131 2073 1878 8 | 1845 91 1662 108 92 1706 1815 1797 1728 1150 1576 83 97 547 1267 261 9 | 78 558 419 435 565 107 638 173 93 580 338 52 633 256 377 73 10 | 1143 3516 4205 3523 148 401 3996 3588 300 1117 2915 1649 135 134 182 267 11 | 156 2760 1816 2442 2985 990 2598 1273 167 821 138 141 2761 2399 1330 1276 12 | 3746 3979 2989 161 4554 156 3359 173 3319 192 3707 264 762 2672 4423 2924 13 | 3098 4309 4971 5439 131 171 5544 595 154 571 4399 4294 160 6201 4329 5244 14 | 728 249 1728 305 2407 239 691 2241 2545 1543 55 2303 1020 753 193 1638 15 | 260 352 190 877 118 77 1065 1105 1085 1032 71 87 851 56 1161 667 16 | 1763 464 182 1932 1209 640 545 931 1979 197 1774 174 2074 1800 939 161 17 | -------------------------------------------------------------------------------- /day21.txt: -------------------------------------------------------------------------------- 1 | ../.. => ##./###/... 2 | #./.. => ..#/##./##. 3 | ##/.. => #.#/##./... 4 | .#/#. => ##./###/### 5 | ##/#. => ###/.#./#.# 6 | ##/## => .#./.#./### 7 | .../.../... => #.../.#.#/..##/#... 8 | #../.../... => .##./#.##/##../##.. 9 | .#./.../... => ##../#.../.#.#/###. 10 | ##./.../... => .#.#/###./.#.#/.#.. 11 | #.#/.../... => .#.#/##../.#../###. 12 | ###/.../... => #.##/.##./..##/#.## 13 | .#./#../... => #..#/...#/.###/.##. 14 | ##./#../... => .###/..#./#.../#### 15 | ..#/#../... => ..../.#../#.##/.... 16 | #.#/#../... => ..##/.##./.##./.... 17 | .##/#../... => ###./#.../#.#./.#.# 18 | ###/#../... => .#../##.#/.#.#/..#. 19 | .../.#./... => ####/##../..#./#..# 20 | #../.#./... => ####/#.##/#..#/..#. 21 | .#./.#./... => #.##/.#../.#../.#.# 22 | ##./.#./... => ..##/###./..../...# 23 | #.#/.#./... => ...#/.#.#/.#../.... 24 | ###/.#./... => ..../..#./#..#/##.# 25 | .#./##./... => ##../.#.#/#.#./.#.# 26 | ##./##./... => ###./##.#/#.#./.##. 27 | ..#/##./... => ..#./.#.#/###./##.# 28 | #.#/##./... => ##.#/.#../#.../#.#. 29 | .##/##./... => ####/..../...#/#.## 30 | ###/##./... => ####/.###/.###/.### 31 | .../#.#/... => .#.#/###./.##./.#.. 32 | #../#.#/... => #.##/#..#/#..#/##.. 33 | .#./#.#/... => ...#/##../..../#..# 34 | ##./#.#/... => #..#/.#../##.#/..## 35 | #.#/#.#/... => ..../...#/..#./#..# 36 | ###/#.#/... => .##./#..#/...#/.##. 37 | .../###/... => ..../#.##/.#../##.. 38 | #../###/... => .#.#/.###/###./#..# 39 | .#./###/... => ...#/.#../###./.### 40 | ##./###/... => #..#/###./#.##/.#.. 41 | #.#/###/... => .#../##../###./.#.# 42 | ###/###/... => ###./.#.#/.##./###. 43 | ..#/.../#.. => ...#/#..#/###./.### 44 | #.#/.../#.. => #.#./#.##/#.#./...# 45 | .##/.../#.. => .#.#/#.#./..../#.## 46 | ###/.../#.. => ##.#/..##/.#.#/##.. 47 | .##/#../#.. => ####/#..#/.#.#/...# 48 | ###/#../#.. => .#.#/####/..##/.#.# 49 | ..#/.#./#.. => ##.#/.#../#.../.##. 50 | #.#/.#./#.. => #..#/.#.#/#.#./#..# 51 | .##/.#./#.. => #..#/..#./#.../...# 52 | ###/.#./#.. => #.##/.#../#.##/##.# 53 | .##/##./#.. => .###/..../#..#/.##. 54 | ###/##./#.. => #.../.#.#/..#./.#.. 55 | #../..#/#.. => ..../##../#.../##.# 56 | .#./..#/#.. => ..##/...#/###./##.. 57 | ##./..#/#.. => .#.#/.###/...#/.#.# 58 | #.#/..#/#.. => .#../..../.###/.##. 59 | .##/..#/#.. => #.##/.##./.##./#### 60 | ###/..#/#.. => #.../.#../..../#... 61 | #../#.#/#.. => .#../.#.#/..##/###. 62 | .#./#.#/#.. => ##.#/#.##/...#/#.## 63 | ##./#.#/#.. => .##./####/.#.#/.#.. 64 | ..#/#.#/#.. => #.##/##.#/..#./.### 65 | #.#/#.#/#.. => ###./.#../###./###. 66 | .##/#.#/#.. => .#../.#../####/##.# 67 | ###/#.#/#.. => #.##/##.#/#.../##.. 68 | #../.##/#.. => ..#./.###/#.#./..#. 69 | .#./.##/#.. => ##.#/##../..#./#... 70 | ##./.##/#.. => #.../..#./#.../.#.. 71 | #.#/.##/#.. => ..#./#.##/.##./#### 72 | .##/.##/#.. => #.#./.#../####/..## 73 | ###/.##/#.. => ...#/#..#/#.../.#.. 74 | #../###/#.. => ..../..../##.#/.##. 75 | .#./###/#.. => ..##/..#./##../.... 76 | ##./###/#.. => .#../..##/..../.#.# 77 | ..#/###/#.. => ...#/...#/..#./###. 78 | #.#/###/#.. => ####/##.#/##../..## 79 | .##/###/#.. => ..##/##../#..#/##.. 80 | ###/###/#.. => ##.#/.##./...#/.#.# 81 | .#./#.#/.#. => ###./####/.##./#..# 82 | ##./#.#/.#. => #.../..#./.##./##.. 83 | #.#/#.#/.#. => .##./####/##../.#.# 84 | ###/#.#/.#. => ##../..../.#.#/.... 85 | .#./###/.#. => ..##/##.#/.##./.#.# 86 | ##./###/.#. => #.../.#../..##/..#. 87 | #.#/###/.#. => ####/.##./#..#/...# 88 | ###/###/.#. => ####/..../##.#/.#.# 89 | #.#/..#/##. => ####/####/####/#... 90 | ###/..#/##. => #.#./####/##.#/#### 91 | .##/#.#/##. => .###/#.../#.../...# 92 | ###/#.#/##. => ..#./#.#./##../##.# 93 | #.#/.##/##. => ###./###./#..#/.### 94 | ###/.##/##. => ##.#/..#./##../.... 95 | .##/###/##. => ##.#/###./.#.#/.##. 96 | ###/###/##. => #.##/.#.#/#..#/.##. 97 | #.#/.../#.# => ..#./####/...#/#.## 98 | ###/.../#.# => .##./..#./####/#... 99 | ###/#../#.# => .##./##../..../###. 100 | #.#/.#./#.# => #.##/#.##/#.##/#... 101 | ###/.#./#.# => ####/#.##/####/.### 102 | ###/##./#.# => .#.#/..../.#.#/#.## 103 | #.#/#.#/#.# => ###./#.##/####/.### 104 | ###/#.#/#.# => .##./.##./.#.#/.... 105 | #.#/###/#.# => ##../..##/...#/.##. 106 | ###/###/#.# => .#../#.##/..##/.#.. 107 | ###/#.#/### => ##.#/..#./...#/.### 108 | ###/###/### => ..##/###./.###/.### 109 | -------------------------------------------------------------------------------- /day22.txt: -------------------------------------------------------------------------------- 1 | .###.#.#####.##.#...#.... 2 | ..####.##.##.#..#.....#.. 3 | .#####.........#####..### 4 | #.#..##..#.###.###.#.#### 5 | .##.##..#.###.###...#...# 6 | #.####..#.#.##.##...##.## 7 | ..#......#...#...#.#....# 8 | ###.#.#.##.#.##.######..# 9 | ###..##....#...##....#... 10 | ###......#..#..###.#...#. 11 | #.##..####.##..####...##. 12 | ###.#.#....######.#.###.. 13 | .#.##.##...##.#.#..#...## 14 | ######....##..##.######.. 15 | ##..##.#.####.##.###.#.## 16 | #.###.#.##....#.##..####. 17 | #.#......##..####.###.#.. 18 | #..###.###...#..#.#.##... 19 | #######..#.....#######..# 20 | ##..##..#..#.####..###.#. 21 | ..#......##...#..##.###.# 22 | ....##..#.#.##....#..#.#. 23 | ..#...#.##....###...###.# 24 | #.#.#.#..##..##..#..#.##. 25 | #.####.#......#####.####. 26 | -------------------------------------------------------------------------------- /day23.txt: -------------------------------------------------------------------------------- 1 | set b 79 2 | set c b 3 | jnz a 2 4 | jnz 1 5 5 | mul b 100 6 | sub b -100000 7 | set c b 8 | sub c -17000 9 | set f 1 10 | set d 2 11 | set e 2 12 | set g d 13 | mul g e 14 | sub g b 15 | jnz g 2 16 | set f 0 17 | sub e -1 18 | set g e 19 | sub g b 20 | jnz g -8 21 | sub d -1 22 | set g d 23 | sub g b 24 | jnz g -13 25 | jnz f 2 26 | sub h -1 27 | set g b 28 | sub g c 29 | jnz g 2 30 | jnz 1 3 31 | sub b -17 32 | jnz 1 -23 33 | -------------------------------------------------------------------------------- /day24.txt: -------------------------------------------------------------------------------- 1 | 14/42 2 | 2/3 3 | 6/44 4 | 4/10 5 | 23/49 6 | 35/39 7 | 46/46 8 | 5/29 9 | 13/20 10 | 33/9 11 | 24/50 12 | 0/30 13 | 9/10 14 | 41/44 15 | 35/50 16 | 44/50 17 | 5/11 18 | 21/24 19 | 7/39 20 | 46/31 21 | 38/38 22 | 22/26 23 | 8/9 24 | 16/4 25 | 23/39 26 | 26/5 27 | 40/40 28 | 29/29 29 | 5/20 30 | 3/32 31 | 42/11 32 | 16/14 33 | 27/49 34 | 36/20 35 | 18/39 36 | 49/41 37 | 16/6 38 | 24/46 39 | 44/48 40 | 36/4 41 | 6/6 42 | 13/6 43 | 42/12 44 | 29/41 45 | 39/39 46 | 9/3 47 | 30/2 48 | 25/20 49 | 15/6 50 | 15/23 51 | 28/40 52 | 8/7 53 | 26/23 54 | 48/10 55 | 28/28 56 | 2/13 57 | 48/14 58 | -------------------------------------------------------------------------------- /day25.txt: -------------------------------------------------------------------------------- 1 | Begin in state A. 2 | Perform a diagnostic checksum after 12368930 steps. 3 | 4 | In state A: 5 | If the current value is 0: 6 | - Write the value 1. 7 | - Move one slot to the right. 8 | - Continue with state B. 9 | If the current value is 1: 10 | - Write the value 0. 11 | - Move one slot to the right. 12 | - Continue with state C. 13 | 14 | In state B: 15 | If the current value is 0: 16 | - Write the value 0. 17 | - Move one slot to the left. 18 | - Continue with state A. 19 | If the current value is 1: 20 | - Write the value 0. 21 | - Move one slot to the right. 22 | - Continue with state D. 23 | 24 | In state C: 25 | If the current value is 0: 26 | - Write the value 1. 27 | - Move one slot to the right. 28 | - Continue with state D. 29 | If the current value is 1: 30 | - Write the value 1. 31 | - Move one slot to the right. 32 | - Continue with state A. 33 | 34 | In state D: 35 | If the current value is 0: 36 | - Write the value 1. 37 | - Move one slot to the left. 38 | - Continue with state E. 39 | If the current value is 1: 40 | - Write the value 0. 41 | - Move one slot to the left. 42 | - Continue with state D. 43 | 44 | In state E: 45 | If the current value is 0: 46 | - Write the value 1. 47 | - Move one slot to the right. 48 | - Continue with state F. 49 | If the current value is 1: 50 | - Write the value 1. 51 | - Move one slot to the left. 52 | - Continue with state B. 53 | 54 | In state F: 55 | If the current value is 0: 56 | - Write the value 1. 57 | - Move one slot to the right. 58 | - Continue with state A. 59 | If the current value is 1: 60 | - Write the value 1. 61 | - Move one slot to the right. 62 | - Continue with state E. 63 | -------------------------------------------------------------------------------- /day3.txt: -------------------------------------------------------------------------------- 1 | 368078 -------------------------------------------------------------------------------- /day4.txt: -------------------------------------------------------------------------------- 1 | oaoe rxeq vssdqtu xrk cjv yaoqp loo 2 | mveua dogbam szydvri hyzk lbega abzqw xwjn wniug kwbre 3 | npaoy uivpxwd oynpa rcdk uixpvdw 4 | yserir iikzcm ieuroca iuwcfov rvb giti crdpdcv mxpps 5 | spyuhgo lucasl ucllsa bymnjig yflbv nxitmlf 6 | xlxyhwz xla mpye fvjegwg fezlfrt inetrh vhg xpvstx ydhvq 7 | xgue cvtmh myg ontvvyw ygm oqzrdrw 8 | srdfsjf dli kccb kauk kauk apa doefc cdffkhh cdffkhh 9 | msizb elqiov lqn epamk onmnlst baawab ncafwaf jrataml iyzhy svycuec 10 | wdzqpcn dkgdumv wdzqpcn qxdmwib cjsigi bgcihgh fmua 11 | kpvbzf kpvbzf svyq flg shwtgp 12 | ywrynt cesjtgk hsvitr brpiul lxgvvrl cesjtgk cesjtgk xuflpfn 13 | tik mrpht gkv unqp wypscc vmwiu ldrigk okbc wztc 14 | zpy kyzvijv bilpf etbrgk edza vuz jzgn 15 | yoa rgppd kzpopd cffjk murcb jmt raace iwt 16 | aobgkja drc ztkd qskxxbv lve lev rhhoqex bmd eolf ybxjr yiiut 17 | zhjcfms fpabnu aozp delsc mge yqi eovg pwefafe 18 | gukf iys qztqxz xhsssz pfqq slg jdbp pfqq yabztc asow ygh 19 | fmr ijgmjrc zbhwsmx ylgccz ycydcyx hjjset 20 | zybsr iqisbs hffmij ikby lwufzvg gwd 21 | ruk rku kur ydurp upmebe 22 | baqide zdijcf ezqfe ovrldez delzrov szimd irmk busim ppv zepqk mlwpl 23 | bxlvp dxumme byaada cgyn diz 24 | xlxr jhili bmcke nkl vuhqsn lxzb zmyuxgk qcqr tyxe 25 | wvth gyerrd yewrta kgri yewrta 26 | fall jpyuusu lffybb ivmtmzx alfl yjupusu 27 | lzvcg xwnt mjyiklh vwlz qejj mjyiklh dmcwq qejj 28 | vgutb smc yvnsbgd bxmjd qmhia krxz luhgg emnrp 29 | uuvhtia aiuutvh brstbr tsrbrb 30 | howd japlq lhk qtsfdq htfufj qkyywy anxxxqw jtmryw cdtajh 31 | pksswl jprpccl wpklss yyrbo 32 | furp pfru bftha iekamfc bixwmr sslovex 33 | nrqobo hyb byh hby 34 | mugix kzlbtuq hmju ysstccs hmju btsuh 35 | hsrlhw zilj jtvto zilj fjq 36 | lvol xic hqqdeo gmsug yqe wue vhmrq buj juv wxexdot 37 | lqeybb odpv mttm bxqy vqbqr ylbei wyjcxco urufsuz kyq 38 | youbiz kvrea xsfcp zaz zybiou earvk qpf 39 | bowsref ooobtic apiushu kplpyza 40 | hxfhoyy ybbe ceebt recegzz ftnlv ukaf gpvx opvd lqnvk ybbe ygnwa 41 | jpbgc aahm aahm aahm 42 | qyvheb xyb elt oaksuj dvgpmel poiowc ykgbgpz dxpit ytg 43 | vgsv yrjo vjss kyfvim izwo yrjo vgsv 44 | hkk xmqx crlki dtp nuh okef okef xomktit viia nuh tplhrx 45 | bmkjclx sbwe bwes bsbnqd nqbsbd 46 | gfwrl vocwln hsuxkz zpclb qprrvlt bkcluvs pqy sxucrla npb fensz 47 | adjklj nyr btmav roxv jrri vqfnis gzsab ogskmaj 48 | bvjm fer ztgfx mtp vvhps hptzrar wpy yhvmh qklfwpf edgrdts vmhhy 49 | lngra nrlga xokqu mgq 50 | mksdk bkkbfsq hazlai nixee vyxh hpvebeg jujoqe wkw mzpxixm 51 | kxrkkx qivtt xsm xsm rqvgdjl jilosjs rji 52 | xiqga rez igqxa odiilj izoiwf xgqia 53 | aepioo krcr aepioo jhigtx krcr qubkv jgo zybyvy wbsguz 54 | ntyscmf duwvvb kga xvaypk sfjlg daguzm kqat otj zmnki 55 | ggxaery jazo ggxaery zevobo zux wfnd wbyd hmhmo oaakvab jsimsw 56 | vqdnvgy qiex yqeweds yqvdvgn iqcukgc bvrc osi 57 | esjzak krwe ivbri hnbah iuvb begybsk ctxmlym gjqi lcscum 58 | hyxdilx tsv evckza bdbscwj jlihiqk dciuj hamd dqsm ydihxxl 59 | lurtwhx ygwf pwhj whxtrlu zfvywxr gcrl zvl wienpqb woto 60 | mfaektr ocvho ukfx ukfx old daqwotk pybjtiz kumkiq tmql lqou tmql 61 | guwy ceqsyvs svteymr nrovwz tesymrv rmsveyt 62 | pigilsu zpyiohn zpyiohn xzl pryi zpyiohn ohdz 63 | pziqfg hhrzdr wxl zpqigf 64 | psnmnxz oed edo deo 65 | tkdp tkdp auozn tfyo wmp jtp wjyskeh dag ojdvw gbptp deiqi 66 | xkr nmsbk mreiv occcvva eca bupc gvaoopu jdhr flh ptgdumz mks 67 | dlevn vmwzws dlevn dlevn 68 | qwx qnuqgc rtzc yvym sft wxq fhv fts nyvrfxz ydjvcq tnwz 69 | debkk pullndo ezaibw ldnloup nllupdo wiiw nij 70 | hng rpd aud epq opzjh jnzge 71 | rmtauf nwinyl nwnliy pjzahm lywnin 72 | cgiv omva fos irse uytiqu iqjo riplx capa dhdl echbyjw cutfam 73 | fqrqmi jfrj zllh gfhhq fqrqmi mmyqv 74 | yoepae uabuxlz jzqy yoepae sxena jzqy 75 | bfr jlrycal ndg xejwjdp khwg wckevqb tud xljzem ntfbazf lkr 76 | aomdwt sji sij jsi wlsvvva kgjzqj whhf 77 | ogorbil orlgiob iorlbog xapwiqs jxb 78 | tnn sxgdikv ynick ynick aumwthl rwhx eqxd jdbzyk kbil pmnifp dpeips 79 | vzeoilq son olqvh jawmny 80 | vsifce kcighpn mubl zkgwm 81 | ncagxs ilohd lyq oqhjf nfeij qmtvf qpru tfmtaj 82 | pfjkcpr dqrfde efqddr edqdrf 83 | wdyygax hscx ptmro wqko ecnfkhj ywui 84 | gdv nrnrzdc vyq vyq vesrj vyq jwxg 85 | oqhrr daoew zpoduh zwmoss nfkh vubf xza kju rhrpt fvsc 86 | oqp ppyq swvin mut uacwd swivn ucdaw icfj ldcujh cejl 87 | dar bqp ajdhuej sxwt bqp tppexrh tppexrh 88 | sitplaj xnb ldopp mqd gwtk uhnvozu ljz dqm ylzy qltf gwtjksx 89 | eqkvncb jdp pahwje avhrer awb zqnwfhx zohmcz fitbyab 90 | xlnel gjzviy cndpuoj jvwxs qsd kwli quisju kyoix imzg 91 | czqjkk evyima ixpelbv eobpd wwuxxof pbxc dgj 92 | czsigs lbdaynp amsexn aemsxn easnmx rsitdzf 93 | xdpc xfbp lrjwlo ntnnob sbe bse 94 | suud fws zgn kvfimsi 95 | wnexa diexvky oemdq uasxzhq qxa kevyixd lpw unluohs 96 | ylruxt beqvn vbenq ogsov mvftu sovog gshtb qriaxko vthgfr jwj 97 | gmz wcjb cqjlb hijz qwuluuf xdpu jybdf ajiv xizwb 98 | fcxos spz idg rjb uhr ert bxia urh xfxp ixba bnvxy 99 | uxiie eixiu wgmwbj euiix qknyd wtaojk naeqfz qmhnulk uscgwxa 100 | qwyxd jno xelqd isdjht qxz dbwnr bfzhewu opxmkgj igfiuck 101 | ljpphwc ijzic pfsemsc mfedoxy pad wsk beqjpbj gbjr imce xumhr 102 | causc ogypj csacu pdokc itpgjl xfx nyt yytg srhrup bontz xbalwnj 103 | asohjj qer pfgwo qgdw wgdq 104 | gpzvyhh tsnx tyu kswlgb whju zkkpdm bmh hdov 105 | unux lhrn unux lhrn rxr 106 | epq ksew pqct jib pqebafk jib pyfjy gnu pqct 107 | anzbbs oyhm moyh mhyo 108 | dpk zael zael mxots zfcum 109 | aehljyc wrj lfhife xbss ztszba vlg eljycah ihffle coypll 110 | aoqedco bogk bogk aoqedco sanwwo 111 | udmbz yxe dft rzolgtp nwwjpti 112 | efu qcls rtx mestnqt pkh ciekj scrv uswd oroowx lcztvt 113 | urnwt uapni ood lzce 114 | zjiqxt jzqxti infgde xbmi kawilp kaipwl 115 | lsfn kxfw zgzdfq meqwql zpqqu otert 116 | taajsho gbeoguv bpi nxeuy 117 | dpoyzi rqlzx rqlzx udhuwjm qnu bnuma udhuwjm gfezx cbjpfp woir 118 | mjbv isni ixjtjue fwsk ncgwpn vqnmq pivz jbmv qoakqou argval dacvksc 119 | xxjcn amdgdhh iup hlk xxjcn elx 120 | gyhocay ofqosv nldfqay aqu dsrz lmekze bus lmekze gfoq lmekze vkor 121 | xidyqq bimvxu zrkg rpcdca ymg nmxkkqu gygcmp euemr 122 | gvd ywog ywog gvd hwjzzq 123 | byu ggpwrl lpexjcf hgy jee febgcae valcgc tcfwicu texqi lxfjepc qeraxcs 124 | lkjejsb eonp jtsbps pfvlos neop ikwnb avzxnk 125 | big pjgttfb eetr jobjfae odvl jheh tuz ystrh tuz tuz ige 126 | czubaxq czubaxq pbxgs jhuopn snmhhc qwmcka xdhxfuz jhuopn eummw 127 | xdwduc sqcano zopaco ozbbc bczob eas cbbzo 128 | oanpgo tiav bbssup ttzchih tpb xmfnqwa ghdx uepmz fzqbx 129 | ahha zsbdq jggv zfcjdp dzcfpj dkew jxmelbf jgsohj oghsjj 130 | awdy plulzw gdi jiiq lod rog mrf uihaz sebk guvb 131 | tlhwro sapaws ovlbbfh xctruk spzpzm latyy 132 | ligaot xfhacs jvk xbnpu yuanx yvvi gjek 133 | nfwuug nxccj dxpfvfq pvxcvy ayss lfwz wwole ewowl xceybeb efs zfwl 134 | lzowlql armo yrlgfg kbl vudahci yav evdi ofak ysmfjk upe 135 | qtmmqrl gxi rrhbi pydbopp yvevlq ovwwdrt mrppov lzzs yjyrxh srzo 136 | hytkyas wpuqvf fftiso fftiso 137 | yutais qjdbzo kewsi opy ysl zyvyoty wkp 138 | qtbad bxfjkwa stcdk lyre tabdq yler 139 | friyh ivp hshy ksmanzq mzdbbub ncbx mhzki friyh vyjk hshy 140 | ijeysr aww evn ttqvshg xkd zjy honvuqy zyj quvyohn gphcir 141 | okft smja fkto etb 142 | pbi zhyy kyjdho mqsuyic vegocmw gdkskg kgavjag dbqh wamfijz ktihnrg 143 | csqix soz ingra gvslgk 144 | ugxgzqt pdn hiynufo lpfabmi rmwj uhsqoo pmlzad ferdup guzqtxg voxd 145 | wkixiq vck vck sylv ttqcbwv ywqta vblz mhohx frv 146 | phns ozeghgm dfodkyv iyc psnh tedotyz xqz gqbyj ydttezo kxgju mvip 147 | chc jdjo pyq usyn vtrbnq ohnx dsxpdzn mgbc ysun mlalmu mqemyuw 148 | qrkosx wcwcv brvbwo nvxwg bvrwob 149 | bovt gpb rwm gpb pitttl rwm rvfzn tbo 150 | zczkb tmpwtj kackkx yzqkzso rsg ema ereo jptvfd jptvfd flbjfii 151 | fcdyetv jqelvx jlevqx cfvetyd 152 | dtyp wfh rxtpwr nolbro iozrs mnshu tkesvyk pkmkf 153 | lvecoh ohpb brlqwx immgqe dzfac bwlrxq hng clxmpd qodfyv 154 | sjbc dsoqk dqosk iyla lqzrsgi tjgt mfxshtd ztmc 155 | nxveg vmxf jwnub kujji aqkonjl xtit xitt 156 | jsft pmojruo vtvjox wimrlhj rezqi rnv hjnvdka 157 | vnl vzgltnl mry kkqf fekwjw knsrvt nct kqy infvys 158 | jbvm igq gvcl crry ylia nbqcq ouduen jklepay 159 | ermsf emrsf uksuvz zrnlun 160 | ecksf dkydasw wddasky pmfhi yltmedt bdovedg vfnyoze ufcki civrjs ohozga 161 | hvf gfqgc adbeykt jdz zmgonhi yua kifxyoy umsza ivnbvoc whnpi gtbinze 162 | nmy fsdu myn iiw 163 | yrkwca jkxc yrkwca yrkwca kxqtvqh 164 | ildxc taopx spykdz dzbpcxp wzgka cbyr xpvrzbk 165 | qqp axdmvo cmppp shx 166 | uldyu luyud uduly rgcmugh 167 | woc vjdpyq cwshqq tlh fzyuz cbwgp egpy sfw 168 | adyv cnrn bhaxvx ofdbkn yxrtir cnrn 169 | ycz ednsydc bqsdcpx adnq bydb tqy tqy vqzpy erdcnv 170 | mouv ouiy gld stdv gwr lxlfq gdl ldg 171 | gtx bbvr fxytm veofwp bvbr opefvw 172 | pcf scu ovso rawtjxs kzxgnuy ifcn tvibap 173 | ugcbob xkjgtx ugcbob ilkkx dikca wpxyq retqhlu ugcbob ylmt tigcmmm 174 | gmnde ool qeuwc ctux 175 | wpajwn gooy fedmjur pxiq xkyniyp xtgi eyfpc gjx 176 | uaivt kvfyn mpsya qxu kvnyf wvoeaz mbt fkyvn 177 | jth awxbprn kpcodj qxegybo 178 | sfvitld mdzczg pdptzm fmz himb eutpyi mgrde gubsta tfsldvi dfistvl 179 | piabmr fckmhrv twnlnka jyb selqflm iwcutk pvvann 180 | uxjfm rmleg ochuj ruiq aobxbb tpuusot uhwjojw tutopus 181 | dzj qdyxzk oan rtpz ona qkdzyx nkunr 182 | urjydh dfreifg tmbetd aakc vdr dkdkldw xgvtfsa ivv doadb axgvstf 183 | fdjhr ujgbj ulkm dfzh tmhx zfdh ckt ortg 184 | obe ywwge rgqmt cfcnyt atn fdkdrwz lmb zwpe sqfoc yllxs akdlsso 185 | ckhbu jfqhkml abenw ckp xvjy wsyhxox jzsz hqksq 186 | tjx zlh zgyrjpe bdorry uofh hgkzl ezixges kaxlkjw ztijupu hlgkz 187 | belj ipbygk dxe cqoyukw jnncelh ihvom qstbowu rocqsz ifiztlf fjrf nsit 188 | vyswalv reaqae hzoqyun lbci ibqfljz cgjflqf kos 189 | njrzfvu nxw nxw bdsgnxp 190 | gxlgn qrx nspbvl pzuob nggxl ipak wjr lggxn zas 191 | xkd sooef fsayaob tfsiyl 192 | ecldvh jugto ghfpbev xzlc 193 | rpyattn spb ajdplq eaorgi ackirxg knrap cobdeu qca pkp zkc 194 | bhh tczwffg bhh bhh hrjx jwyu gry kkgghnx 195 | zsav frsakbr bvzd gafr homzjw frsakbr yasgz homzjw kqa 196 | nbd mekhfif mekhfif keuoag nbd 197 | mzv vzm utuxhuf uufuhtx 198 | siy tdbii qtu yrxar ruubale yrxar lsvnr yqxq ruubale 199 | wstykuz fxnuszr tgmkw eovvrd ohheh raf degh hzoeun tiou wpt cqnw 200 | dzbyhrv vzlbvn ncoa xfglcye ncoa sykfps ghi 201 | lvi ilv xalhd ztejzb 202 | zaeu diz zaeu gtdjsz fmoxgju diz uvh 203 | zef lmkqlcs jnhgqww qsm fuatcq ixfa 204 | wgp gvu rpmxrjh yokepvc yokepvc lywdl bbvvbf yokepvc 205 | etjfs gjh tvmxb agovg yihn rmmh nue jfil 206 | zgcco slios jbfodb wpthe ydvit regizw regizw qosou slios cto jfz 207 | kmmq lnafaha ddos hrsjtxk zjch rfynx eovks 208 | ezeuzu jfpv oinrstv vsw naoz enrcy svw jfvp kgmfwf cfisxzo 209 | ljtv watps equf ljtv equf 210 | axijki zotolsi ryqujrm xmhug fhz lkgaw umzokxh ktr jsdsfat trk iosoztl 211 | vpqvvvn ydjz tcqc asffcxr rxb fyt vyham fys 212 | agxrcxl obcncq htod ved ozesk obcncq iwqmksk fsijtg iidyy lxu ozesk 213 | orsyqt otqrys pnaax qtrsoy 214 | oyisc chu ahdp abhbtry kjsqve tkpux tkpux sxzu sxzu 215 | wquw umlbwf mxzdbvb upp fopxe aub bau eritni punrpfc esnkyg 216 | jjlzy hozskgo jjlzy aiq jjlzy sgfyhsd 217 | ejghc ejghc ejghc igacslu 218 | unzmg fugzotb nxkdlds ewn hydj fbr iuly oiwwkbg scnozau sfi dsishk 219 | xuhjduu hfloaga xhuuduj mbavfkd nrnl ral erc mntev elpoqgq 220 | seydro onpi qjey skgkiox fbdgyt xhr rhvz dpsjcj tfzd spjdcj btqn 221 | difyxz cdm jlzsz oycm txyssd wckqshu ihya yjyb 222 | nmrhlif wcreso chtqfov qcftvoh lqp egd erc myep plq cjdh 223 | hcnwgkq kkrpxxj gwe xqgea kkrpxxj nxz mumqbw kwxhlz kkrpxxj otqy 224 | rxbioyf cszah mhu mhu mhu 225 | qpbrf jzink ojy idt nrjykzu 226 | omnrq kkol dex eaqdmej dnpaum ynnntw ddwewsh ztcenhc zqdrq hmi 227 | ngmqpu owmcuz gop gdbsfc nyott cdsflq ngmqpu 228 | srus lrexy aqgkqvm tiyjm 229 | wxa qopky glaaekv ykopq lna gyxvpx xwa hly dbvo 230 | vqf sqrqw phxn xiw gejyzip ugg gghhugl zyqae 231 | ylj cyolrx giim yrchuu yrchuu ylj 232 | rixa yfusuqn yfusuqn yfusuqn 233 | lpm gboakz ylyv gje yxu ahokxb ixwnpu hlcka cndhbbm nkmvts xdtqbc 234 | veul zjvz regtyp njwfpm 235 | pdlyjbn edawa xbcmyew gme yuk yek nfknzgn ehjz 236 | rcgun ulv ntbwnvg ptf givapv bych gmxxxf iajqpb gwh ipavvg 237 | qvpwk grbb gptdgrh sij vunv hsb uegsmt uos vkxdd 238 | iun aagzlj elqcq vkrk awl yyt dxfhkwq hbkeht 239 | cgf omofuz zddgwef iyosk hmou 240 | mvjorn zseyo wpfjlac kpxb dlh ggo zgxoso txzuy jfbmv lacjpwf vha 241 | twrsrw pxv iklzg rtfcl kfbcjix uyvowpa kfbcjix ofnsf adqm 242 | qvi ivr plxfrg awugjh fxbv ztlljk qvi jdkfts xyq jdkfts uqwgdr 243 | phs eimuuf lmxq wmp 244 | laf gmuowr rplgkh orentm whor lkrhgp mjwr zapz mdqtqyq ttkfkf 245 | fxk wdbl fjh ojqxp yvs fkx ysv ngksb 246 | oclyxqu tpajqun vvmj twin zclk 247 | srcwxs xiduxd tqpfc sbqybp sdtzw gizfn bpji kaolpuy 248 | pfkmk olmsaz uffy uyff 249 | crpazh pcrzha lew lkhcjij stfxq 250 | nkbb rnlo icnzg rnlo ejanu mofx ujblud 251 | abte xnjfo boz fnxzid nqfhifm jmnmsgh 252 | lvck nfll szdgrxc nghig szdgrxc oytahh cibk szdgrxc 253 | sduf jgv rrt spxw fdus 254 | gplutjv ufep fuzrnj tmko zzpj cpd mvtrzq 255 | ycdiav qvr ycdiav tjngezs mphk oykgcei ycdiav 256 | egbkscg ksgcbeg qmw jdbj 257 | kbgx otnfyc agouh iai lyhqd yzihyq ouagh snzhxa xyxrgz 258 | kdpqljx rin dlxms ukdzedc duezdkc ikgplm ffk vdmie qziajdf ftfwl 259 | prrzhj okffaot tlrxpjd aquc dbonaef enfdoab nwbtuh 260 | vyzf ijo cdhek bvlgxt kvldmp kvldmp vfvg 261 | zhijgyb yfkkal utb brew vfj ztiftq 262 | kodsuol ubnbdv iozwfum ayqxgnj qkp yiiv wbkgi psi wnfa epw 263 | iok mecjsp lccn nrb kobca wkznctc afjjlrt 264 | yrw yhsva hgx nxjfbb 265 | dbdj vef xjssylt hjlld bqbmx ihfmz uhij zoh opzrmy mfq 266 | wqhcq usyfuc wqhcq pmf aryq nhvtkh 267 | nkviwge snpfdza nadzfsp evvdnrl qled ekqs qumle myhky 268 | rgljws kjuk txgeein ajmph pjhdy pmvr upae yfh 269 | vmepn wekgc qfwybl midbac vmepn ddqmbu vmepn uhfccp yuh zzz gnx 270 | hyqv fud xdc bssziiv mwo xfrsn xqehs mwo 271 | djhr qxhfy vdjs ueoi mbmwa lkeumzd hyxfq krbyy ywvcstf wdkum xfqyh 272 | heprtex wgxpign lvm vlm ypswfxr ggxipwn hdszz blrv ppy 273 | fwalim sbqj zewxcaf qjsb cjgujwr uclxro wceu wmaifl rnd 274 | gmivd spncot jxeycn notspc nzb wie ceyjxn xlam 275 | cfujai hfvux hhtwe hfvux oputz oam 276 | gmwu xwthnkp xwthnkp mdxa xwthnkp 277 | shfqzi hdq uyyqjrd wczfvy wciko hdq nuywebl 278 | dtkq qnb uzmo ypxfja cekqe cekqe tnaibc uzmo pmtnb 279 | apdz exdze pop pvm pce hywvftx jrjezgd jkajq jcdjli 280 | satq czv cfhyca cshnyh cshnyh rcu cshnyh 281 | mxp ujq fmrnzxx xqv mxp 282 | nel whnnxak lwzlre mrxq kpo pko bsa gimtzwb 283 | okssco iuke vcnv okssco liawwc vcnv aztl 284 | kjvq rye eawplkw qzxt jkqv bxbfyv 285 | bphssax ylemih wsm jnpxce jgh repsyj ieypbz asx 286 | dwivit ptcwt qwectqk ttwcp bklpa ivditw 287 | ies knj zemmcto mczotme yanr kjdrwr mcry ndols 288 | dqzdpg adb ulsv ulsv qux ppmoru sjcn dpihqz 289 | akazkk kssdguo cgigktm indfh wwh kevuhv dclpjv kgtd ehjxous 290 | spogxy jyzhag qumd brk cbu akbpjxb spie 291 | jgyn cxbar axtkwh hktgcm cfsla xll rpauwl cgpziuh dyc brcxa 292 | dodey dysnjxe kzmyytw tzddd cnupwmv 293 | nqab whxkb kvc kvc jcjhywy mbbpfwj fxozlt whxkb qwz 294 | ihmif xhjc lmfk yjrsioo uvtd qvtqsgt dqd 295 | uvzedxd afli hkrigd lkzkzu ncki toam hoaefui 296 | zmvywjv jsjf nrbrgt mbs yog eexuo 297 | ukzab euwb qnkanyt lgeqf qefgl ewub 298 | zbol bolz ilncu ciunl 299 | hjryu qyl ajwju rplplr skbdsl xvto 300 | ojfotbx zvta jofxtbo ejjnhi jyeiz yzeij 301 | ivr pvrwef ivr zgnm jscgaoq hfjuzju cea hfjuzju ehszaz 302 | yikp gul ugbniac jehm fwqxb hqbhi hlfr iyuuf vacrao fwqxb 303 | plsjh efu napxwe jfxfjz efacqcp sythfxc sythfxc napxwe qncqc 304 | meuf rcjzf mhluz kbrk tzjrcn omoiprl khs oyzad yuzbz 305 | exvzzuc ckqfivf uoyidkg mwztyf wxtg uzrls gudioyk wfihpzn tdmwhf 306 | qoovwqm bldswvy xkb yqrcluk qyrclku cluqyrk qgakbv urclhse 307 | rmmymgg ytpqtuq ibt tmedibz tmbsdg ytpqtuq cxbnng 308 | qkyeo frjjht vkpt ikztq avzqon diw noqzva dvkhwdt 309 | opz usos kdqseyb cdxvve nahjc hbr rhsfm hcjna wnczls kky 310 | sgeml uyaoe ked utxab hxqa glems wbdo kzrjsq 311 | isp bmebt becira ixoz yeakj fmueu 312 | jrd qyys cik bmaief zxllza rsu swvodiv ivvdsow ikpvwaj jdr qte 313 | gzjjre tkjhdn lrqmvw gues ositymc xhfiutm 314 | kcnble oxoh zggvo zjz auub kunoj snil zggvo lgql 315 | yyfmd wbwmizs vmb clba bpzzjz nlt wgukoe hedlp osxz 316 | skic mgcr chkj eiiy kdhch gcanziz dpecug fccp 317 | jhnejy akpwbj mhrunvm wjzwyhe lwxostl gfe niuhj iuf bewur 318 | nuursk gehzvck szm fllr bfaq ijpjp gehzvck bfaq 319 | ecx etrsadp lyekp lxf flx tadreps 320 | gbo wzkner hky ggoqu 321 | yiitvf tyvifi xpnbk iiytfv 322 | okpjxyq mmxcha pujgv ltgfdk wpporh bfle tuupth ukyyjgv vlnwhz 323 | phbs qtpolnh udito ukx kjqsi jbwf sgkkwgm udito mwwb wihg 324 | mces dhc qccy sxyilmb qmki dyqnr qsh aigaemz oofdw hbifiz 325 | yyben jjklnz whwswg tox vgytp noijcv jjsa ybney eyrvg htjl vxli 326 | detb tus rloz zymvmg zpe 327 | usvkehi kxgvo rna scnaljd jmowud ipfkkf rxvpie nxysvj pvquagf fjhsvef 328 | ytosun puwdoix oyc qdufuw ysunot 329 | htw biy htw oxot oxot 330 | xgzi nbq lxxtmt nbq lxxtmt fnzmmno 331 | lko bdbj kcqvc torg enbfbj sbooco afjbclm dendwq 332 | cgih ikmfn lyhzhxd ubq ixrori tofbo 333 | glfhfzs gihsccj yic mlci slne 334 | wdiu lhl hdlhzo voo yhqckcy axnz yqyi fyss qhvtsbc 335 | aotbk zfokegh uax myhehay terwus hmzic fdwojh wjuwlp 336 | ucbiex eigq qqe ifqw sxakwl xkwsal qeq 337 | pknvybh qkrwi povvd phairw qst inklob yrryv bcuv dolvr okwe iexrpbw 338 | kkah qrt dihygsm nly rblqvrm sxguxj yspmre 339 | gzhhkjt uimif bssle vdiaa wkohq nrgboi htkojiw 340 | aeb xihgva vwcjbjh lri nlwbxun sargiey uyekrc 341 | fnnwfbj yyccaxu fhqb nlmwhc ymbqky ooljix mfijg ryykirn womn rygezi qsdwgpw 342 | itfs udfr sitf gml 343 | gknztly vay ypy jpid pyy mbpfmwz pfmzbwm qqec 344 | bbhmw uus xffgd xcjzrlk kyecv zcerxe 345 | ncpc otqzotf godtu yhcpsyw ncpc fbs 346 | ggoiqm ofk pryqt kqdbo ktek kklhlju iqgmgo gqoimg flscx 347 | gsgmvy tktzj kgi ikyz pthtk hxt gik 348 | bunvugy fefqpkk juwk aent 349 | atm tma dzyret jmuqke xbayiit jumqke 350 | dilfw qws ldwfi lnujld ywrogk kjh adaj khmlb hkbml 351 | veaemc xugf udpphf mydi jbvebgp ngyhly pufdph vbgepbj 352 | vyd tisntn qmc yzal 353 | uxdlc piw mwjnk qiar xwpspf sxktemh jmw 354 | qhhvar pox aed bgwq doe uyktv pox vriy ndel pzx aed 355 | tswei dtfb yhj krxu yqio wtzpm wtzpm yqio 356 | bjzp zzp qdzdfv tzkbl nggbfqs vquqds xiud xgrkb 357 | ffvjfwp jbzslqo ffvjfwp pchzrqv ffvjfwp pkd nlav 358 | czepixn yurmsw ucckih qqlnxjj exipznc 359 | xeu llc jnmp dmz pnmj stqzao 360 | fzvu uscqp xerkzkg roivhri fzvu yiwae xguz ajpg 361 | qdzk uyyoi cspmnc qdzk nwknfx fnngvla cbl 362 | acg utwrv cahupdm xgat elb aemkf wmkdzj kfmae ahlrwu yxfcj 363 | vdumh rcd rgc hpqk qeum fpgva qkhmuji rjxpuzk ommk 364 | ztvm ntxkav ajv avj ippodg sukg bivcslu tes gdlrbnt bdlkaye xpgslef 365 | aygsym pwq owxmx xjw 366 | dkhykf pfqeyo lfq saoewy qldrky sdgrrcr frdqn tkfezop doo saoewy 367 | cwof mqlscm iqxhb nnkex nxx glgpbn 368 | noq zikmeyx yodahj ssu qqmifa plcbv rsahsd 369 | nvc fuwiyq myv hjn rtuoq zoyp rqnt xchlrg 370 | dziscfa nbzsuvp rbnrban cjdprp dkj zcry ckxtm 371 | stpm ifcbmmw dpkpzo sot ydpeydw nusp nkciqa psnr 372 | udikjfr foqnxl whq ojuspzz ddyz emdktzb gfio mnd hyb 373 | vchdphx zkrtky ucyifqx ryzl txdixd cip aid cip 374 | wcz ywzwpp viswpsm qfus uzopaq mhps sidjky kipvjg 375 | wehhc rzujn urprwzw gkwzhk rhrpph xkzzl rzujn yddlb 376 | wlhif foh rpvylg gruiqdv daih yflhbr coe yflhbr hvluddj 377 | hfzi ffjntj fdth crkrzdr nyel nlxm cawze bfjz neixnw uygqvmw zayf 378 | guthfwn kcinec glhaiqv rfgbi cbrm 379 | mvqv lszqu eyjn suq lavyjbh ujivbza aianl wik noy zth 380 | zkn ren ncoyj fppsy dwgtgqz til 381 | ybxepr hrzcrxs zhrscxr uvpxxl eprxby vzgg 382 | xhi zess zet mtpcu ibz nkwq cbzb etz kjjcns 383 | kvmu rxgw xboplw enlqcxi uxysl xboplw kvmu oqxislh xeg qwhdc spsddge 384 | dxaao ltjjn cpsvnxe core aojgu pbss nudwi 385 | llro yoy tixzyc beim qirnb lffcr gzm 386 | quxetbf gfpll gqyav dckhp xbfetqu xaebz xuqfteb 387 | fblkc hsydxqt bvmwujr rak 388 | epeohq olrwyft cmrvov fbdyxbg 389 | uzqk pkhizw jbrnlvx aqkq mtmjmy gpcln gaqt rinrz gwis gpcln 390 | ttkcu ttkcu mcq xao lhnxdph djj ylet atdln xao 391 | pmwn svqktkm isopar krrfbna knrw kbm zsohxrk xlsmm knrw cmoikq etqeggc 392 | undrw issrttk mcoe pvufl bwjwqkx jdz undrw vje 393 | kfzqbb djpcjv ixctsvb rqsntv fcqz 394 | agezraf ezrfaga pftdwrk slsxu axw 395 | ezvkn smwko utdlu nizby 396 | ygl dwtrpsh qzz cuntrr hdrn lujcx iwc bll qvjhg 397 | jrdrvj ledrjp noqx igodve odgiev 398 | zonvzgy ujnzj ujnzj zonvzgy ckzd 399 | rmg lmib fdn nfd gfobw wrc iro nsz 400 | acgxvh sdn zcef sdn jvgnmhi xitkqgy tbascbh 401 | ykuzk ovp mikolx xxgpylt secuf yrtilra wnoypy mty lmnagx 402 | wwmlins mxwye kjntv sadc wnvyoov rzdawl 403 | ali ncsrq tcbjzpu oiw iimxlbp mwi hdvdl dqnicf lxit 404 | sql vywv vycj nprzb tdqe qwvljm myhpvxy hdixbk ywqpn xvue vrno 405 | etncz etncz czqw moz uaxbtm axlslow fhephy moz 406 | wsriuaj umjkx mhxau luzf wmo kyx jidl ufuoz cbk 407 | msfrvbt bxnd msfrvbt yut qwbx 408 | rhag vfkqf rekoz buw qffvk wxs ghra 409 | meignx dhdu xacg hmiqkd nrijc gcxa gwap lov ybtyr vol 410 | qoqns swib mlegyjn ojdtt tvdrrhg oetg xdret nzpq 411 | ntc zowllt dwiyht ztdeifx velaumx jfxxsqt uefmb gwn 412 | bgykxl bykan tvvgcpa wdcsj coonage hpocfz sqmihw pnagv uozsh 413 | wass vve ngyd yyvxmsq rsaypsa newxyc adqmbm xqsvymy ygdn idysq 414 | ybo vpjcf tsbpc hcdszr qrxwjqr bzz tgjhkpu hgtxkt stpbc woro 415 | ogszrg rszt owufa cohmv msygfw fud fzi lhts sfiy dfu gxsuj 416 | fclumcq ejuj jkbu hbsv ythmpoo xdzg dkvrdue 417 | rbf sunzzl sokgih rngqli xndnuj rbf smiea mqzpzb fwpcx smiea 418 | uuuxchs uuuxchs fzna qlj tcjnv oghk fzna 419 | zuiyk tbn nqma wptoecs xndgbqm mqan wmcahvm qpir 420 | ztexf pqsc icxqsuf tkgr itnn yorg oyvqaj yoxggqk lep 421 | ehm hysd jfv iugyt jyvh 422 | fenjp zjtvvhb xfe dgxoah ljn ixvdyi fenjp odnlr 423 | uosxyy euicgp lrsc euicgp mcszotm kvxrpk jfo oxu xyeiv fhdwl wbw 424 | tsmdp gshgm kpb tlx kfznsu gglefv pkb gcnydo eavgrc rgd lgefvg 425 | xuq svh cmzt bxxlvfm rtblxpu imuexhl lbre hqyedxa hwkgaak 426 | hhlfj mlrdv dlsn zgcy hciiuzw uwciihz iizhcwu gwx 427 | ukqoj kjqou hlk nfyz lusf kebvmrw ccaj ewmicq useba 428 | jlnnl jsmox vnw ucr ggithr usqe allzc pfumkkm jlnnl 429 | mswpbk lffjwq icc kef zlba uolrrl fqlfwj tbc 430 | bfmra hdgczrw dgmnod afbmr fnczx 431 | dcqrso cgbymsg jbx ofpbp rmtygip syly 432 | yrmn wzkt lqys tzkw sqyl fxoc 433 | wal zgjy cwnqyaf bhz dbpft owx 434 | xnrautk dlsyot nzbohog xmzsbh soec wyy 435 | kde jpkvbs eyzw ukgiv ggrtzcd vikgu mxqy jyh crdtgzg ebzet 436 | psg jsykdw drpqzl qzqbge ldqpzr wsdykj lmhbldv hbognjp nqej fmxoq guuf 437 | ueo ncedaju ijasprn rvxb mxkddl qvgdlbx bpj bpf pxewuf chvo lvrq 438 | zlmg eciyqi xfbeoq pupyrc bfqexo ituqab pycrpu 439 | jsk clo vqxzl aja jfbce ldov 440 | muss tzg iksvdej zpw fxwhrv eeye fxwhrv 441 | kjjd dzf zkppx qdwlx irudds kjgd pdrz rgogy qdwlx egx rjxldp 442 | szjpf aouvl ehxq exqh 443 | nzweop qlkje welkfs jqmvqi coc 444 | ivmjzk usk auvmc vvcnwn qubihx vkms fbt udn uyto jjt kxqy 445 | rayw ijaklcr ywra qkj qytxeh pmnfh qffvsft tyxheq 446 | pea cqy tkg qidvx qidvx pea skgrndq 447 | iijm xgwq zzpskl qtjezqt yqjwy dhbq 448 | dfuv iqw iejb bjei iwq 449 | ogrmldp xdc dcx cqhbwlp 450 | wzwb xrjl keciql ckky litdr bmurdk anjs nyggesn ygwt svmee 451 | bvkkzj rcr lozrw mgpwkm lwm yecsr ykl tzny aeus jmq mchopp 452 | rsnvaa oikce angqn rnvsaa mhc 453 | hsiov kxqpxtc rzh vjrqlx xxtkpqc wiunol qckxtpx 454 | aosek lhi ruqgd rmr 455 | agqvlao pvhcgz esw kwnpefs qsrvxz hgkgrs mpx odaiqi 456 | dvqkrzf dawioo jtaco oeutol ravp apvr frjunad 457 | wss nahhsh pfwgcfr rvvvq uqxxmhq qax vtrkfou medfj 458 | imdyfc sez gve kgtryl kmqklg 459 | crmg yhkpa bsfouax kyttpa who mcrbzaj kcsktxe yfv 460 | zpw zlab pzw pwz okb 461 | fgqlb byhkhfn qglfb ladle ifa 462 | skr zwwjnr iub wekt biu jnrwwz 463 | mpvt mpvt havn ztf 464 | odqhd uxrswp ppj eztyj nxzwm fvxyadn tostwy odo abyp meqdm ktqkvh 465 | fgufup uabd vhxem imto imto vhxem 466 | vrpxxhi kii zwatqg nokg wesxju xplc sumte muwjj 467 | nsse iquhoc giuv pxaa qpqn zrfk kywjr spz kgzc lfa 468 | cjjgarr psvwoap ivijyt nfbxu ktiuy jajrgrc goyc 469 | yrfzf wyxda gsslsy oeyve jczghf cbuwf iwnu izyrtho dyoup toizyhr vzzrr 470 | bwqgxsr ufy cnouypd qwxbgsr efdkfe rwsblis bhvyws oodh 471 | piqpez yhqahjp oxu qtomld 472 | vjvpnwy kajjaim lcxmbyd fkdy ywvvnjp xcn nbwlklo 473 | qghq mihdp vuv ocrzsw mlmkn rgnbfcm qgufcks btlulb effsrih 474 | psazbfo vbpr efcspj yrjl pqjrfe relxjc nzzvb yviuhc 475 | tbbhdbm uxhawtk bmdhtbb rqxrr pspjzx krtmf pnaz srcej rsjec 476 | owikzec glvbqy jhknyuz jkaxu ldhnlpx wdp 477 | qvuv wteohr daynue nehs gzqu porzrsk cqokye zzsbqox rqh ogxtn pskorrz 478 | gnm grlfoon lxid isxa 479 | jes iixswl umgbg qfixa xnecpns asm nopsmo axaopsm qahwpqd 480 | orr auvlruu mqq uurlvua urauuvl fjrcuo mqht tkdgps tdvnhvq iezdv 481 | txwyzy zzwk bzi etfg gtef 482 | qyydr lllgosq qyydr lllgosq 483 | xqm uyl ldpowm pxhi ievvvez hmhzwmr ldpowm jaw 484 | qlvfq efgivhr rfhhu gvw bxgsrp sgbnjh ekgbp cyof rvghph nxfekia xym 485 | lgladv ogj cir jxx msz fshf ayheu wpmke zckng vgrlv lxgmge 486 | fcmp aabxdp hpxbb bblpy mpcf eju pnkv jxwoy hmv fgynps pbdxaa 487 | jcrh dgg lzyiv ojop vhk vdb uinoetv 488 | utlzcf ziizdo njffmxe uhyjxdb cztluf yjdhbxu 489 | ubl cgz tyg nljl 490 | slwe qaos ybcwdoh ogazkj tqh opggnzt ffrscl opggnzt izeh 491 | evitfwb jpivmn dpnxzuf gdkx zprogl xehb 492 | dktt kpnkizb rreq gjmosa iekdtpj rcxk eweawk qrre olv 493 | cmcw vmw mujx mujx ypqfz 494 | nzxcl fzwa ftcrc immendi tmxzzi hslye eibc tmxzzi 495 | abfc jdqvk lichxx uiomtz tlq 496 | mnkthoj nohjktm eued izmcjj 497 | ullh wju bxfsif icnrmmj qnufw zubcnmo yewz phovhv 498 | ndfvd gcyt wnm badaww twm jahlat ndfdv mtw xrq bechxx dnp 499 | ceg gcxgu gnudeib utsynwx dpg wpsnp ahbbvkt wpsnp iou 500 | wutcg congyz erkj ibtcics 501 | xsbq lyycse qbsx ppgutls lroo tyor 502 | hfiwoy hclhl gcwgqox ogo hlqr ultkaz yke iwohyf oog 503 | bcl nemims udwkmlm nokck tkwny ulkihcu knwty pngamqg yxtphkn kuihlcu 504 | nwsr enrutc eqcfb uxmdgju rfnzhsn tzk vysc 505 | wbtki vjmkk kvjkm ibwkt sckvbv 506 | xjxnow tli woxldj rotrtz nfkhcz ibh mla ybxldg 507 | cwtpkhr oxywg qpwrgfm dfjpfuc kpcopa 508 | byczby tbfkonk ytlczzf bbyczy 509 | khuvrne rnamlgt akjtu qlx odr git xmiazr icwsxsq 510 | jfm bneh tkdzuad bsr oruvmqq uauw zjlp gwov hot jkjbex 511 | jjo uvk vlpy lpxd irntb uvk ehhsqv fxhvt jjo fpa 512 | qrwu mgnw hvflf ytspp mco ikvbqg fflvh wts cbbf 513 | -------------------------------------------------------------------------------- /day5.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 1 3 | 2 4 | -2 5 | 0 6 | 0 7 | -5 8 | 0 9 | -3 10 | -5 11 | -8 12 | -2 13 | -1 14 | -2 15 | -1 16 | -9 17 | -10 18 | 1 19 | -11 20 | -5 21 | -9 22 | -7 23 | -13 24 | -19 25 | -22 26 | 1 27 | 0 28 | -3 29 | 2 30 | -9 31 | -4 32 | -5 33 | -15 34 | -13 35 | -30 36 | -21 37 | -4 38 | 0 39 | -34 40 | 0 41 | -31 42 | 0 43 | -29 44 | -42 45 | -1 46 | 2 47 | -24 48 | -16 49 | -16 50 | -12 51 | -22 52 | -37 53 | -16 54 | -34 55 | -46 56 | -12 57 | -53 58 | -12 59 | -23 60 | -44 61 | -1 62 | -29 63 | -9 64 | -52 65 | -17 66 | -30 67 | -60 68 | -5 69 | -29 70 | -26 71 | -48 72 | -55 73 | -10 74 | 0 75 | -50 76 | -1 77 | -8 78 | 2 79 | -37 80 | -74 81 | -63 82 | -39 83 | -7 84 | -81 85 | -33 86 | -62 87 | -59 88 | -20 89 | -58 90 | -54 91 | -23 92 | -19 93 | -80 94 | -39 95 | 0 96 | 0 97 | -92 98 | -75 99 | -24 100 | 0 101 | -73 102 | -36 103 | -14 104 | 1 105 | -102 106 | -97 107 | -30 108 | -105 109 | -99 110 | -84 111 | -46 112 | -67 113 | -88 114 | -86 115 | -94 116 | -53 117 | -88 118 | 0 119 | -100 120 | -86 121 | -11 122 | -93 123 | -99 124 | -21 125 | -2 126 | -108 127 | -6 128 | 0 129 | -113 130 | -116 131 | -127 132 | -42 133 | -131 134 | -124 135 | -24 136 | -56 137 | -63 138 | -130 139 | -118 140 | -52 141 | -139 142 | -43 143 | -90 144 | -123 145 | -7 146 | -93 147 | -117 148 | -34 149 | -59 150 | -140 151 | -103 152 | -52 153 | -115 154 | -83 155 | -42 156 | -92 157 | -48 158 | -82 159 | -104 160 | -38 161 | -2 162 | -28 163 | -150 164 | -39 165 | -30 166 | -71 167 | -146 168 | -55 169 | -114 170 | -141 171 | -158 172 | -55 173 | -21 174 | -121 175 | -142 176 | -137 177 | -119 178 | -99 179 | -113 180 | -99 181 | -33 182 | -99 183 | -20 184 | -129 185 | -83 186 | -64 187 | -179 188 | -182 189 | -43 190 | -86 191 | -50 192 | -135 193 | -186 194 | -68 195 | -100 196 | -181 197 | -22 198 | -106 199 | -178 200 | -157 201 | -46 202 | -41 203 | -80 204 | -166 205 | -77 206 | -81 207 | -144 208 | -132 209 | -81 210 | -11 211 | -38 212 | -57 213 | -69 214 | -13 215 | -79 216 | -146 217 | -1 218 | -165 219 | -52 220 | -134 221 | -86 222 | -160 223 | -97 224 | -220 225 | -92 226 | -200 227 | -145 228 | -175 229 | -138 230 | -205 231 | -127 232 | -165 233 | -155 234 | -211 235 | -134 236 | -31 237 | -118 238 | -190 239 | -40 240 | -182 241 | -96 242 | -134 243 | -93 244 | -84 245 | -76 246 | -34 247 | -33 248 | -203 249 | -16 250 | -245 251 | -167 252 | -102 253 | -5 254 | -44 255 | -239 256 | -127 257 | -255 258 | -116 259 | -61 260 | -140 261 | -238 262 | -69 263 | -254 264 | -203 265 | -178 266 | -229 267 | -250 268 | -120 269 | -109 270 | -153 271 | -108 272 | -137 273 | -247 274 | 2 275 | -151 276 | -270 277 | -164 278 | -62 279 | -186 280 | -272 281 | -190 282 | -180 283 | -70 284 | -179 285 | -38 286 | -208 287 | -215 288 | -151 289 | -156 290 | -62 291 | -57 292 | -275 293 | -182 294 | -169 295 | -264 296 | -70 297 | -279 298 | -55 299 | -287 300 | -57 301 | -3 302 | -67 303 | -155 304 | -213 305 | -17 306 | 2 307 | -200 308 | -291 309 | -179 310 | -175 311 | -73 312 | -257 313 | -47 314 | -118 315 | -206 316 | -93 317 | -293 318 | -199 319 | -102 320 | -118 321 | -188 322 | -66 323 | -288 324 | -21 325 | -204 326 | -80 327 | -237 328 | -175 329 | -297 330 | -235 331 | -168 332 | -262 333 | 2 334 | -162 335 | -95 336 | 1 337 | -286 338 | -318 339 | -9 340 | -213 341 | -159 342 | -127 343 | -175 344 | -266 345 | -240 346 | -268 347 | -245 348 | -196 349 | -281 350 | -86 351 | -202 352 | -127 353 | -144 354 | -157 355 | -333 356 | -122 357 | -230 358 | -182 359 | -38 360 | -296 361 | -12 362 | -224 363 | -123 364 | -40 365 | -6 366 | -324 367 | -135 368 | -289 369 | -85 370 | -179 371 | -37 372 | -58 373 | -125 374 | -228 375 | -124 376 | -250 377 | -73 378 | -35 379 | -286 380 | -267 381 | -257 382 | -348 383 | -83 384 | -3 385 | -98 386 | -99 387 | -273 388 | -118 389 | -310 390 | -23 391 | -299 392 | -96 393 | -51 394 | -273 395 | -79 396 | -112 397 | -355 398 | -48 399 | -219 400 | -10 401 | -103 402 | -18 403 | -201 404 | -108 405 | -34 406 | -362 407 | -165 408 | -359 409 | -347 410 | -157 411 | -148 412 | -20 413 | -344 414 | -66 415 | -337 416 | -387 417 | -62 418 | -125 419 | -4 420 | -355 421 | -322 422 | -263 423 | -381 424 | -108 425 | -25 426 | -262 427 | -425 428 | -100 429 | -54 430 | -315 431 | -221 432 | -268 433 | -211 434 | -321 435 | -89 436 | -124 437 | -297 438 | -22 439 | -162 440 | -117 441 | -430 442 | -152 443 | -373 444 | -256 445 | -37 446 | -61 447 | -59 448 | -436 449 | -377 450 | -346 451 | -245 452 | -167 453 | -451 454 | -392 455 | -382 456 | -248 457 | -254 458 | -382 459 | -249 460 | -267 461 | -216 462 | -205 463 | -310 464 | -326 465 | -144 466 | -107 467 | -65 468 | -382 469 | -79 470 | -401 471 | -370 472 | -221 473 | -283 474 | -269 475 | -64 476 | -207 477 | -262 478 | -181 479 | -146 480 | -52 481 | -169 482 | -147 483 | -225 484 | -179 485 | -215 486 | -116 487 | -115 488 | -37 489 | -227 490 | -250 491 | -228 492 | -132 493 | -414 494 | -425 495 | -230 496 | -224 497 | -319 498 | -42 499 | -353 500 | -285 501 | -38 502 | -145 503 | -263 504 | -25 505 | -142 506 | -296 507 | -267 508 | -43 509 | -315 510 | -352 511 | -105 512 | -275 513 | -354 514 | -66 515 | -414 516 | -464 517 | -215 518 | -107 519 | -267 520 | -394 521 | -10 522 | -27 523 | -315 524 | -286 525 | -113 526 | -454 527 | -400 528 | -468 529 | -245 530 | -18 531 | -427 532 | -479 533 | -281 534 | -43 535 | -29 536 | -15 537 | -371 538 | -127 539 | -371 540 | -251 541 | -343 542 | -267 543 | -355 544 | -271 545 | -68 546 | -454 547 | -532 548 | -264 549 | -513 550 | -170 551 | -484 552 | -85 553 | -329 554 | -389 555 | -317 556 | -382 557 | -535 558 | -169 559 | -395 560 | -53 561 | -429 562 | -394 563 | -465 564 | -250 565 | -419 566 | -434 567 | -84 568 | -130 569 | -229 570 | -496 571 | -336 572 | -388 573 | -412 574 | -123 575 | -502 576 | -205 577 | -367 578 | -224 579 | -40 580 | -551 581 | -99 582 | -394 583 | -321 584 | -515 585 | -260 586 | -410 587 | -518 588 | -22 589 | -23 590 | -259 591 | -397 592 | -306 593 | -199 594 | -157 595 | -49 596 | -298 597 | -176 598 | -564 599 | -271 600 | -6 601 | -297 602 | -514 603 | -432 604 | -455 605 | -192 606 | -95 607 | -447 608 | -237 609 | -571 610 | -543 611 | -229 612 | -405 613 | -282 614 | -235 615 | -380 616 | -25 617 | -603 618 | -335 619 | -94 620 | -533 621 | -463 622 | -396 623 | -421 624 | -393 625 | -588 626 | -376 627 | -152 628 | -328 629 | -460 630 | -90 631 | -315 632 | -533 633 | -207 634 | -590 635 | -100 636 | -588 637 | -574 638 | -259 639 | -183 640 | -522 641 | -424 642 | -272 643 | -341 644 | -443 645 | -217 646 | -143 647 | -26 648 | -196 649 | -632 650 | -520 651 | -606 652 | -277 653 | -176 654 | -547 655 | -564 656 | -444 657 | -228 658 | -223 659 | -115 660 | -200 661 | -616 662 | -576 663 | -398 664 | -157 665 | -78 666 | -586 667 | -12 668 | -650 669 | -239 670 | -152 671 | -20 672 | -366 673 | -100 674 | -478 675 | -666 676 | -247 677 | -105 678 | -230 679 | -218 680 | -48 681 | -238 682 | 0 683 | -387 684 | -660 685 | -542 686 | -189 687 | -339 688 | -577 689 | -527 690 | -273 691 | -565 692 | -230 693 | -578 694 | -147 695 | -106 696 | -373 697 | -513 698 | -8 699 | -465 700 | -66 701 | -408 702 | -351 703 | -357 704 | -119 705 | -251 706 | -626 707 | -81 708 | -575 709 | -542 710 | -193 711 | -219 712 | -189 713 | -635 714 | -77 715 | -517 716 | -608 717 | -309 718 | -716 719 | -712 720 | -287 721 | -67 722 | -312 723 | -334 724 | -584 725 | -687 726 | -488 727 | -612 728 | -42 729 | -180 730 | -726 731 | -235 732 | -606 733 | -538 734 | -470 735 | -477 736 | -504 737 | -278 738 | -24 739 | -435 740 | -610 741 | -540 742 | -646 743 | -503 744 | -151 745 | -350 746 | -43 747 | -699 748 | -459 749 | -516 750 | -424 751 | -343 752 | -297 753 | -460 754 | -592 755 | -30 756 | -614 757 | -125 758 | -425 759 | -180 760 | -73 761 | -550 762 | -361 763 | -390 764 | -380 765 | -518 766 | -418 767 | -305 768 | -326 769 | -84 770 | -675 771 | -320 772 | -557 773 | -486 774 | -457 775 | -414 776 | -69 777 | -228 778 | -683 779 | -610 780 | -188 781 | -608 782 | -480 783 | -225 784 | -186 785 | -374 786 | -256 787 | -672 788 | -145 789 | -323 790 | -453 791 | -252 792 | -214 793 | -600 794 | -49 795 | -652 796 | -593 797 | -93 798 | -42 799 | -101 800 | -600 801 | -422 802 | -146 803 | -191 804 | -474 805 | -725 806 | -568 807 | -572 808 | -498 809 | -506 810 | -702 811 | -120 812 | -210 813 | -340 814 | -482 815 | -210 816 | -666 817 | -520 818 | -647 819 | -219 820 | -435 821 | -455 822 | -814 823 | -304 824 | -610 825 | -224 826 | -95 827 | -425 828 | -456 829 | -761 830 | -339 831 | -256 832 | -793 833 | -49 834 | -317 835 | -274 836 | -374 837 | -620 838 | -730 839 | -130 840 | -128 841 | -420 842 | -315 843 | -47 844 | -92 845 | -467 846 | -269 847 | -563 848 | -495 849 | -501 850 | -32 851 | -755 852 | -774 853 | -154 854 | 1 855 | -685 856 | -657 857 | -38 858 | -727 859 | -428 860 | -293 861 | -68 862 | -203 863 | -850 864 | -775 865 | -545 866 | -740 867 | -683 868 | -728 869 | -502 870 | -520 871 | -44 872 | -53 873 | -826 874 | -555 875 | -539 876 | -291 877 | -435 878 | -673 879 | -865 880 | -114 881 | -467 882 | -679 883 | -598 884 | -611 885 | -566 886 | -606 887 | -320 888 | -124 889 | -430 890 | -240 891 | -85 892 | -549 893 | -847 894 | -481 895 | -444 896 | -792 897 | -695 898 | -405 899 | -427 900 | -292 901 | -533 902 | -91 903 | -5 904 | -546 905 | -181 906 | -156 907 | -488 908 | -29 909 | -17 910 | -572 911 | -510 912 | -663 913 | -321 914 | -177 915 | -516 916 | -85 917 | -829 918 | -109 919 | -236 920 | -876 921 | -141 922 | -427 923 | -180 924 | -576 925 | -45 926 | -178 927 | -6 928 | -236 929 | -381 930 | -638 931 | -144 932 | -391 933 | -739 934 | -43 935 | -898 936 | -896 937 | -395 938 | -280 939 | -712 940 | -127 941 | -823 942 | -130 943 | -783 944 | -324 945 | -29 946 | -136 947 | -941 948 | -816 949 | -712 950 | -120 951 | -639 952 | -209 953 | -522 954 | -618 955 | -205 956 | -557 957 | -153 958 | -451 959 | -280 960 | -214 961 | -683 962 | -134 963 | -329 964 | -403 965 | -156 966 | -645 967 | -194 968 | -811 969 | -377 970 | -161 971 | -620 972 | -920 973 | -225 974 | -632 975 | -543 976 | -658 977 | -864 978 | -137 979 | -928 980 | -616 981 | -728 982 | -145 983 | -182 984 | -879 985 | -595 986 | -598 987 | -409 988 | -934 989 | -23 990 | -58 991 | -301 992 | -427 993 | -599 994 | -562 995 | -373 996 | -656 997 | -360 998 | -783 999 | -68 1000 | -228 1001 | -712 1002 | -912 1003 | -260 1004 | -490 1005 | -588 1006 | -481 1007 | -610 1008 | -615 1009 | -180 1010 | -914 1011 | -960 1012 | -462 1013 | -522 1014 | -782 1015 | -617 1016 | -687 1017 | -477 1018 | -934 1019 | -54 1020 | -201 1021 | -279 1022 | -101 1023 | -27 1024 | -759 1025 | -407 1026 | -187 1027 | -202 1028 | -715 1029 | -488 1030 | -206 1031 | -802 1032 | -737 1033 | -18 1034 | -364 1035 | -325 1036 | -155 1037 | -573 1038 | -536 1039 | -769 1040 | -747 1041 | -669 1042 | -856 1043 | -521 1044 | -24 1045 | -921 1046 | -394 1047 | -726 1048 | -251 1049 | -5 1050 | -533 1051 | -923 1052 | -752 1053 | -28 1054 | -775 1055 | -100 1056 | -801 1057 | -22 1058 | -723 1059 | -383 1060 | -952 1061 | -355 1062 | -1058 1063 | -975 1064 | -975 1065 | -706 1066 | -843 1067 | -75 1068 | -124 1069 | -150 1070 | -98 1071 | -1019 1072 | -195 1073 | -342 1074 | -915 1075 | -------------------------------------------------------------------------------- /day6.txt: -------------------------------------------------------------------------------- 1 | 2 8 8 5 4 2 3 1 5 5 1 2 15 13 5 14 2 | -------------------------------------------------------------------------------- /day9.txt: -------------------------------------------------------------------------------- 1 | {{{},{{{{},<"o!!}i>,!i},<>},{},{{,<{!u!!!>,!,,!!"!e'o}>}}},{},{}!!!>,io!>'!o>}},{{{!oe!>!,{},}},{},{{<}}>,<"'',!!}{!!i{>}}},{{{{<'o!>>,!{u}a,">},{{,<"!>e!!'!!!!!>},<'o!!!,!e},{{}}}},{{,<,>},{<'!!!>},<,"u>}}},{{{{!><},<>}},{e>,{},<"}a"''!!!!!!!>o<}!!,>}}},{{{,<'!!!!e!>},},<{!>},<,,!!}}!!u>},{{}}},{{{,<>}},{{}}},{{}}},{{{<>},},},!!!>!!<>},{<>}},{{},{,<>,{}},{{},{{<>},{{!>!!!!a!>,{>}}}}}},{{{},{}}}}},{{{}},{,,"e!u>,{{{}}}},{{<}!!<,e>},<,<'{!{ei!!!>>}}}},{{{{{<'!a>,,},a>},{{,"!>},},!>,<{!>,<>,{}},{{},{{}}},{,<}!!!!!>!!!>!>},"!!!>!!ui'>}}},{{},},},<"{>}},{{},{{{{!a<}},,{'!!a},,<>}},{<",>}},{{!!}!e!>,<<{!>},<,},<>,{<'!e!>},,!>!>!'>}}},{{<!!{>},{{},{i!{>}}},{{{{{{{,},<">,<,}i!!!>!}!>!!!!!>},io,!>},}!!i>}}},{{},{,{{},{}}}},{,<>}}},{{{<,!>i!!!>},!{ue!!i>},{{{<,!>!>},<}!!{u'!}!>!!!>!>},<>}},{}}},{!!!>!!!!!>!io>}},{{{{,!>e!{'>,{<'e!!'!,u!>},}},{{,,o!>a},}}}},{{{{}},{{},},>},{!!!>"}!oae>},{{<"!!!!>,<'!!!>a,<"!>},>}}},{{{,<'uo{!{>}},<}!!}'a!>},<>}},{{{!!'!!>},,{oi{!!,!e!!!<>},{{},{}},{{,,},<}"{e},{oa>}}}},{{{,<'eo!>,,<'"!!!!!>!!e"!!!>'}!!>},{{{<"!>},<{a!!'!!!>!!"!'a!!!!!>!!u>},{<'>}}},{{i!>},!>!!!>!>},<">},{<<>}}},{{<,>},{}},{{},<'u{',uo>,},{}}},{{!!e!>,,{{},<{'!>,'a,!!!>!'!>,<!!!,<<{">}}},{},,<>}}},{{<,<}!"!>!>},u>}}},{{}},{{{>,{<>}},{{o{>},{}},{}},{{<">}},{"uaou!>,"'>,{},<!>u!e!>,},<<>,<,!}}}"!!{e!>,}}}}}},{{{}},{{},!!!>,o,o!!o!!!><>}},{{<}'!!!>!>!!a}>,{}},{}}}}},{{{{{{<>},{,},},<{!>,}},{{}},{">,,<}"{ee>}},{{}}},{{{{}},<<'"!o,e{a!>},,<">},{{<},},},},{o>},},{{{},<>},{{ao!!{}{u!>},<,i"!!>}}}},{{<">},{{},<'!!!>"!>},<"!>,<,""!}ua!>"a>}}},{{{},<!>,!>},<'oe!!!>,,!!!!!!i'!uieo>},{{!>},>,,},<},{{u!!!>{!!oi!>>},{}},{{,},{},<,>}}}}},{{},{{{,},<'"}!!!>}u"o!>,<"!}<},{{,e!!!>!,!!!>ae!a!!",}}},{<<"!>},,{}},{{},{i!>},,,!!'e>}}},{{{'{>},,},<}!o>},{<}e!!!>!>,'!>,,{}},{{},<>}},{}},{{{{<'!!!!!>o!!!,!>,<"'>}}},{{{},<>}},{},{{,{}}}}}},{{{{{{},{{<""ie!"{>}}}},{<}!!!!e<'ioa!>},<"!>},},,}},{},{{<<<>,{},!a!>"{!!!>!{!!!!iei<>,{{},<'u!!u">},{{},<,"oe!<{!,u!!!>!"!!!>>}}}}},{{},<!!!!,>},{{},{,<'!>"!>,<>}}}},{{{{},{{{,<{e!!!>!!!!!">},<},<"!>u!'{',>},a!"o",!a!'!u}!>},<"a!>},<>}},{<>,},<{!!!>,o!!aa"!!'!!!!"!!!>ie>}},{{{,}},{{{{<{!>ii>}}},!!!>e!!{!>,u!!o!!!!o>},{{<>}}},{{{{<{!!!!i"i,"ui"!!o!>},'",>},{>}},{{{{{},},<{o<,o"i!!!>},<,!!!'!!o!>,>},<<"!>,<{o{!}i!!<>}}},{{{{'a'"!ei>},{,<,!!!>'"e!{,<>}}}}}},{{<"!!!>ai'>},{{{,<"ou"u!>}!!'ue!>},<'o}!>},}},},<"i,u!!!>!!!!!>i"{!!!>>}}},{{{{!o}!!!>},eo!!!>!>},!>},",!!!!u,>,!!ie,o<',<}!>"oe!>,},{{!i{u>},},<'o!}eu{}!e>},{{<"!>,<,'!!!>>},}},{},{{{{{<"!!!>!!!>}o!>},!!e!!e!!!>>}}}},,>}},{{{{<{'!iu!>,<}!>},<}>},{<'i>}},{<}ea!!{,o!!!>,<'}oi<,!}a">,,}},{{aei{!>,,<'e<>},{}},{{{},,<>}}},{{<>,,},<>}}},{{{{<,"oo!>},i<'!!{!>a!!i"!"!!>,i!!a!!!!!>{>}},{{}}},{{{,{}},{{},},,},<"!!!!!!!>!!!>!!!!uau<>},{a!>{oo,!>},!!ii<}>,{<"!ia!>}}},{{{<"o,!>,!a!!e>},{},{{{<>},},<{>},{!!!>},},}}},{},'!>},<,!>!>}!!!>!>!!!>!>,,},{{u!>!{,a!}!>,<},i!>,,<>}}},{},{{},{<}!>e!!>,!!!>},!!'u!>,>}}},{{{{{!!o!i"!!!>!>i!!<}o!>},}},<<{<>},{{{},},!>,<'!>},<>}},{},{{{}!>,},{}}},{{{{{<"!!,}{a!!>},<,!{eau>},{,}},{{{},{}}}},{},{<,!!!>a!>,<'>,{}}}},{{!>,<}!>},}<,>},{{<>},{}},{<""a!!!>>}}},{},{{{{a!>},<!!!,!!>},{},,>}},{{},{{<},<{{!>o!>,<>},,<}o>}},{{},,{}}}},{{{{{},{!!!>!>,,aaa!!!>!>,}}},{{!!'e{!,",!!!>ii!>">},{{},<}u{!!!>!!!>!!"!!!>}!!">}}},{{iu!!!>!>},,,<>},{},{{"!!!!!>u!!!!!>!>,i>},,!>!>!!{"!!a>}},{{},{}},{{{,<}!e>},{},!>,!>!ao"!a>}},{{{{{<>}},{{},<>},{}},{},{<}e>,{}}}},{}}},{{{<}"!!!>e!!!><>}},{{<'!!!!"u'}aou,a>,{<!>,<{!>},oa>,{{},<">}}},{{<'!!!>e{!>},<",>},{{a,u!>!>,<}u!!}!>},<>},<",!>},<"!a!!"!>!>},<>}},{!!}eiii{>,!>!>}!>!!!>,!!!!!!i>}},{{{,<{!!a!>!>,,},<>},{<"o}'"!uo{'o'"{>,{}}},{}>}}},{{{{{},},<>},{}},{<{'>},{,<>,{{}}}},{{},{},<"!>,<{>},{}},{{{">,<'!!,{!>!!!>,>}},{{{<{},},<'>,o!!!!!!"!>,},<>},{},ie!e!!"{auu}}}},{{{<}>},,},,!!!>,<>}}},{{{<!>!>}}{{!!o"e>}},{{}},{},!>e>}},{{},{},{{<>}}},{{{u!!!>eo!o}u!}!{!>},<}'i!>},<>,<,!!!>},<'!!!!!!!>'uu!!a,,e>},{"}},{{{},},{e!!!>!!!!u}o!!">}},{{<>},{,},<'!>},<{}!<}"!>,},!>e>},{<{'{!>!!ae!!>}}}}}}},{{{{{{<">},<}oea!>,<}o>},{,<!e!!!o>,{}},{{!>,<'a{'>}}}},{{{{},{{<>}}},{,}eae'!uuo!!}!!<>,{{<"'i>}}},{},<}ae!!!>e'{!!!><>}},{{{{<}!>},e<'a!!!>,<}ee}!>,!>},<"<">,{"!>!!i!!>}},{{{{<>}},{}},{{,<{u}>}},{}},{<>,{,o!!!>},}}},{{{u!!!>!eoeo{!!,<}i!>},<>,<,!}a!>,},{},{<"e>,{}}},{,,{!!!>i!!>}},{{{},,,<'!!!>},},},},<"!>>}},{{},{<i!!,!>},<',>}}}},{{{<'ei!!!>{!>,!!!>>},},ieu!>,>},{{{!<>}}},{,{}}},{{{{{,{{{{},!!"!>,!!!>},}}},{}}},{{!>"{a!!{!>,},{<>}},{}}},{}}}},{{{{{,},o!>e!!,>}}},{},{,<'!!aoa!!!>!!!!!!!>!!!>,<',!!a!>i>}},{{!!!>},}{}">,{,,i"!<'{!o>}}}},{{{{{<"e!!i!>>,{!>},},<!!e,,<<>}}},{<,"o!e<o!io!>,,{}}},{{},{}},{{},{{{},,},},!!<>},{{}},{{{'!!e!>},,},!!!>"}}!!i,'>},<{>},{},<!>},}}},{{{<'i{i'!>!!e!!!>!{ie!!!!!>,<{!>{!!!!a">},{},},>}},{<{i,!{>,{{{!!,>}},{!>!!!!}iu,!>},<{o!>},>}}}}}}},{{{{,},},{{{{{o{>,{}}},{,<{>}}},{{<}!>,,,{{},<>}},{}},{{{!<{,!>iu{'"o>,{}},{{u>},{}},{}},{{,ee!!''i!>},<{!>,,,o,o,i!>},,}!>},<"!!!>},<{!!!o>},{{{!!>,{>,{{{},{{<{!!!>'!>,!>!!o!!!>}!!!>>}}},},},},!>u"e"}!a!'a!u{>}}},{{{{,<'{a!>,<}"!>,},,{}},<}u!>u,a!>!!!>u!!!!!>u!},{{<,u<'!>!>},<>}},{{{{},<}!>},<{ee"}"!>!!<>}},{{!!e<'>},io!'!>"!!i!!}!>,},{,!>,ei!>!!u!>o,!>},<>}}}}},{{{!>,},{{{}}}}}}},{{u"},<}!>},<>}},{{},,aa!'!!!>>},{}}},{{{<'}!!>,!>},,<}!!!>!!a'!!!>}!>},!',"!>}!>},},<>},{{{,"{}'!!!>!!!>!!!>{>},{!>'!>ea!!!>u!!i>,{{<"a<,}!!",'a!!u}a{}},<'!!>},<'!,u>}}},{{},!!!!u'au!!u>},{<>,!>u{aeai!>,!!"}!!'e!!'}>}}},{{{},{,<}o}>,{,},!!'!>},},}}}}}},{{{{{{},ao!!"}o!>},<>}},{}},{,<{!!!!!>}"!>},<}>}},{{,<,!>,!!!>,<,}}}},{{{{{},{}},{{{!!!>,}},{{<}},,,,},{},ia>}}},{,<'<{!>uu!!ia>,,,<,,<>}},{{{{},{<"!>},},<"!>,}ai!!!!a!'u>},{{},{o"!>,!>!!!!"{!>o}>}}},{<{!!">}},{{{<,oooe>,{eo<{!>,},'!!>}},{},{}},{{<{,<}!>,},{{}}}},{{,},,<}!!'}},{{!uu''!!{,oeu!>,{>,<,"'>},{{},,}"a""!!!>>},{{},{}}}}}},{{}}},{{{{},{<'!!",<},,}},},}!,,!!ia{>},{{{{{,{<},!!!>>}},{{}}}},<>},{{!!'>,<}!!<,!!!>,<},i!>!<>},{}},{{!>,'!>,},u,}!>}>},{>}}},{{!!{!>{>},,}},{{{"a!>},<a!!!>'!>},<}!ii>},{,{},!!>}},{{{{},<>}},<}e!>},<}!!a>}}}}},{{{{{},{<>}},{<>}},{{"!!!!!>!i!>!>,!>,,<}!!!>,<>},},!!i'!>,<>},{{},},<<,!!!!a!!,},<'!u!>,<>},{<!>!>},e"i!>>,{}},{,<>}}},{{}},{{!!!u"!>,,{}},{}}}}},{{{{},{<{!>,},<>}},{{},<>}},{},{{},{{{{{}},{{{{}}}}},{{,<>}}},{{<{ie!!'!o'!!!>,,<,!>!!{!u!>},<>,!!!>!>'"eu>},{{{<,!eu!io,{{},},,<}}}},{{{},{,!>e>}},{},},},<'!>,<"e!!!>"">,{>}}}},{{}}},{{<>},<<}>}},{{{},>},{{},}!!oe'>}}}}},{{{{{,!!">}}},{{{},{}},{{},!}ie!!{!!>}}},{{{o<'!e!e!>,<>}},{{{},!u!!{u},,,,<>},{{!>a!>!!,>,{}}}},{{{{{{{!>,<,<>},},,<'{!!}!!!>,uo>}},{u!!!!!>>,},},!!!>,,}}},{{{{,!!!>"">}},{,o>,{{{{{<'!>},!!o"oe!>},<,e!!'a>,,<,a!!!u}!!!!!!"!!i!!'i!!"u!>},<>},{<}}},,,!!!>>}}}},{{{{{{<}e!>!>o!>!>'i!!"'<,!>},<{e!!i>},},{<,!>},},<}!>,,{<!!'!>,<<<>}}},{!!!!o!!}i,!!!!!!!>!}'!>!!}i>,{<,},,u!>},>}},{{!!!>e,!a,a!!!>o}!>},<},},{,},<}},{{,<{"!aeoa!!>,,<>},{<>}}},{{{,,<}e"!>,<>},{<{!>,,,>,{}}}},{{<<>}}}}}},{{{{,<>},<}u!>},<'ei>},{{},{{,}}!>,<">,{}{{!!!>{>,<">}},{{{<"a!!a!!!}{<>},{{},<}u>}},{{!>'}!!!>!!!>,!!!>e>},{{{!>,iu>}}}}},{{,{,<"'!>,},},a!!>}},<,,<}!!!>!>,!!!!!>}!u>}},{{!>,<"!}}}<}ou>},{},<>}}},{{<,!!o>}}},{{{{<!!!>},,o!>},<}!'!!!>{>},{<>}}}},{{{},<>},{},}i>}},{{}},{{{}},{{},!>},!!{!!!><'!{!>!!'>}}},{{}}},{{{},{<{,'!>,!!!>{!!!>,!!!>'!!!>>,{<,<{{!i!!oe'a!>i"!!a}},{i!>},<}!!!>,<'!!!>,,<,!!!!au!>,,{<,,<{'>}}},{{},!!!>ao!!!>>,{!>,},!>!>!>>}},{!!!>!>}>,<,,,{>},{,!!>}}},{{{{{},{{},!}"ea!!!>>}},{{},{,},<'{}!!!i!!!>"!>},},,}},{}},{{{},,'a!>u!!<,!!!>>},{},}},{{},<}i!!!!!>e!!!!!>o>},{<>}},{}}},{{{{{i}e'!!!>},},<{!>,<!>,<>}},{{{!<{,"o!>,!!o>},{i{'!!!!!i'!>,}a!!!>},<>}}}}}}}} 2 | -------------------------------------------------------------------------------- /packages/growarray/growarray.cabal: -------------------------------------------------------------------------------- 1 | name: growarray 2 | version: 0.1.0.0 3 | author: Daniel Lin 4 | maintainer: ephemient@gmail.com 5 | build-type: Simple 6 | cabal-version: >=1.10 7 | 8 | library 9 | exposed-modules: GrowArray 10 | build-depends: base >=4.7 && <5 11 | , primitive 12 | , unboxed-ref 13 | , vector 14 | hs-source-dirs: src 15 | default-language: Haskell2010 16 | 17 | test-suite growarray-test 18 | type: exitcode-stdio-1.0 19 | hs-source-dirs: test 20 | main-is: Main.hs 21 | build-depends: base 22 | , growarray 23 | , hspec 24 | , QuickCheck 25 | other-modules: GrowArraySpec 26 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 27 | default-language: Haskell2010 28 | -------------------------------------------------------------------------------- /packages/growarray/src/GrowArray.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleInstances, NoMonomorphismRestriction, NondecreasingIndentation, RecordWildCards #-} 2 | module GrowArray (GrowArray, foldGrowArray, newGrowArray, readGrowArray, writeGrowArray) where 3 | 4 | import Control.Monad.ST (ST) 5 | import Data.Bits (FiniteBits, countLeadingZeros, finiteBitSize, shiftL) 6 | import Data.Ix (Ix, inRange, index, rangeSize) 7 | import Data.Primitive (Prim) 8 | import Data.STRef (STRef, newSTRef, readSTRef, writeSTRef) 9 | import Data.STRef.Unboxed (STRefU, newSTRefU, readSTRefU, writeSTRefU) 10 | import Data.Vector.Unboxed.Mutable as V (STVector, Unbox, length, replicate, unsafeCopy, unsafeRead, unsafeSlice, unsafeWrite) 11 | 12 | -- | A growable array with unboxed indices and elements. 13 | data GrowArray s i e = GrowArray 14 | { growArrayDef :: e 15 | , growArrayMin :: STRefU s i 16 | , growArrayMax :: STRefU s i 17 | , growArrayVec :: STRef s (V.STVector s e) 18 | } 19 | 20 | -- | Creates a new growable array, pre-allocating the given indices with the 21 | -- given default value. 22 | newGrowArray :: (FiniteBits i, Ix i, Num i, Prim i, V.Unbox e) => 23 | (i, i) -> e -> ST s (GrowArray s i e) 24 | newGrowArray (min, max) def | min <= max = 25 | GrowArray def <$> newSTRefU min <*> newSTRefU (min + size - 1) <*> 26 | (newSTRef =<< V.replicate size def) where 27 | size = 1 `shiftL` (finiteBitSize max - countLeadingZeros (max - min)) 28 | 29 | getBounds :: (Prim i) => GrowArray s i e -> ST s (i, i) 30 | getBounds GrowArray {..} = 31 | (,) <$> readSTRefU growArrayMin <*> readSTRefU growArrayMax 32 | 33 | -- | Reads an element at an index. Returns the default value if unallocated. 34 | {-# INLINE readGrowArray #-} 35 | readGrowArray :: (Ix i, Prim i, V.Unbox e) => GrowArray s i e -> i -> ST s e 36 | readGrowArray arr@GrowArray {..} i = do 37 | bounds <- getBounds arr 38 | if inRange bounds i 39 | then flip V.unsafeRead (index bounds i) =<< readSTRef growArrayVec 40 | else pure growArrayDef 41 | 42 | -- | Writes an element at an index, growing the underlying storage as needed. 43 | {-# INLINE writeGrowArray #-} 44 | writeGrowArray :: (FiniteBits i, Ix i, Num i, Prim i, V.Unbox e) => 45 | GrowArray s i e -> i -> e -> ST s () 46 | writeGrowArray arr@GrowArray {..} i e = do 47 | bounds@ ~(l, h) <- getBounds arr 48 | if inRange bounds i 49 | then readSTRef growArrayVec >>= \v -> V.unsafeWrite v (index bounds i) e 50 | else do 51 | let bits = finiteBitSize i - countLeadingZeros (max h i - min l i) 52 | oldSize = rangeSize bounds 53 | newSize = 1 `shiftL` bits 54 | old <- readSTRef growArrayVec 55 | new <- V.replicate newSize growArrayDef 56 | let min = if i < l then h - newSize + 1 else l 57 | max = if i < l then h else l + newSize - 1 58 | start = if i < l then newSize - oldSize else 0 59 | dest = V.unsafeSlice start oldSize new 60 | V.unsafeCopy dest old 61 | V.unsafeWrite new (index (min, max) i) e 62 | writeSTRefU growArrayMin min 63 | writeSTRefU growArrayMax max 64 | writeSTRef growArrayVec new 65 | 66 | -- | Folds a function over all elements, potentially including default values at 67 | -- indices that were not explicitly allocated or written. 68 | {-# INLINE foldGrowArray #-} 69 | foldGrowArray :: (Prim i, V.Unbox e) => 70 | (a -> e -> ST s a) -> a -> GrowArray s i e -> ST s a 71 | foldGrowArray f z arr@GrowArray{..} = do 72 | vec <- readSTRef growArrayVec 73 | let go i a = if i >= V.length vec then pure a else 74 | V.unsafeRead vec i >>= f a >>= go (i + 1) 75 | go 0 z 76 | -------------------------------------------------------------------------------- /packages/growarray/test/GrowArraySpec.hs: -------------------------------------------------------------------------------- 1 | module GrowArraySpec (spec) where 2 | 3 | import Control.Monad.ST (ST) 4 | import Data.Ix (range) 5 | import Data.List (isInfixOf, replicate) 6 | import GrowArray (GrowArray, foldGrowArray, newGrowArray, readGrowArray, writeGrowArray) 7 | import Test.Hspec (Spec, describe, it) 8 | import Test.QuickCheck ((===), property) 9 | import Test.QuickCheck.Monadic (assert, monadicST, pre, run) 10 | 11 | spec :: Spec 12 | spec = do 13 | describe "read" $ do 14 | it "in bounds" $ property $ \lo def xs -> monadicST $ do 15 | pre $ not (null xs) 16 | let hi = lo + length xs - 1 17 | arr <- run $ fillArray lo def xs 18 | xs' <- run $ readArray arr $ range (lo, hi) 19 | pure $ xs === xs' 20 | it "out of bounds" $ property $ \lo def xs n -> monadicST $ do 21 | pre $ not (null xs) 22 | let p i = (if i < 0 then lo else lo + length xs) + i 23 | arr <- run $ fillArray lo def xs 24 | x <- run $ readGrowArray arr $ p n 25 | pure $ def === x 26 | describe "write" $ 27 | it "out of bounds" $ property $ \lo def xs n m x -> monadicST $ do 28 | pre $ not (null xs) && n /= m 29 | let hi = lo + length xs - 1 30 | p i = (if i < 0 then lo else hi + 1) + i 31 | arr <- run $ fillArray lo def xs 32 | run $ writeGrowArray arr (p n) x 33 | xs' <- run $ readArray arr $ range (lo, hi) ++ map p [n, m] 34 | pure $ xs ++ [x, def] === xs' 35 | describe "fold" $ 36 | it "includes all" $ property $ \lo def xs n x -> monadicST $ do 37 | pre $ not (null xs) 38 | let top = lo + length xs 39 | expected = if n < 0 40 | then x : replicate (- n - 1) def ++ xs 41 | else xs ++ replicate n def ++ [x] 42 | arr <- run $ fillArray lo def xs 43 | run $ writeGrowArray arr (if n < 0 then lo + n else top + n) x 44 | actual <- run $ foldGrowArray (\xs x -> pure $ x:xs) [] arr 45 | assert $ reverse expected `isInfixOf` actual 46 | where 47 | fillArray :: Int -> Char -> String -> ST s (GrowArray s Int Char) 48 | fillArray lo def xs = do 49 | let hi = lo + length xs - 1 50 | arr <- newGrowArray (lo, hi) def 51 | sequence_ [writeGrowArray arr i x | (i, x) <- zip [lo..] xs] 52 | pure arr 53 | readArray :: GrowArray s Int Char -> [Int] -> ST s String 54 | readArray arr is = sequence [readGrowArray arr i | i <- is] 55 | -------------------------------------------------------------------------------- /packages/growarray/test/Main.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -F -pgmF hspec-discover #-} 2 | -------------------------------------------------------------------------------- /packages/lcg/bench/Main.hs: -------------------------------------------------------------------------------- 1 | module Main (main) where 2 | 3 | import Criterion.Main (bench, defaultMain, nf) 4 | import LinearCongruentialGenerator (minstdRand, minstdRand0) 5 | 6 | main :: IO () 7 | main = defaultMain 8 | [ bench "minstdRand0" $ nf (sum . take 40000000 . minstdRand0) 1 9 | , bench "minstdRand" $ nf (sum . take 40000000 . minstdRand) 1 10 | ] 11 | -------------------------------------------------------------------------------- /packages/lcg/lcg.cabal: -------------------------------------------------------------------------------- 1 | name: lcg 2 | version: 0.1.0.0 3 | author: Daniel Lin 4 | maintainer: ephemient@gmail.com 5 | build-type: Simple 6 | cabal-version: >=1.10 7 | 8 | library 9 | exposed-modules: LinearCongruentialGenerator, LCGMatches 10 | build-depends: base >=4.7 && <5 11 | , ghc-prim 12 | hs-source-dirs: src 13 | default-language: Haskell2010 14 | 15 | test-suite lcg-test 16 | type: exitcode-stdio-1.0 17 | hs-source-dirs: test 18 | main-is: Main.hs 19 | build-depends: base 20 | , lcg 21 | , hspec 22 | , QuickCheck 23 | other-modules: LinearCongruentialGeneratorSpec 24 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 25 | default-language: Haskell2010 26 | 27 | benchmark lcg-bench 28 | type: exitcode-stdio-1.0 29 | hs-source-dirs: bench 30 | main-is: Main.hs 31 | build-depends: base 32 | , lcg 33 | , criterion 34 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 35 | default-language: Haskell2010 36 | -------------------------------------------------------------------------------- /packages/lcg/src/LCGMatches.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: LCGMatches 3 | Description: Count matches between 'minstdRand0' and 'minstdRand' 4 | -} 5 | {-# LANGUAGE BangPatterns, MagicHash, UnboxedTuples #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module LCGMatches (countMatches, countMatchesMod) where 8 | 9 | import GHC.Prim (Word#, and#, eqWord#, remWord#, timesWord#) 10 | import GHC.Types (Int(I#), Word(W#)) 11 | import GHC.Word (Word32(W32#)) 12 | import LinearCongruentialGenerator (next32#) 13 | 14 | genA, genB :: Word# -> Word# 15 | genA = next32# (# 16807##, 2147483647## #) 16 | genB = next32# (# 48271##, 2147483647## #) 17 | 18 | gen, gen' :: (# Word#, Word# #) -> (# Word#, Word# #) 19 | gen (# a, b #) = (# genA a, genB b #) 20 | gen' (# a, b #) = (# genA' a, genB' b #) where 21 | genA' x = if W# (and# y 3##) == 0 then y else genA' y where y = genA x 22 | genB' x = if W# (and# y 7##) == 0 then y else genB' y where y = genB x 23 | 24 | eq16 :: (# Word#, Word# #) -> Bool 25 | eq16 (# a, b #) = I# (eqWord# (and# a 65535##) (and# b 65535##)) /= 0 26 | 27 | count, count' :: Int -> Int -> (# Word#, Word# #) -> Int 28 | count 0 k _ = k 29 | count n !k x = count (n - 1) (if eq16 y then k + 1 else k) y where y = gen x 30 | count' 0 k _ = k 31 | count' n !k x = count' (n - 1) (if eq16 y then k + 1 else k) y where y = gen' x 32 | 33 | countMatches, countMatchesMod :: Int -> (Word32, Word32) -> Int 34 | countMatches n (W32# a, W32# b) = count n 0 (# a, b #) 35 | countMatchesMod n (W32# a, W32# b) = count' n 0 (# a, b #) 36 | -------------------------------------------------------------------------------- /packages/lcg/src/LinearCongruentialGenerator.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: LinearCongruentialGenerator 3 | Description: Linear congruential generators 4 | -} 5 | {-# LANGUAGE CPP, MagicHash, UnboxedTuples #-} 6 | #include "MachDeps.h" 7 | module LinearCongruentialGenerator 8 | ( lcg32 9 | , minstdRand 10 | , minstdRand0 11 | , next32 12 | , next32# 13 | ) where 14 | 15 | import GHC.Prim (Word#, not#, quotRemWord2#, remWord#, timesWord#, timesWord2#) 16 | import GHC.Types (Int(I#)) 17 | import GHC.Word (Word32(W32#)) 18 | 19 | #if WORD_SIZE_IN_BITS < 32 20 | # error "The native word size must be at least 32 bits." 21 | #endif 22 | 23 | {-# INLINE next32# #-} 24 | next32# :: (# Word#, Word# #) -> Word# -> Word# 25 | next32# (# a, m #) x 26 | #if WORD_SIZE_IN_BITS < 64 27 | | W32# (or# (and# a (not# 0x7FFFFFFF##)) (and# m (not# 0x7FFFFFFF##))) /= 0 || 28 | I# (mulIntMayOflo# (word2Int# a) (word2Int# m)) /= 0 29 | = let (# y1, y0 #) = timesWord2# a x 30 | (# _, r #) = quotRemWord2# y1 y0 m 31 | in r 32 | | otherwise 33 | #endif 34 | = remWord# (timesWord# a x) m 35 | 36 | -- | prop> next32 (a, m) x == a * x `mod` x 37 | {-# INLINE next32 #-} 38 | next32 :: (Word32, Word32) -> Word32 -> Word32 39 | next32 (W32# a, W32# m) (W32# x) = W32# (next32# (# a, m #) x) 40 | 41 | -- | prop> (x : lcg (a, m) x) == iterate (next32 (a, m)) x 42 | {-# INLINE lcg32 #-} 43 | lcg32 :: (Word32, Word32) -> Word32 -> [Word32] 44 | lcg32 (W32# a, W32# m) (W32# i) = loop i where 45 | loop x = W32# y : loop y where y = next32# (# a, m #) x 46 | 47 | minstdRand0, minstdRand :: Word32 -> [Word32] 48 | minstdRand0 = lcg32 (16807, 2147483647) 49 | minstdRand = lcg32 (48271, 2147483647) 50 | -------------------------------------------------------------------------------- /packages/lcg/test/LinearCongruentialGeneratorSpec.hs: -------------------------------------------------------------------------------- 1 | module LinearCongruentialGeneratorSpec (spec) where 2 | 3 | import Data.Word (Word64) 4 | import LinearCongruentialGenerator (lcg32, next32) 5 | import Test.Hspec (Spec, describe, it, shouldBe) 6 | import Test.QuickCheck (Small(..), (===), (==>), property) 7 | 8 | spec :: Spec 9 | spec = do 10 | describe "next32" $ 11 | it "is a * x % m" $ property $ \a m x -> m /= 0 ==> 12 | let (a', m', x') = (fromIntegral a, fromIntegral m, fromIntegral x) 13 | in fromIntegral (next32 (a, m) x) === (a' * x' `mod` m' :: Word64) 14 | describe "lcg32" $ 15 | it "iterates" $ property $ \a m x (Small n) -> m /= 0 && n > 1 ==> 16 | let (a', m', x') = (fromIntegral a, fromIntegral m, fromIntegral x) 17 | _:lcg32' = iterate ((`mod` m') . (a' *)) x' :: [Word64] 18 | in map fromIntegral (lcg32 (a, m) x) !! n === (lcg32' !! n) 19 | -------------------------------------------------------------------------------- /packages/lcg/test/Main.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -F -pgmF hspec-discover #-} 2 | -------------------------------------------------------------------------------- /packages/morton/morton.cabal: -------------------------------------------------------------------------------- 1 | name: morton 2 | version: 0.1.0.0 3 | author: Daniel Lin 4 | maintainer: ephemient@gmail.com 5 | build-type: Simple 6 | cabal-version: >=1.10 7 | 8 | library 9 | exposed-modules: Morton 10 | build-depends: base >=4.7 && <5 11 | hs-source-dirs: src 12 | default-language: Haskell2010 13 | 14 | test-suite morton-test 15 | type: exitcode-stdio-1.0 16 | hs-source-dirs: test 17 | main-is: Main.hs 18 | build-depends: base 19 | , morton 20 | , hspec 21 | , QuickCheck 22 | other-modules: MortonSpec 23 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 24 | default-language: Haskell2010 25 | -------------------------------------------------------------------------------- /packages/morton/src/Morton.hs: -------------------------------------------------------------------------------- 1 | module Morton (Z(..), decX, decY, getX, getY, incX, incY, toZ) where 2 | 3 | import Data.Bits ((.&.), (.|.), complement, finiteBitSize, shiftL, xor) 4 | import Data.Int (Int32) 5 | import Data.Ix (Ix) 6 | import Data.List (foldl', transpose) 7 | import Data.Word (Word64) 8 | 9 | -- | 2-D Z-order. 10 | newtype Z = Z {getZ :: Word64} deriving (Bounded, Eq, Ix, Ord) 11 | 12 | instance Show Z where 13 | showsPrec n z = showsPrec n (getX z, getY z) 14 | 15 | instance Read Z where 16 | readsPrec n s = [(toZ x y, r) | ((x, y), r) <- readsPrec n s] 17 | 18 | getX :: Z -> Int32 19 | getX (Z z) = get 0 z 20 | 21 | getY :: Z -> Int32 22 | getY (Z z) = get 1 z 23 | 24 | incX :: Z -> Z 25 | incX (Z z) 26 | | z .&. 1 == 0 = Z $ incX' z 27 | | z .&. 0x5555555555555555 == 1 = Z $ z `xor` 1 28 | | otherwise = Z $ decX' z 29 | 30 | incY :: Z -> Z 31 | incY (Z z) 32 | | z .&. 2 == 0 = Z $ incY' z 33 | | z .&. 0xAAAAAAAAAAAAAAAA == 2 = Z $ z `xor` 2 34 | | otherwise = Z $ decY' z 35 | 36 | decX :: Z -> Z 37 | decX (Z z) 38 | | z .&. 1 /= 0 = Z $ incX' z 39 | | z .&. 0x5555555555555555 == 0 = Z $ z `xor` 1 40 | | otherwise = Z $ decX' z 41 | 42 | decY :: Z -> Z 43 | decY (Z z) 44 | | z .&. 2 /= 0 = Z $ incY' z 45 | | z .&. 0xAAAAAAAAAAAAAAAA == 0 = Z $ z `xor` 2 46 | | otherwise = Z $ decY' z 47 | 48 | toZ :: Int32 -> Int32 -> Z 49 | toZ x y = Z $ foldl' (.|.) 0 50 | [1 `shiftL` i | (i, True) <- zip [0..] $ bits x +/+ bits y] where 51 | bits n = if n < 0 then True : bits' (complement n) else False : bits' n 52 | bits' n = [n .&. 1 `shiftL` i /= 0 | i <- [0 .. finiteBitSize n - 2]] 53 | x +/+ y = concat $ transpose [x, y] 54 | infix 5 +/+ 55 | 56 | get :: Int -> Word64 -> Int32 57 | get i z = if s then complement n else n where 58 | n = foldl' (.|.) 0 [1 `shiftL` j | (j, True) <- zip [0..] bits] 59 | s:bits = [z .&. 1 `shiftL` j /= 0 | j <- [i, i + 2 .. finiteBitSize z - 1]] 60 | 61 | incX' :: Word64 -> Word64 62 | incX' z = x .&. 0x5555555555555555 .|. y where 63 | x = (z .|. 0xAAAAAAAAAAAAAAAA) + 4 64 | y = z .&. 0xAAAAAAAAAAAAAAAA 65 | 66 | incY' :: Word64 -> Word64 67 | incY' z = x .|. y .&. 0xAAAAAAAAAAAAAAAA where 68 | x = z .&. 0x5555555555555555 69 | y = (z .|. 0x5555555555555555) + 8 70 | 71 | decX' :: Word64 -> Word64 72 | decX' z = x .&. 0x5555555555555555 .|. y where 73 | x = (z .&. 0x5555555555555555) - 4 74 | y = z .&. 0xAAAAAAAAAAAAAAAA 75 | 76 | decY' :: Word64 -> Word64 77 | decY' z = x .|. y .&. 0xAAAAAAAAAAAAAAAA where 78 | x = z .&. 0x5555555555555555 79 | y = (z .&. 0xAAAAAAAAAAAAAAAA) - 8 80 | -------------------------------------------------------------------------------- /packages/morton/test/Main.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -F -pgmF hspec-discover #-} 2 | -------------------------------------------------------------------------------- /packages/morton/test/MortonSpec.hs: -------------------------------------------------------------------------------- 1 | module MortonSpec (spec) where 2 | 3 | import Morton (decX, decY, getX, getY, incX, incY, toZ) 4 | import Test.Hspec (Spec, describe, it) 5 | import Test.QuickCheck ((===), (==>), property) 6 | 7 | spec :: Spec 8 | spec = 9 | describe "Z" $ do 10 | it "getX, getY" $ property $ \x y -> 11 | let z = toZ x y in (x, y) === (getX z, getY z) 12 | it "incX" $ property $ \x y -> x /= maxBound ==> 13 | toZ (x + 1) y === incX (toZ x y) 14 | it "incY" $ property $ \x y -> y /= maxBound ==> 15 | toZ x (y + 1) === incY (toZ x y) 16 | it "decX" $ property $ \x y -> x /= minBound ==> 17 | toZ (x - 1) y === decX (toZ x y) 18 | it "decY" $ property $ \x y -> y /= minBound ==> 19 | toZ x (y - 1) === decY (toZ x y) 20 | -------------------------------------------------------------------------------- /src/Day1.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day1 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day1 (day1a, day1b) where 7 | 8 | import Control.Monad (ap, liftM2) 9 | import Data.Char (digitToInt, isDigit) 10 | 11 | -- |The 'digits' function returns a list of digits contained in a string. 12 | digits :: String -> [Int] 13 | digits = map digitToInt . filter isDigit 14 | 15 | day1a :: String -> Int 16 | day1a = sum . map fst . filter (uncurry (==)) . ap zip (tail . cycle) . digits 17 | 18 | day1b :: String -> Int 19 | day1b = sum . map fst . filter (uncurry (==)) . 20 | ap zip (liftM2 drop half cycle) . digits 21 | where half = (`div` 2) . length 22 | -------------------------------------------------------------------------------- /src/Day10.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day10 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day10 (day10a, day10b, deriveKey, hashString, knotRanges, reverseRange, xorEach) where 7 | 8 | import Data.Array.IArray (IArray, (!), bounds, elems, ixmap, listArray) 9 | import Data.Array.Unboxed (UArray) 10 | import Data.Bits (Bits, xor) 11 | import Data.Bool (bool) 12 | import Data.Char (ord) 13 | import Data.Ix (Ix, inRange, index, rangeSize) 14 | import Data.List (foldl', foldl1', replicate, scanl') 15 | import Data.List.Split (chunksOf) 16 | import Data.Word (Word8) 17 | import Text.Printf (printf) 18 | 19 | -- | Reverse elements of an array in a range of indices. The range may wrap. 20 | reverseRange :: (IArray a e, Ix i, Num i) => a i e -> (i, i) -> a i e 21 | reverseRange arr r@(start, end) = ixmap b reverseIx arr where 22 | b@(low, high) = bounds arr 23 | ix = index b 24 | reverseIx i 25 | | start <= end, inRange r i = start + end - i 26 | | start > end, inRange (start, high) i || inRange (low, end) i 27 | = low + fromIntegral ((ix start + ix end - ix i) `mod` rangeSize b) 28 | | otherwise = i 29 | 30 | -- | Given array bounds and a list of lengths, returns a list of ranges in the 31 | -- array, with each one starting at an increasing distance from the end of the 32 | -- previous, wrapping around the ends of the array. 33 | knotRanges :: (Ix i, Num i) => (i, i) -> [Int] -> [Maybe (i, i)] 34 | knotRanges b@(low, high) counts = 35 | [ if len <= 0 then Nothing else Just 36 | (low + fromIntegral start, low + fromIntegral (addMod start $ len - 1)) 37 | | (len, start) <- zip counts $ scanl' addMod 0 $ zipWith (+) [0..] counts 38 | ] where addMod x y = (x + y) `mod` rangeSize b 39 | 40 | -- | Sequentially reverses all ranges in an array from a list of lengths. 41 | hash :: (IArray a e, Ix i, Num i) => a i e -> [Int] -> a i e 42 | hash arr counts = 43 | foldl' (maybe <*> reverseRange) arr $ knotRanges (bounds arr) counts 44 | 45 | -- | Adds some magic numbers to the codepoints to a string, repeated 64 times. 46 | deriveKey :: String -> [Int] 47 | deriveKey = concat . replicate 64 . (++ [17, 31, 73, 47, 23]) . map ord 48 | 49 | -- | Reduce consecutive groups of a fixed length by @xor@. 50 | xorEach :: (IArray a e, Ix i, Bits e) => Int -> a i e -> [e] 51 | xorEach n = fmap (foldl1' xor) . chunksOf n . elems 52 | 53 | -- | Deriving a key from a string by using its codepoints plus some magic 54 | -- numbers, 'hash' @[0..255]@ 64 times, then 'xor' together each group of 16. 55 | hashString :: String -> [Word8] 56 | hashString = xorEach 16 . hash arr . deriveKey where 57 | arr = listArray (0, 255) [0..] :: UArray Int Word8 58 | 59 | day10a :: Int -> String -> Int 60 | day10a len input = hashed ! 0 * hashed ! 1 where 61 | arr = listArray (0, len - 1) [0..] :: UArray Int Int 62 | hashed = hash arr . read $ '[' : input ++ "]" 63 | 64 | day10b :: String -> String 65 | day10b = concatMap (printf "%02x") . hashString 66 | -------------------------------------------------------------------------------- /src/Day11.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day11 3 | Description: 4 | -} 5 | {-# LANGUAGE RecordWildCards #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day11 (day11a, day11b, Chart(..), chart) where 8 | 9 | import Data.Char (toUpper) 10 | import Data.List (foldl', scanl') 11 | 12 | -- | A single step on a hexagonal grid. 13 | data Step = N | NE | SE | S | SW | NW deriving Read 14 | 15 | -- | A position on a hexagonal grid, in trapezoidal coordinates. 16 | data Pos = Pos 17 | { x :: !Int -- ^ The distance along the NE/SW axis. 18 | , y :: !Int -- ^ The distance along the NW/SE axis. 19 | } -- ^ The distance along the N/S axis is given by @x + y@. 20 | 21 | -- | A representation of all hexagons touched along a path. 22 | data Chart = Chart 23 | { bounds :: ((Int, Int), (Int, Int)) -- ^ Cartesian bounding box. 24 | , maxDistance :: Int -- ^ The maximum distance from origin. 25 | , path :: [((Int, Int), Int)] -- ^ Hexagons and distances from origin. 26 | } 27 | 28 | -- | Parse comma-separated steps. 29 | parse :: String -> [Step] 30 | parse s = read $ '[' : map toUpper s ++ "]" 31 | 32 | -- | Move from a position by one step. 33 | step :: Pos -> Step -> Pos 34 | step Pos {..} N = Pos (x + 1) (y + 1) 35 | step Pos {..} NE = Pos (x + 1) y 36 | step Pos {..} SE = Pos x (y - 1) 37 | step Pos {..} S = Pos (x - 1) (y - 1) 38 | step Pos {..} SW = Pos (x - 1) y 39 | step Pos {..} NW = Pos x (y + 1) 40 | 41 | -- | Returns the minimum number of steps required to reach the origin. 42 | walk :: Pos -> Int 43 | walk Pos {..} = (abs x + abs y + abs (x - y)) `div` 2 44 | 45 | day11a :: String -> Int 46 | day11a = walk . foldl' step (Pos 0 0) . parse 47 | 48 | day11b :: String -> Int 49 | day11b = maximum . map walk . scanl' step (Pos 0 0) . parse 50 | 51 | {- 52 | ( 2, 1) ( 3, 0) 53 | ( 1, 1) ( 2, 0) ( 3,-1) 54 | ( 1, 0) ( 2,-1) 55 | ( 0, 0) ( 1,-1) ( 2,-2) 56 | ( 0,-1) ( 1,-2) Trapezoidal 57 | ------------------------------------------- 58 | ( 1, 3) ( 3, 3) Cartesian 59 | ( 0, 2) ( 2, 2) ( 4, 2) 60 | ( 1, 1) ( 3, 1) 61 | ( 0, 0) ( 2, 0) ( 4, 0) 62 | ( 1,-1) ( 3, -1) 63 | -} 64 | 65 | chart :: String -> Chart 66 | chart input = Chart {..} where 67 | positions = scanl' step (Pos 0 0) $ parse input 68 | points = [(x - y, x + y) | Pos {..} <- positions] 69 | distances = map walk positions 70 | bounds = 71 | ((minimum $ map fst points, minimum $ map snd points), 72 | (maximum $ map fst points, maximum $ map snd points)) 73 | maxDistance = maximum distances 74 | path = zip points distances 75 | -------------------------------------------------------------------------------- /src/Day12.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day12 3 | Description: 4 | -} 5 | {-# LANGUAGE ViewPatterns #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day12 (day12a, day12b) where 8 | 9 | import Data.Char (isDigit) 10 | import Data.List (unfoldr) 11 | import qualified Data.Map.Lazy as Map ((!?), fromList, keysSet) 12 | import Data.Map.Lazy (Map) 13 | import Data.Maybe (fromMaybe) 14 | import qualified Data.Set as Set ((\\), empty, insert, member, minView, size) 15 | import Data.Set (Set) 16 | 17 | -- | Returns a mapping containing each input line "0 -> 1, 2..". 18 | parse :: String -> Map Int [Int] 19 | parse = Map.fromList . map parseLine . lines where 20 | parseLine (words -> x : "<->" : xs) = (read x, read . filter isDigit <$> xs) 21 | 22 | -- | Returns the set of all nodes reachable from a seed node. 23 | connected :: (Ord a) => Map a [a] -> a -> Set a 24 | connected neighbors = grow Set.empty . (:[]) where 25 | grow s [] = s 26 | grow s (x:xs) = grow (Set.insert x s) $ queue ++ xs where 27 | queue = if Set.member x s then [] else fromMaybe [] $ neighbors Map.!? x 28 | 29 | day12a :: String -> Int 30 | day12a = Set.size . flip connected 0 . parse 31 | 32 | day12b :: String -> Int 33 | day12b input = length . unfoldr (fmap dropConnected . Set.minView) $ 34 | Map.keysSet neighbors where 35 | neighbors = parse input 36 | dropConnected (x, xs) = ((), xs Set.\\ connected neighbors x) 37 | -------------------------------------------------------------------------------- /src/Day13.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day13 3 | Description: 4 | -} 5 | {-# LANGUAGE TransformListComp #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day13 (day13a, day13b) where 8 | 9 | import Data.List ((\\)) 10 | import GHC.Exts (groupWith, the) 11 | 12 | -- | Maps each @x: y@ line in the input to a @(x, y)@ tuple. 13 | parse :: String -> [(Int, Int)] 14 | parse = map parseLine . lines where 15 | parseLine input = head 16 | [(d, n) | (d, ':':' ':rest) <- reads input, (n, "") <- reads rest] 17 | 18 | -- | @combine (rs1, q1) (rs2, q2)@ returns an @(rs3, lcm q1 q2)@ such that 19 | -- 20 | -- prop> and [r3 `mod` q1 `elem` rs1 && r3 `mod` q2 `elem` rs2 | r3 <- rs3] 21 | combine :: (Integral a) => ([a], a) -> ([a], a) -> ([a], a) 22 | combine (rs1, q1) (rs2, q2) = (rs3, q3) where 23 | q3 = lcm q1 q2 24 | rs3 = common (broaden rs1 q1) (broaden rs2 q2) 25 | broaden rs q = [0, q .. q3 - 1] >>= flip map rs . (+) 26 | common xs@(x:xs') ys@(y:ys') = case compare x y of 27 | EQ -> x : common xs' ys' 28 | LT -> common xs' ys 29 | GT -> common xs ys' 30 | common _ _ = [] 31 | 32 | day13a :: String -> Int 33 | day13a input = sum [d * n | (d, n) <- parse input, d `mod` (2 * n - 2) == 0] 34 | 35 | day13b :: String -> Int 36 | day13b input = head . fst $ foldl combine ([0], 1) 37 | [ ([0 .. q - 1] \\ [q - 1 - (t - 1) `mod` q | t <- d], q) 38 | | (d, n) <- parse input 39 | , then group by n using groupWith 40 | , let q = 2 * the n - 2 41 | ] 42 | -------------------------------------------------------------------------------- /src/Day14.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day14 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day14 (bits, day14a, day14b, groupedBits) where 7 | 8 | import Control.Parallel.Strategies (parMap, rpar) 9 | import Data.Bits (FiniteBits, finiteBitSize, popCount, testBit) 10 | import Data.Graph (components, graphFromEdges) 11 | import Data.List (zip3, zip4) 12 | import Data.Tree (flatten) 13 | import Data.Word (Word8) 14 | import Day10 (hashString) 15 | 16 | -- | Given an input string, returns 'hashString' of the string with a dash and 17 | -- each integer in @[0..127]@. 18 | grid :: String -> [[Word8]] 19 | grid input = parMap rpar hashString $ ((input ++) . ('-':) . show) <$> [0..127] 20 | 21 | -- | Returns a list of bits from most-significant to least-significant. 22 | bits :: (FiniteBits b) => b -> [Bool] 23 | bits b = map (testBit b) $ reverse [0 .. finiteBitSize b - 1] 24 | 25 | -- | Returns a list of the coordinates of connected groups of bits. 26 | groupedBits :: (FiniteBits b) => [[b]] -> [[(Int, Int)]] 27 | groupedBits input = map vertex . flatten <$> components gr where 28 | (gr, f, _) = graphFromEdges 29 | [ ((), (x, y), [(x - 1, y) | left] ++ [(x, y - 1) | up]) 30 | | let bitgrid = concatMap bits <$> input 31 | , (y, line, prev) <- zip3 [0..] bitgrid $ repeat False : bitgrid 32 | , (x, True, up, left) <- zip4 [0..] line prev $ False : line 33 | ] 34 | vertex v = let (_, xy, _) = f v in xy 35 | 36 | day14a :: String -> Int 37 | day14a = sum . map popCount . concat . grid 38 | 39 | day14b :: String -> Int 40 | day14b = length . groupedBits . grid 41 | -------------------------------------------------------------------------------- /src/Day15.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day15 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day15 (day15a, day15b) where 7 | 8 | import Data.Word (Word32) 9 | import Data.List (stripPrefix) 10 | import LCGMatches (countMatches, countMatchesMod) 11 | 12 | -- | Returns the initial values for generators A and B. 13 | parse :: String -> (Word32, Word32) 14 | parse input = (a, b) where 15 | [line1, line2] = lines input 16 | Just a = read <$> stripPrefix "Generator A starts with " line1 17 | Just b = read <$> stripPrefix "Generator B starts with " line2 18 | 19 | day15a :: String -> Int 20 | day15a = countMatches 40000000 . parse 21 | 22 | day15b :: String -> Int 23 | day15b = countMatchesMod 5000000 . parse 24 | -------------------------------------------------------------------------------- /src/Day16.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day16 3 | Description: 4 | -} 5 | {-# LANGUAGE FlexibleContexts, ViewPatterns #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day16 (day16a, day16b) where 8 | 9 | import Data.Array.IArray (IArray, Ix, (!), amap, bounds, elems, ixmap, listArray) 10 | import Data.Array.Unboxed (UArray) 11 | import Data.Bool (bool) 12 | import Data.Char (chr, isSpace, ord) 13 | import Data.Ix (range) 14 | import Data.List (foldl') 15 | import Data.List.Split (wordsBy) 16 | 17 | -- | A dance move. 18 | data Move i e = Spin i | Exchange i i | Partner e e 19 | 20 | -- | Split words by whitespaces or commas. 21 | words' :: String -> [String] 22 | words' = wordsBy $ \c -> c == ',' || isSpace c 23 | 24 | -- | Parse a list of dance moves. 25 | parse :: String -> [Move Int Char] 26 | parse = map parseMove . words' where 27 | parseMove ('s' : d) = Spin $ read d 28 | parseMove ('x' : (break (== '/') -> (x, _:y))) = Exchange (read x) (read y) 29 | parseMove ['p', a, '/', b] = Partner a b 30 | 31 | -- | Compose two permutations. 32 | (-*-) :: (IArray a e, IArray a' i, Ix i) => a i e -> a' i i -> a i e 33 | a -*- b = ixmap (bounds a) (b !) a 34 | infixl 7 -*- 35 | 36 | -- | Repeat a permutation. 37 | (-^-) :: (IArray a i, Ix i) => a i i -> Int -> a i i 38 | a -^- 0 = listArray <*> range $ bounds a 39 | a -^- n 40 | | (h, 0) <- n `divMod` 2 = (a -*- a) -^- h 41 | | (h, 1) <- n `divMod` 2 = (a -*- a) -^- h -*- a 42 | infixr 8 -^- 43 | 44 | -- | Like 'id', but swapping the two given values. 45 | exchange :: (Eq a) => a -> a -> a -> a 46 | exchange x y z 47 | | x == z = y 48 | | y == z = x 49 | | otherwise = z 50 | 51 | -- | Given a list of dance moves, map out the resulting partner changes. 52 | permuteNames :: (IArray a Char) => Int -> [Move i Char] -> a Char Char 53 | permuteNames size moves = foldl' permuteName 54 | (listArray ('a', chr $ ord 'a' + size - 1) ['a'..]) 55 | [(x, y) | Partner x y <- moves] where 56 | permuteName arr (x, y) = amap (exchange x y) arr 57 | 58 | -- | Given a list of dance moves, map out the resulting spins and exchanges. 59 | permuteIndices :: (IArray a Int) => Int -> [Move Int e] -> a Int Int 60 | permuteIndices size = foldl' permuteIndex (listArray (0, size - 1) [0..]) where 61 | permuteIndex arr (Spin d) = 62 | ixmap (bounds arr) ((`mod` size) . subtract d) arr 63 | permuteIndex arr (Exchange x y) = ixmap (bounds arr) (exchange x y) arr 64 | permuteIndex arr _ = arr 65 | 66 | day16a :: Int -> String -> String 67 | day16a = flip day16b 1 68 | 69 | day16b :: Int -> Int -> String -> String 70 | day16b size n input = map (elems pn !!) (elems pi) where 71 | dance = parse input 72 | pn = permuteNames size dance -^- n :: UArray Char Char 73 | pi = permuteIndices size dance -^- n :: UArray Int Int 74 | -------------------------------------------------------------------------------- /src/Day17.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day17 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day17 (day17a, day17b) where 7 | 8 | import Data.Bool (bool) 9 | import Data.List (foldl') 10 | import qualified Data.Sequence as Seq (index, insertAt, length, singleton) 11 | 12 | day17a :: Int -> Int 13 | day17a step = Seq.index s $ (i + 1) `mod` Seq.length s where 14 | (i, s) = foldl' insert (0, Seq.singleton 0) [1..2017] 15 | insert (pos, s) value = (pos', Seq.insertAt pos' value s) where 16 | pos' = (pos + step) `mod` Seq.length s + 1 17 | 18 | day17b :: Int -> Int 19 | day17b step = insert 0 1 0 where 20 | insert pos len next 21 | | len' > 50000000 = next 22 | | otherwise = insert pos' len' $! bool next (len + q) $ pos' == 1 where 23 | q = (len - pos) `div` (step + 1) 24 | pos' = (pos + (q + 1) * (step + 1) - 1) `mod` (len + q) + 1 25 | len' = len + q + 1 26 | -------------------------------------------------------------------------------- /src/Day18.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day18 3 | Description: 4 | -} 5 | {-# LANGUAGE FlexibleContexts, LambdaCase, NamedFieldPuns, RecordWildCards, ViewPatterns #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day18 (day18a, day18b) where 8 | 9 | import Control.Applicative (liftA2) 10 | import Control.Arrow (first) 11 | import Control.Monad.Except (catchError, runExceptT, throwError) 12 | import Control.Monad.State (evalState, get, modify, put) 13 | import Control.Monad.Writer (execWriterT, tell) 14 | import Data.Array (Array, (!), bounds, listArray) 15 | import Data.Int (Int64) 16 | import Data.Ix (Ix, inRange) 17 | import qualified Data.Map.Lazy as Map (empty, insert, lookup, singleton) 18 | import Data.Map.Lazy (Map) 19 | import Data.Maybe (catMaybes, fromJust, fromMaybe, listToMaybe) 20 | import Data.Monoid (First(..)) 21 | import Text.Read (readMaybe) 22 | 23 | -- | A single instruction. 24 | -- 25 | -- 'Either' represents either a register reference or an immediate value. 26 | data Ins reg val 27 | = Rcv reg 28 | | Snd (Either reg val) 29 | | Op (val -> val -> val) reg (Either reg val) 30 | | Jgz (Either reg val) (Either reg val) 31 | 32 | -- | A specification for how to run a machine. 33 | data MachineSpec m pc reg val = MachineSpec 34 | { program :: Array pc (Ins reg val) -- ^ The list of instructions. 35 | , send :: val -> m () -- ^ Handler for 'Snd'. 36 | , recv :: val -> m val -- ^ Handler for 'Rcv'. 37 | } 38 | 39 | -- | The current state of a machine. 40 | data MachineState pc reg val 41 | -- | The machine is running. 42 | = MachineState 43 | { pc :: pc -- ^ The program counter. 44 | , regs :: Map reg val -- ^ The registers. 45 | } 46 | -- | The machine is stopped. 47 | | MachineTerminated 48 | 49 | -- | Parse an assembly listing to instructions. 50 | parse :: (Integral a, Read a) => String -> [Ins String a] 51 | parse = map parseIns . lines where 52 | parseIns line = case words line of 53 | ["rcv", reg] -> Rcv reg 54 | ["snd", val] -> Snd (read' val) 55 | ["set", reg, val] -> Op (flip const) reg (read' val) 56 | ["add", reg, val] -> Op (+) reg (read' val) 57 | ["mul", reg, val] -> Op (*) reg (read' val) 58 | ["mod", reg, val] -> Op mod reg (read' val) 59 | ["jgz", cnd, jmp] -> Jgz (read' cnd) (read' jmp) 60 | read' s = maybe (Left s) Right $ readMaybe s 61 | 62 | -- | Evaluate a single instruction. 63 | step :: (Monad m, Ix pc, Num pc, Ord reg, Integral val, Ord val) => 64 | MachineSpec m pc reg val -> MachineState pc reg val -> 65 | m (MachineState pc reg val) 66 | step MachineSpec {..} s@MachineState {..} = case program ! pc of 67 | Rcv reg -> do 68 | val <- recv $ loadReg reg 69 | check s {pc = pc + 1, regs = Map.insert reg val regs} 70 | Snd (load -> val) -> send val >> check s {pc = pc + 1} 71 | Op f reg@(loadReg -> src) (load -> val) -> 72 | check s {pc = pc + 1, regs = Map.insert reg (f src val) regs} 73 | Jgz (load -> cnd) (load -> jmp) -> 74 | check s {pc = pc + (if cnd > 0 then fromIntegral jmp else 1)} 75 | where 76 | loadReg = fromMaybe 0 . flip Map.lookup regs 77 | load = either loadReg id 78 | check MachineState {pc} | not (inRange (bounds program) pc) = 79 | pure MachineTerminated 80 | check state = pure state 81 | 82 | -- | Run a machine until its state reaches 'MachineTerminated'. 83 | loop :: (Monad m, Ix pc, Num pc, Ord reg, Integral val, Ord val) => 84 | MachineSpec m pc reg val -> MachineState pc reg val -> m () 85 | loop spec = loop' where 86 | loop' MachineTerminated = pure () 87 | loop' state = step spec state >>= loop' 88 | 89 | day18a :: String -> Int64 90 | day18a input = fromJust . getFirst . flip evalState 0 . execWriterT $ 91 | loop spec MachineState {pc = 0, regs = Map.empty} where 92 | program = parse input 93 | spec = MachineSpec 94 | { program = listArray (0, length program - 1) program 95 | , send = put 96 | , recv = \case 97 | 0 -> pure 0 98 | _ -> get >>= liftA2 (<$) id (tell . First . Just) 99 | } 100 | 101 | day18b :: String -> Int 102 | day18b input = 103 | let program = parse input :: [Ins String Int64] 104 | recvJust (n, Just val : rest) = val <$ put (n, rest) 105 | recvJust (n, Nothing:rest) | n > 0 = recvJust (n - 1, rest) 106 | recvJust _ = throwError () 107 | spec = MachineSpec 108 | { program = listArray (0, length program - 1) program 109 | , send = \val -> modify (first succ) >> tell [Just val] 110 | , recv = const $ tell [Nothing] >> get >>= recvJust 111 | } 112 | state p = MachineState {pc = 0, regs = Map.singleton "p" p} 113 | m0 = flip evalState (0, m1) . execWriterT . runExceptT . 114 | flip catchError (const $ pure ()) . loop spec $ state 0 115 | m1 = flip evalState (0, m0) . execWriterT . runExceptT . 116 | flip catchError (const $ pure ()) . loop spec $ state 1 117 | in length $ catMaybes m1 118 | -------------------------------------------------------------------------------- /src/Day19.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day19 3 | Description: 4 | -} 5 | {-# LANGUAGE FlexibleContexts, TypeApplications #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day19 (day19a, day19b) where 8 | 9 | import Data.Array.IArray (IArray, (!), array, bounds) 10 | import Data.Array.Unboxed (UArray) 11 | import Data.Char (isAlpha, isSpace) 12 | import Data.Ix (Ix, inRange) 13 | import Data.List ((\\), elemIndex) 14 | 15 | -- | Represents a cardinal direction. 16 | data Direction = U | D | L | R deriving (Bounded, Enum, Eq) 17 | 18 | -- | Returns the 2D representation of a string by lines and the index of the 19 | -- only @|@ pipe character on the first line. 20 | parse :: (IArray a Char) => String -> (a (Int, Int) Char, (Int, Int)) 21 | parse input = (maze, (x0 + 1, 1)) where 22 | Just x0 = elemIndex '|' row0 23 | rows@(row0:_) = lines input 24 | maze = array ((1, 1), (maximum $ length <$> rows, length rows)) 25 | [((x, y), c) | (y, row) <- zip [1..] rows, (x, c) <- zip [1..] row] 26 | 27 | -- | Rotates a cardinal direction by 180 degrees. 28 | rot180 :: Direction -> Direction 29 | rot180 U = D 30 | rot180 D = U 31 | rot180 L = R 32 | rot180 R = L 33 | 34 | -- | Moves a point one step in a cardinal direction. 35 | move :: (Num a) => (a, a) -> Direction -> (a, a) 36 | move (x, y) U = (x, y - 1) 37 | move (x, y) D = (x, y + 1) 38 | move (x, y) L = (x - 1, y) 39 | move (x, y) R = (x + 1, y) 40 | 41 | -- | Returns the cardinal directions around a point which contain non-space. 42 | joints :: (IArray a Char, Ix i, Num i) => a (i, i) Char -> (i, i) -> [Direction] 43 | joints maze p = filter f [minBound .. maxBound] where 44 | f d = (&&) <$> inRange (bounds maze) <*> not . isSpace . (maze !) $ move p d 45 | 46 | -- | Walks a maze from a starting point in a direction until it runs of 47 | -- non-space characters to follow. Returns a list of all characters on the walk. 48 | walk :: (IArray a Char, Ix i, Num i) => 49 | a (i, i) Char -> (i, i) -> Direction -> String 50 | walk maze p d 51 | | not (inRange (bounds maze) p) || isSpace c = [] 52 | | otherwise = c : (walk maze =<< move p) (if c == '+' then d' else d) 53 | where 54 | c = maze ! p 55 | [d'] = joints maze p \\ [rot180 d] 56 | 57 | day19a :: String -> String 58 | day19a input = filter isAlpha $ walk maze p0 D where 59 | (maze, p0) = parse @UArray input 60 | 61 | day19b :: String -> Int 62 | day19b input = length $ walk maze p0 D where (maze, p0) = parse @UArray input 63 | -------------------------------------------------------------------------------- /src/Day2.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day2 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day2 (day2a, day2b) where 7 | 8 | import Control.Monad (liftM2) 9 | 10 | -- | The 'readSpreadsheet' function splits lines to rows and spaces to columns. 11 | readSpreadsheet :: String -> [[Int]] 12 | readSpreadsheet = map (map read . words) . lines 13 | 14 | day2a :: String -> Int 15 | day2a = sum . map (liftM2 (-) maximum minimum) . readSpreadsheet 16 | 17 | day2b :: String -> Int 18 | day2b = sum . map checksum . readSpreadsheet where 19 | checksum l = head [q | (q, 0) <- liftM2 quotRem l l, q /= 1] 20 | -------------------------------------------------------------------------------- /src/Day20.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day20 3 | Description: 4 | -} 5 | {-# LANGUAGE NamedFieldPuns, RecordWildCards, ViewPatterns #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day20 (day20a, day20b) where 8 | 9 | import Control.Arrow (second) 10 | import Data.Function (on) 11 | import Data.List (groupBy, minimumBy, sortOn, tails) 12 | import qualified Data.Map.Strict as Map (fromListWith, lookup) 13 | import Data.Ord (comparing) 14 | 15 | -- | A 3D vector. 16 | data Vec3 a = Vec3 {x :: !a, y :: !a, z :: !a} deriving (Eq, Ord) 17 | 18 | -- | A point with position, velocity, and acceleration in 3D space. 19 | data Point a = Point {pos :: !(Vec3 a), vel :: !(Vec3 a), acc :: !(Vec3 a)} 20 | 21 | -- | Read non-overlapping substrings. 22 | readMany :: (Read a) => String -> [a] 23 | readMany s = take 1 (tails s >>= reads) >>= uncurry ((. readMany) . (:)) 24 | 25 | -- | Reads points. 26 | parse :: (Read a) => String -> [Point a] 27 | parse = map parseLine . lines where 28 | parseLine (readMany -> [px, py, pz, vx, vy, vz, ax, ay, az]) = 29 | Point {pos = Vec3 px py pz, vel = Vec3 vx vy vz, acc = Vec3 ax ay az} 30 | 31 | -- | Pointwise addition. 32 | (*+*) :: (Num a) => Vec3 a -> Vec3 a -> Vec3 a 33 | Vec3 x y z *+* Vec3 u v w = Vec3 (x + u) (y + v) (z + w) 34 | infixl 3 *+* 35 | 36 | -- | Pointwise subtraction. 37 | (*-*) :: (Num a) => Vec3 a -> Vec3 a -> Vec3 a 38 | Vec3 x y z *-* Vec3 u v w = Vec3 (x - u) (y - v) (z - w) 39 | infixl 3 *-* 40 | 41 | -- | Performs one timestep of velocity and position updates. 42 | step :: (Num a) => Point a -> Point a 43 | step p@Point {..} = p {pos = pos *+* v', vel = v'} where v' = vel *+* acc 44 | 45 | -- | Returns the Manhattan distance of a vector to the origin. 46 | manhattan :: (Num a) => Vec3 a -> a 47 | manhattan Vec3 {..} = abs x + abs y + abs z 48 | 49 | -- | Returns true if repeated 'step' will not change the sign of any component 50 | -- of velocity and position. 51 | signumsMatch :: (Eq a, Num a) => Point a -> Bool 52 | signumsMatch Point {..} = 53 | (x acc == 0 || signum (x acc) == signum (x vel)) && 54 | (x acc == 0 && x vel == 0 || signum (x vel) == signum (x pos)) && 55 | (y acc == 0 || signum (y acc) == signum (y vel)) && 56 | (y acc == 0 && y vel == 0 || signum (y vel) == signum (y pos)) && 57 | (z acc == 0 || signum (z acc) == signum (z vel)) && 58 | (z acc == 0 && z vel == 0 || signum (z vel) == signum (z pos)) 59 | 60 | -- | Filters out all elements which are duplicated under transformation. 61 | collide :: (Ord a) => (b -> a) -> [b] -> [b] 62 | collide f points = 63 | filter ((== Just 1) . (`Map.lookup` counts) . f) points where 64 | counts = Map.fromListWith (+) [(f p, 1) | p <- points] 65 | 66 | day20a :: String -> Int 67 | day20a input = fst $ minimumBy (comparing $ manhattan . pos . snd) points''' 68 | where 69 | points = zip [0..] $ parse input 70 | minAcc = minimum $ manhattan . acc . snd <$> points 71 | points' = filter ((== minAcc) . manhattan . acc . snd) points 72 | points'':_ = dropWhile (any $ not . signumsMatch . snd) $ 73 | iterate (map $ second step) points' 74 | minVel = minimum $ manhattan . vel . snd <$> points'' 75 | points''' = filter ((== minVel) . manhattan . vel . snd) points'' 76 | 77 | day20b :: String -> [Int] 78 | day20b = 79 | map fst . head . filter (done . map snd) . 80 | iterate (collide (pos . snd) . map (second step)) . 81 | sortOn (manhattan . acc . snd) . zip [0..] . parse where 82 | done points = all signumsMatch points && and 83 | [ dAcc <== dVel && dVel <== dPos 84 | | let sgnVec3 Vec3 {..} = (signum x, signum y, signum z) 85 | Vec3 x y z <== Vec3 u v w = 86 | abs x <= abs u && abs y <= abs v && abs z <= abs w 87 | infix 4 <== 88 | , octant <- groupBy ((==) `on` sgnVec3 . pos) points 89 | , p:ps <- tails octant 90 | , q <- ps 91 | , let dPos = pos p *-* pos q 92 | dVel = vel p *-* vel q 93 | dAcc = acc p *-* acc q 94 | ] 95 | -------------------------------------------------------------------------------- /src/Day21.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day21 3 | Description: 4 | -} 5 | {-# LANGUAGE TupleSections, ViewPatterns #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day21 (day21, day21a, day21b) where 8 | 9 | import Data.List (foldl', transpose) 10 | import Data.List.Split (chunksOf, splitOn) 11 | import qualified Data.Map.Lazy as Map ((!), assocs, empty, fromList, fromListWith, insert, map, member, unionsWith) 12 | import Data.Map.Lazy (Map) 13 | 14 | -- | 8 affine transformations. 15 | transforms :: [[[a]] -> [[a]]] 16 | transforms = [id, f, g, f . g, t, t . f, t . g, t . f . g] where 17 | f = reverse 18 | g = map reverse 19 | t = transpose 20 | 21 | -- | Parse a list of enhancements. 22 | parse :: String -> Map [[Bool]] [[Bool]] 23 | parse = Map.fromList . concatMap parseLine . lines where 24 | parseLine s = let [a, "=>", b] = words s in 25 | [ (transform a', b') 26 | | let a' = map (== '#') <$> splitOn "/" a 27 | , let b' = map (== '#') <$> splitOn "/" b 28 | , transform <- transforms 29 | ] 30 | 31 | -- | The glider. 32 | start :: [[Bool]] 33 | start = map (== '#') <$> splitOn "/" ".#./..#/###" 34 | 35 | -- | Expand sub-squares according to the rules map. 36 | step :: (Ord a) => Map [[a]] [[a]] -> [[a]] -> [[a]] 37 | step rules grid = assemble $ map (rules Map.!) exploded where 38 | (d, n):_ = [(d, n) | d <- [2..], (n, 0) <- [length grid `divMod` d]] 39 | exploded = chunksOf d grid >>= transpose . map (chunksOf d) 40 | assemble parts = chunksOf n parts >>= map concat . transpose 41 | 42 | -- | Returns the same valeu for all transformations of the same block. 43 | canonicalize :: (Ord a) => [[a]] -> [[a]] 44 | canonicalize grid = minimum [t grid | t <- transforms] 45 | 46 | -- | Returns the number of occurrences of each type of 3x3 block, starting from 47 | -- a 3x3 block, after iterating the rules @3*n@ times. 48 | --step3 :: (Ord a) => Map [[a]] [[a]] -> [[a]] -> Int -> [([[a]], Int)] 49 | step3 rules (canonicalize -> grid) n = iterate expand3 [(grid, 1)] !! n where 50 | rules3 = step' Map.empty grid 51 | step' expansions grid 52 | | Map.member grid expansions = expansions 53 | | otherwise = foldl' step' (Map.insert grid counts expansions) parts 54 | where 55 | parts = chunksOf 3 (iterate (step rules) grid !! 3) >>= 56 | map canonicalize . transpose . map (chunksOf 3) 57 | counts = Map.fromListWith (+) $ (, 1) <$> parts 58 | expand3 counts = Map.assocs $ Map.unionsWith (+) 59 | [Map.map (* count) $ rules3 Map.! grid | (grid, count) <- counts] 60 | 61 | -- | @day21 n input@ returns the number of bits set in the @n@-th 'step' of 62 | -- transforming the 'start' glider using 'parse' rules from @input@. 63 | day21 :: Int -> String -> Int 64 | day21 n (parse -> rules) = sum 65 | [ count * length (iterate (step rules) grid !! r >>= filter id) 66 | | (grid, count) <- step3 rules start q 67 | ] where (q, r) = n `quotRem` 3 68 | 69 | day21a :: String -> Int 70 | day21a = day21 5 71 | 72 | day21b :: String -> Int 73 | day21b = day21 18 74 | -------------------------------------------------------------------------------- /src/Day22.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day22 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day22 (day22a, day22b) where 7 | 8 | import Control.Monad.ST (runST) 9 | import Data.Bool (bool) 10 | import Data.List (genericLength) 11 | import Data.Maybe (fromMaybe) 12 | import Data.Word (Word64, Word8) 13 | import GrowArray (GrowArray, newGrowArray, readGrowArray, writeGrowArray) 14 | import Morton (Z(..), decX, decY, incX, incY, toZ) 15 | 16 | -- | A cardinal direction. 17 | data O = U | R | D | L deriving (Bounded, Enum, Eq) 18 | 19 | -- | Node state. 20 | data S = C | W | I | F deriving (Bounded, Enum, Eq) 21 | 22 | -- | 'succ' with wraparound. 23 | next :: (Bounded a, Enum a, Eq a) => a -> a 24 | next a = if a == maxBound then minBound else succ a 25 | 26 | -- | 'pred' with wraparound. 27 | prev :: (Bounded a, Enum a, Eq a) => a -> a 28 | prev a = if a == minBound then maxBound else pred a 29 | 30 | -- | Moves a Cartesian coordinate by one step in a direction. 31 | move :: O -> Z -> Z 32 | move U = decY 33 | move R = incX 34 | move D = incY 35 | move L = decX 36 | 37 | -- | Parses a string as a 2-D grid centered around @(0, 0)@, returning positions 38 | -- with a @'#'@ character. 39 | parse :: String -> [Z] 40 | parse s = 41 | [ toZ x y 42 | | let h = genericLength $ lines s 43 | , (y, line) <- zip [- h `div` 2 ..] $ lines s 44 | , let w = genericLength line 45 | , (x, '#') <- zip [- w `div` 2 ..] line 46 | ] 47 | 48 | -- | Returns all viral activity from an initial state. 49 | day22 :: (Enum a, Eq a) => 50 | a -> (a -> O -> O) -> (a -> a) -> a -> Int -> [Z] -> Int 51 | day22 infected turn mut def n input = runST $ do 52 | let def' = fromIntegral $ fromEnum def :: Word8 53 | infected' = fromIntegral $ fromEnum infected 54 | grid <- newGrowArray (0, 0) def' 55 | sequence_ [writeGrowArray grid z infected' | Z z <- input] 56 | let loop 0 _ _ k = pure k 57 | loop n dir pos k = do 58 | a <- toEnum . fromIntegral <$> readGrowArray grid (getZ pos) 59 | let a' = mut a 60 | dir' = turn a dir 61 | pos' = move dir' pos 62 | writeGrowArray grid (getZ pos) . fromIntegral $ fromEnum a' 63 | loop (n - 1) dir' pos' $! if a' == infected then k + 1 else k 64 | loop n U (toZ 0 0) 0 65 | 66 | day22a :: String -> Int 67 | day22a = day22 True (bool prev next) next False 10000 . parse 68 | 69 | day22b :: String -> Int 70 | day22b = day22 I turn next C 10000000 . parse where 71 | turn C = prev 72 | turn W = id 73 | turn I = next 74 | turn F = next . next 75 | -------------------------------------------------------------------------------- /src/Day23.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day23 3 | Description: 4 | -} 5 | {-# LANGUAGE LambdaCase, NamedFieldPuns, PatternGuards, RecordWildCards, TypeApplications, ViewPatterns #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day23 (day23a, day23b) where 8 | 9 | import Data.Array.IArray (IArray, (!), (//), listArray) 10 | import Data.Array.Unboxed (UArray) 11 | import Data.Ix (Ix) 12 | import Data.List (findIndices) 13 | import Math.NumberTheory.Primes (isPrime) 14 | import Text.Read (readMaybe) 15 | 16 | -- | A single instruction. 17 | -- 18 | -- 'Either' represents either a register reference or an immediate value. 19 | data Ins reg imm 20 | = Set {reg :: reg, val :: Either reg imm} 21 | | Sub {reg :: reg, val :: Either reg imm} 22 | | Mul {reg :: reg, val :: Either reg imm} 23 | | Jnz {cnd :: Either reg imm, jmp :: Either reg imm} 24 | 25 | -- | The current state of a machine. 26 | data State a reg imm = State {pc :: Int, regs :: a reg imm} 27 | 28 | -- | Parses an immediate value or a single character register name. 29 | parseVal :: (Read imm) => String -> Either Char imm 30 | parseVal (readMaybe -> Just imm) = Right imm 31 | parseVal [reg] = Left reg 32 | 33 | -- | Parses an assembly listing to instructions. 34 | parse :: (Read imm) => String -> [Ins Char imm] 35 | parse = map (parseIns . words) . lines where 36 | parseIns ["set", [reg], parseVal -> val] = Set {..} 37 | parseIns ["sub", [reg], parseVal -> val] = Sub {..} 38 | parseIns ["mul", [reg], parseVal -> val] = Mul {..} 39 | parseIns ["jnz", parseVal -> cnd, parseVal -> jmp] = Jnz {..} 40 | 41 | -- | Evaluates a single instruction. 42 | step :: (IArray a imm, Ix reg, Integral imm) => 43 | [Ins reg imm] -> State a reg imm -> Maybe (State a reg imm) 44 | step ins State {pc} | pc < 0 || null (drop pc ins) = Nothing 45 | step ins state@State {..} = Just $ case ins !! pc of 46 | Set {..} -> State (pc + 1) (regs // [(reg, load val)]) 47 | Sub {..} -> State (pc + 1) (regs // [(reg, regs ! reg - load val)]) 48 | Mul {..} -> State (pc + 1) (regs // [(reg, regs ! reg * load val)]) 49 | Jnz {..} 50 | | load cnd == 0 -> state {pc = pc + 1} 51 | | otherwise -> state {pc = pc + fromIntegral (load jmp)} 52 | where 53 | load = either (regs !) id 54 | 55 | -- | Evaluates the @f = 0 if !isPrime(b)@ sequence, or a single instruction. 56 | stepOptimized :: (IArray a imm, Ix reg, Integral imm) => 57 | [Ins reg imm] -> State a reg imm -> Maybe (State a reg imm) 58 | stepOptimized ins State {pc} | pc < 0 = Nothing 59 | stepOptimized ins state@State {..} = case drop pc ins of 60 | ( Set d (Right 2) : 61 | Set e (Right 2) : 62 | Set g (Left ((== d) -> True)) : 63 | Mul ((== g) -> True) (Left ((== e) -> True)) : 64 | Sub ((== g) -> True) b : 65 | Jnz (Left ((== g) -> True)) (Right 2) : 66 | Set f f0 : 67 | Sub ((== e) -> True) (Right (-1)) : 68 | Set ((== g) -> True) (Left ((== e) -> True)) : 69 | Sub ((== g) -> True) ((== b) -> True) : 70 | Jnz (Left ((== g) -> True)) (Right (-8)) : 71 | Sub ((== d) -> True) (Right (-1)) : 72 | Set ((== g) -> True) (Left ((== d) -> True)) : 73 | Sub ((== g) -> True) ((== b) -> True) : 74 | Jnz (Left ((== g) -> True)) (Right (-13)) : _) 75 | | d /= e, d /= g, d /= f, e /= g, e /= f, g /= f 76 | , either (not . (`elem` [d, e, g, f])) (const True) b 77 | , either (not . (`elem` [d, e, g, f])) (const True) f0 78 | , either Just (const Nothing) b /= either Just (const Nothing) f0 -> 79 | let b' = either (regs !) id b in Just . State (pc + 15) $ regs // 80 | ( [(d, b'), (e, b'), (g, 0)] ++ 81 | [(f, either (regs !) id f0) | not . isPrime $ fromIntegral b'] ) 82 | _ -> step ins state 83 | 84 | -- | Iterates a function until 'Nothing'. 85 | iterateMaybe :: (a -> Maybe a) -> Maybe a -> [a] 86 | iterateMaybe f = maybe [] $ (:) <*> iterateMaybe f . f 87 | 88 | day23a :: String -> Int 89 | day23a input = countMuls $ iterateMaybe (step ins) $ Just state0 where 90 | ins = parse input 91 | muls = findIndices (\case Mul {} -> True; _ -> False) ins 92 | countMuls = length . filter (`elem` muls) . map pc 93 | state0 = State {pc = 0, regs = listArray @UArray @Int ('a', 'h') $ repeat 0} 94 | 95 | day23b :: String -> Int 96 | day23b input = 97 | regs (last . iterateMaybe (stepOptimized ins) $ Just state0) ! 'h' where 98 | ins = parse input 99 | state0 = 100 | State {pc = 0, regs = listArray @UArray @Int ('a', 'h') $ 1 : repeat 0} 101 | -------------------------------------------------------------------------------- /src/Day24.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day24 3 | Description: 4 | -} 5 | {-# LANGUAGE ViewPatterns #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day24 (day24a, day24b) where 8 | 9 | import Control.Arrow ((***)) 10 | import Data.Bool (bool) 11 | import Data.List.NonEmpty (NonEmpty((:|))) 12 | import Data.List.Split (splitOn) 13 | import qualified Data.Map.Lazy as Map (assocs, delete, empty, findWithDefault, fromListWith, null, singleton, union, update) 14 | import Data.Map.Lazy (Map) 15 | import Data.Semigroup (Max(..), Semigroup, sconcat) 16 | 17 | -- | Bidrectionally associates @a => n => b@ and @b => n => a@, where @n@ is an 18 | -- unique identifier for each @a/b@ line. 19 | parse :: (Ord a, Read a) => String -> Map a (Map Int a) 20 | parse = Map.fromListWith Map.union . concatMap parseLine . zip [0..] . lines 21 | where 22 | parseLine (n, splitOn "/" -> [read -> a, read -> b]) = 23 | [(a, Map.singleton n b), (b, Map.singleton n a)] 24 | 25 | -- | Deletes a key from a 'Map', returning 'Nothing' if it becomes empty. 26 | deleteOrNull :: (Ord k) => k -> Map k v -> Maybe (Map k v) 27 | deleteOrNull k m = bool Just (const Nothing) =<< Map.null $ Map.delete k m 28 | 29 | -- | Explores all bridges. 30 | buildBridge :: (Num a, Ord a, Ord b, Semigroup s) => 31 | (a -> a -> s -> s) -> s -> a -> Map a (Map b a) -> s 32 | buildBridge f k start parts = sconcat $ k :| 33 | [ buildBridge f (f start next k) next . 34 | Map.update (deleteOrNull n) start . 35 | Map.update (deleteOrNull n) next $ parts 36 | | (n, next) <- greedy $ Map.assocs $ Map.findWithDefault Map.empty start parts 37 | ] where 38 | greedy connections = case filter ((== start) . snd) connections of 39 | [] -> connections 40 | selfConnections -> selfConnections 41 | 42 | day24a :: String -> Int 43 | day24a = getMax . buildBridge toMax (Max 0) 0 . parse where 44 | toMax start next = fmap (start + next +) 45 | 46 | day24b :: String -> Int 47 | day24b = snd . getMax . buildBridge toMax (Max (0 :: Int, 0)) 0 . parse where 48 | toMax start next = fmap $ succ *** (start + next +) 49 | -------------------------------------------------------------------------------- /src/Day25.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day25 3 | Description: 4 | -} 5 | {-# LANGUAGE NoMonomorphismRestriction, RecordWildCards, TypeApplications #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day25 (day25) where 8 | 9 | import Control.Monad.ST (ST, runST) 10 | import Data.Bits (FiniteBits) 11 | import Data.Char (isSpace) 12 | import Data.Ix (Ix) 13 | import Data.List (uncons) 14 | import qualified Data.Map.Lazy as Map ((!), fromList) 15 | import Data.Map.Lazy (Map) 16 | import Data.Maybe (fromMaybe) 17 | import Data.Primitive (Prim) 18 | import qualified Data.Vector.Unboxed as V (Unbox) 19 | import Data.Word (Word8) 20 | import GrowArray (GrowArray, foldGrowArray, newGrowArray, readGrowArray, writeGrowArray) 21 | import Text.ParserCombinators.ReadP (ReadP, (<++), between, char, many1, readP_to_S, readS_to_P, sepBy, string) 22 | 23 | -- | A movement of the cursor of the Turing machine on its tape. 24 | data Move = MoveLeft | MoveRight 25 | 26 | -- | The state of the the Turing machine. 27 | data State = A | B | C | D | E | F deriving (Eq, Ord, Read) 28 | 29 | -- | An operation to be performed by the Turing machine. 30 | data Op state value = Op {write :: value, move :: Move, next :: state} 31 | 32 | -- | The setup for a run of a Turing machine. 33 | data Program state value = Program 34 | { start :: state -- ^ Initial state of the Turing machine. 35 | , steps :: Int -- ^ Number of cycles to run the Turing machine. 36 | , transitions :: Map (state, value) (Op state value) -- ^ State transitions. 37 | } 38 | 39 | -- | Parses a description to a 'Program'. 40 | parseProgram :: (Ord state, Read state, Ord value, Read value) => 41 | ReadP (Program state value) 42 | parseProgram = do 43 | let readp = readS_to_P reads 44 | start <- between (string "Begin in state ") (string ".\n") readp 45 | steps <- between (string "Perform a diagnostic checksum after ") 46 | (string " steps.\n\n") readp 47 | transitions <- fmap (Map.fromList . concat) . 48 | flip sepBy (many1 $ char '\n') $ do 49 | state <- between (string "In state ") (string ":\n") readp 50 | flip sepBy (char '\n') $ do 51 | value <- between (string " If the current value is ") 52 | (string ":\n") readp 53 | write <- between (string " - Write the value ") 54 | (string ".\n") readp 55 | move <- between (string " - Move one slot to the ") 56 | (string ".\n") $ 57 | (MoveLeft <$ string "left") <++ 58 | (MoveRight <$ string "right") 59 | next <- between (string " - Continue with state ") 60 | (string ".") readp 61 | pure ((state, value), Op {..}) 62 | pure Program {..} 63 | 64 | -- | Performs a single state transition. 65 | step :: (Ord state, Num value, Ord value, V.Unbox value, FiniteBits pos, Num pos, Ix pos, Prim pos) => 66 | Map (state, value) (Op state value) -> GrowArray s pos value -> 67 | (pos, state) -> ST s (pos, state) 68 | step transitions tape (pos, state) = do 69 | val <- readGrowArray tape pos 70 | let Op {..} = transitions Map.! (state, val) 71 | pos' = case move of MoveLeft -> pos - 1; MoveRight -> pos + 1 72 | (pos', next) <$ writeGrowArray tape pos write 73 | 74 | day25 :: String -> Int 75 | day25 input = runST $ newGrowArray @Int (0, 0) 0 >>= loop steps (0, start) where 76 | (Program {..}, _):_ = filter (all isSpace . snd) $ 77 | readP_to_S (parseProgram @State @Word8) input 78 | loop 0 _ tape = foldGrowArray (\a e -> pure $! a + fromIntegral e) 0 tape 79 | loop n tm tape = step transitions tape tm >>= \tm -> loop (n - 1) tm tape 80 | -------------------------------------------------------------------------------- /src/Day3.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day3 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day3 (day3a, day3b) where 7 | 8 | import Data.List (mapAccumL) 9 | import qualified Data.Map.Strict as Map (insert, lookup, singleton) 10 | import Data.Maybe (mapMaybe) 11 | 12 | day3a :: Int -> Int 13 | day3a n = a + abs ((n - b) `mod` (2 * a) - a) where 14 | (a, b) = last $ zip [1..] $ takeWhile (< n) $ scanl (+) 1 [8, 16..] 15 | 16 | day3b :: Int -> Int 17 | day3b n = head $ filter (> n) values where 18 | (_, values) = mapAccumL next (Map.singleton (0, 0) 1) positions 19 | next m pos = (Map.insert pos n m, n) where 20 | n = sum . mapMaybe ((`Map.lookup` m) . add pos) $ take 8 positions 21 | _:positions = scanl add (0, 0) $ do 22 | n <- [0, 2..] 23 | replicate (n - 1) (0, -1) ++ 24 | replicate n (-1, 0) ++ 25 | replicate n (0, 1) ++ 26 | replicate (n + 1) (1, 0) 27 | add (a, b) (c, d) = (a + c, b + d) 28 | -------------------------------------------------------------------------------- /src/Day4.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day4 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day4 (day4a, day4b) where 7 | 8 | import Data.List (sort, tails, uncons) 9 | 10 | -- | The 'allUnique' function returns whether the list has no duplicates. 11 | allUnique :: (Eq a) => [a] -> Bool 12 | allUnique = not . any (maybe False (uncurry elem) . uncons) . tails 13 | 14 | day4a :: String -> Int 15 | day4a = length . filter allUnique . map words . lines 16 | 17 | day4b :: String -> Int 18 | day4b = length . filter (allUnique . map sort) . map words . lines 19 | -------------------------------------------------------------------------------- /src/Day5.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day5 3 | Description: 4 | -} 5 | {-# LANGUAGE FlexibleContexts #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day5 (day5a, day5b) where 8 | 9 | import Control.Monad (join) 10 | import Control.Monad.ST (ST, runST) 11 | import Data.Array.MArray (newListArray, readArray, writeArray) 12 | import Data.Array.ST (STUArray) 13 | import Data.Bool (bool) 14 | import Data.Ix (inRange) 15 | 16 | -- | At each step, the current item is used as a relative index shift. 17 | steps :: (Int -> Int) -- ^ After each step, mutate the previous item 18 | -> [Int] -- ^ Start at index 0 19 | -> Int -- ^ Number of steps until the index is out of bounds 20 | steps f jumps = runST $ do 21 | let bounds = (0, length jumps - 1) 22 | mem <- newListArray bounds jumps :: ST s (STUArray s Int Int) 23 | let step ip k | inRange bounds ip = do 24 | jump <- readArray mem ip 25 | writeArray mem ip $ f jump 26 | step (ip + jump) $! k + 1 27 | step _ k = return k 28 | step 0 0 29 | 30 | day5a :: String -> Int 31 | day5a = steps succ . map read . lines 32 | 33 | day5b :: String -> Int 34 | day5b = steps (join $ bool succ pred . (>= 3)) . map read . lines 35 | -------------------------------------------------------------------------------- /src/Day6.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day6 3 | Description: 4 | -} 5 | {-# LANGUAGE FlexibleContexts, TypeApplications #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day6 (day6a, day6b) where 8 | 9 | import Control.Arrow (second) 10 | import Control.Monad (msum) 11 | import Data.Array.IArray (IArray, array, assocs, bounds, listArray) 12 | import Data.Array.Unboxed (UArray) 13 | import Data.Ix (Ix, index, rangeSize) 14 | import Data.List (genericLength, genericSplitAt, maximumBy) 15 | import qualified Data.Map.Strict as Map (empty, insert, lookup) 16 | import Data.Maybe (catMaybes, listToMaybe) 17 | import Data.Ord (Down(Down), comparing) 18 | import Data.Tuple (swap) 19 | 20 | -- | Reads the words of a string to an array. 21 | parse :: (IArray a e, Ix i, Num i, Read e) => String -> a i e 22 | parse s = let l = map read $ words s in listArray (0, genericLength l - 1) l 23 | 24 | -- | Returns the index and value of first maximum in an array. 25 | top :: (IArray a e, Ix i, Ord e) => a i e -> (i, e) 26 | top = maximumBy (comparing $ second Down . swap) . assocs 27 | 28 | -- | Removes the first maximum and redistributes its value throughout the array. 29 | redistribute :: (IArray a i, Integral i, Ix i) => a i i -> a i i 30 | redistribute arr = 31 | let b = bounds arr 32 | (i, v) = top arr 33 | (q, r) = v `quotRem` fromIntegral (rangeSize b) 34 | (before, _:after) = splitAt (index b i) $ assocs arr 35 | (up, down) = genericSplitAt r $ after ++ before ++ [(i, 0)] 36 | in array b $ map (second (q + 1 +)) up ++ map (second (q +)) down 37 | 38 | -- | The indices of the first two duplicated elements in a list. 39 | indexDup :: (Ord a) => [a] -> Maybe (Int, Int) 40 | indexDup l = msum . zipWith (fmap . (,)) [0..] . zipWith Map.lookup l . 41 | scanl (flip ($)) Map.empty $ zipWith Map.insert l [0..] 42 | 43 | day6a :: String -> Maybe Int 44 | day6a = fmap fst . indexDup . iterate redistribute . parse @UArray @Int 45 | 46 | day6b :: String -> Maybe Int 47 | day6b = fmap (uncurry (-)) . indexDup . iterate redistribute . parse @UArray @Int 48 | -------------------------------------------------------------------------------- /src/Day7.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day7 3 | Description: 4 | -} 5 | {-# LANGUAGE FlexibleContexts, PatternGuards #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day7 (day7a, day7b) where 8 | 9 | import Control.Arrow ((***)) 10 | import Control.Monad ((>=>), guard, join, zipWithM_) 11 | import Control.Monad.Writer (MonadWriter, execWriterT, tell) 12 | import Data.Char (isAlphaNum) 13 | import Data.Functor (($>)) 14 | import Data.List (find, group, maximumBy) 15 | import qualified Data.Map.Strict as Map (Map, fromList, lookup) 16 | import Data.Maybe (listToMaybe) 17 | import Data.Monoid (First(..)) 18 | import Data.Ord (comparing) 19 | import qualified Data.Set as Set (difference, fromList, lookupMin, unions) 20 | import Text.ParserCombinators.ReadP (char, eof, many1, option, readP_to_S, readS_to_P, satisfy, sepBy1, skipSpaces, string) 21 | 22 | -- | Parses a string as a table of node name to node weight and children. 23 | parseTree :: String -> Maybe [(String, (Int, [String]))] 24 | parseTree = mapM (fmap fst . find (null . snd) . readsLine) . lines where 25 | readsLine = readP_to_S $ do 26 | name <- many1 $ satisfy isAlphaNum 27 | skipSpaces; char '(' 28 | weight <- readS_to_P reads 29 | char ')'; skipSpaces 30 | children <- option [] $ do 31 | string "->"; skipSpaces 32 | sepBy1 (many1 $ satisfy isAlphaNum) (char ',' >> skipSpaces) 33 | eof $> (name, (weight, children)) 34 | 35 | -- | Finds a node with no parents. 36 | findRoot :: (Ord a) => [(a, (b, [a]))] -> Maybe a 37 | findRoot = Set.lookupMin . uncurry Set.difference . 38 | (Set.fromList *** Set.unions . map (Set.fromList . snd)) . unzip 39 | 40 | -- | Returns the most common element. 41 | mode :: (Eq a) => [a] -> Maybe a 42 | mode [] = Nothing 43 | mode x = listToMaybe . maximumBy (comparing length) $ group x 44 | 45 | -- | Returns the total weight of the tree rooted at the given node. 46 | -- 47 | -- As a side effect, also 'tell' the corrected weight for nodes whose tree 48 | -- weight does not equal the majority of their siblings'. 49 | weighTree :: (Monad m, MonadWriter (First b) m, Ord a, Eq b, Num b) => 50 | Map.Map a (b, [a]) -> a -> m b 51 | weighTree tree root = do 52 | let Just (weight, children) = Map.lookup root tree 53 | childWeights <- mapM (weighTree tree) children 54 | let Just targetWeight = mode childWeights 55 | check child actualWeight 56 | | actualWeight == targetWeight = pure () 57 | | Just (childWeight, _) <- Map.lookup child tree 58 | = tell . First . Just $ childWeight + targetWeight - actualWeight 59 | zipWithM_ check children childWeights 60 | pure $ weight + sum childWeights 61 | 62 | day7a :: String -> Maybe String 63 | day7a = parseTree >=> findRoot 64 | 65 | day7b :: String -> Maybe Int 66 | day7b input = do 67 | tree <- parseTree input 68 | root <- findRoot tree 69 | join $ getFirst <$> execWriterT (weighTree (Map.fromList tree) root) 70 | -------------------------------------------------------------------------------- /src/Day8.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day8 3 | Description: 4 | -} 5 | {-# OPTIONS_HADDOCK ignore-exports #-} 6 | module Day8 (day8a, day8b) where 7 | 8 | import Data.List (foldl', scanl') 9 | import qualified Data.Map.Strict as Map (elems, empty, insert, lookup) 10 | import Data.Map.Strict (Map) 11 | import Data.Maybe (fromMaybe) 12 | 13 | -- | Performs one operation on a register state, if the condition applies. 14 | exec :: (Num a, Ord a, Read a) => Map String a -> String -> Map String a 15 | exec regs line 16 | | q cond (fromMaybe 0 $ Map.lookup when regs) (read cmp) 17 | = Map.insert reg (p op (fromMaybe 0 $ Map.lookup reg regs) (read val)) regs 18 | | otherwise = regs where 19 | [reg, op, val, "if", when, cond, cmp] = words line 20 | p "inc" = (+); p "dec" = (-); q "<" = (<); q "<=" = (<=) 21 | q "==" = (==); q ">=" = (>=); q ">" = (>); q "!=" = (/=) 22 | 23 | day8a :: String -> Int 24 | day8a = maximum . Map.elems . foldl' exec Map.empty . lines 25 | 26 | day8b :: String -> Int 27 | day8b = maximum . concatMap Map.elems . scanl' exec Map.empty . lines 28 | -------------------------------------------------------------------------------- /src/Day9.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module: Day9 3 | Description: 4 | -} 5 | {-# LANGUAGE FlexibleContexts #-} 6 | {-# OPTIONS_HADDOCK ignore-exports #-} 7 | module Day9 (day9a, day9b) where 8 | 9 | import Data.List (mapAccumL) 10 | 11 | day9a :: String -> Int 12 | day9a = sum . snd . mapAccumL accum (1, Nothing) where 13 | accum (k, Nothing) '{' = ((k + 1, Nothing), k) 14 | accum (k, Nothing) '}' = ((k - 1, Nothing), 0) 15 | accum (k, Nothing) '<' = ((k, Just False), 0) 16 | accum (k, Just False) '>' = ((k, Nothing), 0) 17 | accum (k, Just False) '!' = ((k, Just True), 0) 18 | accum (k, Just True) _ = ((k, Just False), 0) 19 | accum acc _ = (acc, 0) 20 | 21 | day9b :: String -> Int 22 | day9b = sum . snd . mapAccumL accum Nothing where 23 | accum Nothing '<' = (Just True, 0) 24 | accum Nothing _ = (Nothing, 0) 25 | accum (Just True) '>' = (Nothing, 0) 26 | accum (Just True) '!' = (Just False, 0) 27 | accum (Just True) _ = (Just True, 1) 28 | accum (Just False) _ = (Just True, 0) 29 | -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by 'stack init' 2 | # 3 | # Some commonly used options have been documented as comments in this file. 4 | # For advanced use and comprehensive documentation of the format, please see: 5 | # https://docs.haskellstack.org/en/stable/yaml_configuration/ 6 | 7 | # Resolver to choose a 'specific' stackage snapshot or a compiler version. 8 | # A snapshot resolver dictates the compiler version and the set of packages 9 | # to be used for project dependencies. For example: 10 | # 11 | # resolver: lts-3.5 12 | # resolver: nightly-2015-09-21 13 | # resolver: ghc-7.10.2 14 | # resolver: ghcjs-0.1.0_ghc-7.10.2 15 | # resolver: 16 | # name: custom-snapshot 17 | # location: "./custom-snapshot.yaml" 18 | resolver: nightly-2017-11-25 19 | 20 | # User packages to be built. 21 | # Various formats can be used as shown in the example below. 22 | # 23 | # packages: 24 | # - some-directory 25 | # - https://example.com/foo/bar/baz-0.0.2.tar.gz 26 | # - location: 27 | # git: https://github.com/commercialhaskell/stack.git 28 | # commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a 29 | # - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a 30 | # extra-dep: true 31 | # subdirs: 32 | # - auto-update 33 | # - wai 34 | # 35 | # A package marked 'extra-dep: true' will only be built if demanded by a 36 | # non-dependency (i.e. a user package), and its test suites and benchmarks 37 | # will not be run. This is useful for tweaking upstream packages. 38 | packages: 39 | - . 40 | - packages/growarray 41 | - packages/lcg 42 | - packages/morton 43 | # Dependency packages to be pulled from upstream that are not in the resolver 44 | # (e.g., acme-missiles-0.3) 45 | # extra-deps: [] 46 | 47 | # Override default flag values for local packages and extra-deps 48 | # flags: {} 49 | 50 | # Extra package databases containing global packages 51 | # extra-package-dbs: [] 52 | 53 | # Control whether we use the GHC we find on the path 54 | # system-ghc: true 55 | # 56 | # Require a specific version of stack, using version ranges 57 | # require-stack-version: -any # Default 58 | # require-stack-version: ">=1.6" 59 | # 60 | # Override the architecture used by stack, especially useful on Windows 61 | # arch: i386 62 | # arch: x86_64 63 | # 64 | # Extra directories used by stack for building 65 | # extra-include-dirs: [/path/to/dir] 66 | # extra-lib-dirs: [/path/to/dir] 67 | # 68 | # Allow a newer minor version of GHC than the snapshot specifies 69 | # compiler-check: newer-minor 70 | 71 | ghc-options: 72 | lcg: -fllvm -------------------------------------------------------------------------------- /test/Day10Spec.hs: -------------------------------------------------------------------------------- 1 | module Day10Spec (spec) where 2 | 3 | import Day10 (day10a, day10b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day10a 5 "3,4,1,5" `shouldBe` 12 11 | describe "part 2" $ 12 | it "examples" $ do 13 | day10b "" `shouldBe` "a2582a3a0e66e6e86e3812dcb672a272" 14 | day10b "AoC 2017" `shouldBe` "33efeb34ea91902bb2f59c9920caa6cd" 15 | day10b "1,2,3" `shouldBe` "3efbe78a8d82f29979031a4aa0b16a9d" 16 | day10b "1,2,4" `shouldBe` "63960835bcdc130f0b66d7ff4f6a5a8e" 17 | -------------------------------------------------------------------------------- /test/Day11Spec.hs: -------------------------------------------------------------------------------- 1 | module Day11Spec (spec) where 2 | 3 | import Day11 (day11a, day11b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ do 10 | day11a "ne,ne,ne" `shouldBe` 3 11 | day11a "ne,ne,sw,sw" `shouldBe` 0 12 | day11a "ne,ne,s,s" `shouldBe` 2 13 | day11a "se,sw,se,sw,sw" `shouldBe` 3 14 | describe "part 2" $ 15 | it "examples" $ 16 | day11b "ne,ne,sw,sw" `shouldBe` 2 17 | -------------------------------------------------------------------------------- /test/Day12Spec.hs: -------------------------------------------------------------------------------- 1 | module Day12Spec (spec) where 2 | 3 | import Day12 (day12a, day12b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "0 <-> 2" 9 | , "1 <-> 1" 10 | , "2 <-> 0, 3, 4" 11 | , "3 <-> 2, 4" 12 | , "4 <-> 2, 3, 6" 13 | , "5 <-> 6" 14 | , "6 <-> 4, 5" 15 | ] 16 | 17 | spec :: Spec 18 | spec = do 19 | describe "part 1" $ 20 | it "examples" $ 21 | day12a example `shouldBe` 6 22 | describe "part 2" $ 23 | it "examples" $ 24 | day12b example `shouldBe` 2 25 | -------------------------------------------------------------------------------- /test/Day13Spec.hs: -------------------------------------------------------------------------------- 1 | module Day13Spec (spec) where 2 | 3 | import Day13 (day13a, day13b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "0: 3" 9 | , "1: 2" 10 | , "4: 4" 11 | , "6: 4" 12 | ] 13 | 14 | spec :: Spec 15 | spec = do 16 | describe "part 1" $ 17 | it "examples" $ 18 | day13a example `shouldBe` 24 19 | describe "part 2" $ 20 | it "examples" $ 21 | day13b example `shouldBe` 10 22 | -------------------------------------------------------------------------------- /test/Day14Spec.hs: -------------------------------------------------------------------------------- 1 | module Day14Spec (spec) where 2 | 3 | import Day14 (day14a, day14b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day14a "" `shouldBe` 7964 11 | describe "part 2" $ 12 | it "examples" $ 13 | day14b "" `shouldBe` 1275 14 | -------------------------------------------------------------------------------- /test/Day15Spec.hs: -------------------------------------------------------------------------------- 1 | module Day15Spec (spec) where 2 | 3 | import Day15 (day15a, day15b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = "Generator A starts with 65\nGenerator B starts with 8921\n" 8 | 9 | spec :: Spec 10 | spec = do 11 | describe "part 1" $ 12 | it "examples" $ 13 | day15a example `shouldBe` 588 14 | describe "part 2" $ 15 | it "examples" $ 16 | day15b example `shouldBe` 309 17 | -------------------------------------------------------------------------------- /test/Day16Spec.hs: -------------------------------------------------------------------------------- 1 | module Day16Spec (spec) where 2 | 3 | import Day16 (day16a, day16b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = "s1,x3/4,pe/b\n" 8 | 9 | spec :: Spec 10 | spec = do 11 | describe "part 1" $ 12 | it "examples" $ 13 | day16a 5 example `shouldBe` "baedc" 14 | describe "part 2" $ 15 | it "examples" $ 16 | day16b 5 2 example `shouldBe` "ceadb" 17 | -------------------------------------------------------------------------------- /test/Day17Spec.hs: -------------------------------------------------------------------------------- 1 | module Day17Spec (spec) where 2 | 3 | import Day17 (day17a, day17b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day17a 3 `shouldBe` 638 11 | describe "part 2" $ 12 | it "examples" $ 13 | day17b 3 `shouldBe` 1222153 14 | -------------------------------------------------------------------------------- /test/Day18Spec.hs: -------------------------------------------------------------------------------- 1 | module Day18Spec (spec) where 2 | 3 | import Day18 (day18a, day18b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "set a 1" 9 | , "add a 2" 10 | , "mul a a" 11 | , "mod a 5" 12 | , "snd a" 13 | , "set a 0" 14 | , "rcv a" 15 | , "jgz a -1" 16 | , "set a 1" 17 | , "jgz a -2" 18 | ] 19 | 20 | spec :: Spec 21 | spec = do 22 | describe "part 1" $ 23 | it "examples" $ 24 | day18a example `shouldBe` 4 25 | describe "part 2" $ 26 | it "examples" $ 27 | day18b example `shouldBe` 1 28 | -------------------------------------------------------------------------------- /test/Day19Spec.hs: -------------------------------------------------------------------------------- 1 | module Day19Spec (spec) where 2 | 3 | import Day19 (day19a, day19b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ " | " 9 | , " | +--+ " 10 | , " A | C " 11 | , " F---|----E|--+ " 12 | , " | | | D " 13 | , " +B-+ +--+ " 14 | ] 15 | 16 | spec :: Spec 17 | spec = do 18 | describe "part 1" $ 19 | it "examples" $ 20 | day19a example `shouldBe` "ABCDEF" 21 | describe "part 2" $ 22 | it "examples" $ 23 | day19b example `shouldBe` 38 24 | -------------------------------------------------------------------------------- /test/Day1Spec.hs: -------------------------------------------------------------------------------- 1 | module Day1Spec (spec) where 2 | 3 | import Day1 (day1a, day1b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ do 10 | day1a "1122" `shouldBe` 3 11 | day1a "1111" `shouldBe` 4 12 | day1a "1234" `shouldBe` 0 13 | day1a "91212129" `shouldBe` 9 14 | describe "part 2" $ 15 | it "examples" $ do 16 | day1b "1212" `shouldBe` 6 17 | day1b "1221" `shouldBe` 0 18 | day1b "123425" `shouldBe` 4 19 | day1b "123123" `shouldBe` 12 20 | day1b "12131415" `shouldBe` 4 21 | -------------------------------------------------------------------------------- /test/Day20Spec.hs: -------------------------------------------------------------------------------- 1 | module Day20Spec (spec) where 2 | 3 | import Day20 (day20a, day20b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day20a (unlines 11 | [ "p=<3,0,0>, v=<2,0,0>, a=<-1,0,0>" 12 | , "p=<4,0,0>, v=<0,0,0>, a=<-2,0,0>" 13 | ]) `shouldBe` 0 14 | describe "part 2" $ 15 | it "examples" $ 16 | day20b (unlines 17 | [ "p=<-6,0,0>, v=<3,0,0>, a=<0,0,0>" 18 | , "p=<-4,0,0>, v=<2,0,0>, a=<0,0,0>" 19 | , "p=<-2,0,0>, v=<1,0,0>, a=<0,0,0>" 20 | , "p=<3,0,0>, v=<-1,0,0>, a=<0,0,0>" 21 | ]) `shouldBe` [3] 22 | -------------------------------------------------------------------------------- /test/Day21Spec.hs: -------------------------------------------------------------------------------- 1 | module Day21Spec (spec) where 2 | 3 | import Day21 (day21) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = it "examples" $ 8 | day21 2 (unlines 9 | [ "../.# => ##./#../..." 10 | , ".#./..#/### => #..#/..../..../#..#" 11 | ]) `shouldBe` 12 12 | -------------------------------------------------------------------------------- /test/Day22Spec.hs: -------------------------------------------------------------------------------- 1 | module Day22Spec (spec) where 2 | 3 | import Day22 (day22a, day22b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "..#" 9 | , "#.." 10 | , "..." 11 | ] 12 | 13 | spec :: Spec 14 | spec = do 15 | describe "part 1" $ 16 | it "examples" $ 17 | day22a example `shouldBe` 5587 18 | describe "part 2" $ 19 | it "examples" $ 20 | day22b example `shouldBe` 2511944 21 | -------------------------------------------------------------------------------- /test/Day24Spec.hs: -------------------------------------------------------------------------------- 1 | module Day24Spec (spec) where 2 | 3 | import Day24 (day24a, day24b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "0/2" 9 | , "2/2" 10 | , "2/3" 11 | , "3/4" 12 | , "3/5" 13 | , "0/1" 14 | , "10/1" 15 | , "9/10" 16 | ] 17 | 18 | spec :: Spec 19 | spec = do 20 | describe "part 1" $ 21 | it "examples" $ 22 | day24a example `shouldBe` 31 23 | describe "part 2" $ 24 | it "examples" $ 25 | day24b example `shouldBe` 19 26 | -------------------------------------------------------------------------------- /test/Day25Spec.hs: -------------------------------------------------------------------------------- 1 | module Day25Spec (spec) where 2 | 3 | import Day25 (day25) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "Begin in state A." 9 | , "Perform a diagnostic checksum after 6 steps." 10 | , "" 11 | , "In state A:" 12 | , " If the current value is 0:" 13 | , " - Write the value 1." 14 | , " - Move one slot to the right." 15 | , " - Continue with state B." 16 | , " If the current value is 1:" 17 | , " - Write the value 0." 18 | , " - Move one slot to the left." 19 | , " - Continue with state B." 20 | , "" 21 | , "In state B:" 22 | , " If the current value is 0:" 23 | , " - Write the value 1." 24 | , " - Move one slot to the left." 25 | , " - Continue with state A." 26 | , " If the current value is 1:" 27 | , " - Write the value 1." 28 | , " - Move one slot to the right." 29 | , " - Continue with state A." 30 | ] 31 | 32 | spec :: Spec 33 | spec = describe "part 1" $ it "examples" $ day25 example `shouldBe` 3 34 | -------------------------------------------------------------------------------- /test/Day2Spec.hs: -------------------------------------------------------------------------------- 1 | module Day2Spec (spec) where 2 | 3 | import Day2 (day2a, day2b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day2a (unlines 11 | [ "5 1 9 5" 12 | , "7 5 3" 13 | , "2 4 6 8" 14 | ]) `shouldBe` 18 15 | describe "part 2" $ 16 | it "examples" $ 17 | day2b (unlines 18 | [ "5 9 2 8" 19 | , "9 4 7 3" 20 | , "3 8 6 5" 21 | ]) `shouldBe` 9 22 | -------------------------------------------------------------------------------- /test/Day3Spec.hs: -------------------------------------------------------------------------------- 1 | module Day3Spec (spec) where 2 | 3 | import Day3 (day3a, day3b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ do 10 | day3a 12 `shouldBe` 3 11 | day3a 23 `shouldBe` 2 12 | day3a 1024 `shouldBe` 31 13 | describe "part 2" $ 14 | it "examples" $ do 15 | day3b 351 `shouldBe` 362 16 | day3b 362 `shouldBe` 747 17 | day3b 747 `shouldBe` 806 18 | -------------------------------------------------------------------------------- /test/Day4Spec.hs: -------------------------------------------------------------------------------- 1 | module Day4Spec (spec) where 2 | 3 | import Day4 (day4a, day4b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day4a (unlines 11 | [ "aa bb cc dd ee" 12 | , "aa bb cc dd aa" 13 | , "aa bb cc dd aaa" 14 | ]) `shouldBe` 2 15 | describe "part 2" $ 16 | it "examples" $ 17 | day4b (unlines 18 | [ "abcde fghij" 19 | , "abcde xyz ecdab" 20 | , "a ab abc abd abf abj" 21 | , "iiii oiii ooii oooi oooo" 22 | , "oiii ioii iioi iiio" 23 | ]) `shouldBe` 3 24 | -------------------------------------------------------------------------------- /test/Day5Spec.hs: -------------------------------------------------------------------------------- 1 | module Day5Spec (spec) where 2 | 3 | import Day5 (day5a, day5b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day5a (unlines $ map show [0, 3, 0, 1, -3]) `shouldBe` 5 11 | describe "part 2" $ 12 | it "examples" $ 13 | day5b (unlines $ map show [0, 3, 0, 1, -3]) `shouldBe` 10 14 | -------------------------------------------------------------------------------- /test/Day6Spec.hs: -------------------------------------------------------------------------------- 1 | module Day6Spec (spec) where 2 | 3 | import Day6 (day6a, day6b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ 10 | day6a "0 2 7 0" `shouldBe` Just 5 11 | describe "part 2" $ 12 | it "examples" $ 13 | day6b "0 2 7 0" `shouldBe` Just 4 14 | -------------------------------------------------------------------------------- /test/Day7Spec.hs: -------------------------------------------------------------------------------- 1 | module Day7Spec (spec) where 2 | 3 | import Day7 (day7a, day7b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "pbga (66)" 9 | , "xhth (57)" 10 | , "ebii (61)" 11 | , "havc (66)" 12 | , "ktlj (57)" 13 | , "fwft (72) -> ktlj, cntj, xhth" 14 | , "qoyq (66)" 15 | , "padx (45) -> pbga, havc, qoyq" 16 | , "tknk (41) -> ugml, padx, fwft" 17 | , "jptl (61)" 18 | , "ugml (68) -> gyxo, ebii, jptl" 19 | , "gyxo (61)" 20 | , "cntj (57)" 21 | ] 22 | 23 | spec :: Spec 24 | spec = do 25 | describe "part 1" $ 26 | it "examples" $ 27 | day7a example `shouldBe` Just "tknk" 28 | describe "part 2" $ 29 | it "examples" $ 30 | day7b example `shouldBe` Just 60 31 | -------------------------------------------------------------------------------- /test/Day8Spec.hs: -------------------------------------------------------------------------------- 1 | module Day8Spec (spec) where 2 | 3 | import Day8 (day8a, day8b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | example :: String 7 | example = unlines 8 | [ "b inc 5 if a > 1" 9 | , "a inc 1 if b < 5" 10 | , "c dec -10 if a >= 1" 11 | , "c inc -20 if c == 10" 12 | ] 13 | 14 | spec :: Spec 15 | spec = do 16 | describe "part 1" $ 17 | it "examples" $ 18 | day8a example `shouldBe` 1 19 | describe "part 2" $ 20 | it "examples" $ 21 | day8b example `shouldBe` 10 22 | -------------------------------------------------------------------------------- /test/Day9Spec.hs: -------------------------------------------------------------------------------- 1 | module Day9Spec (spec) where 2 | 3 | import Day9 (day9a, day9b) 4 | import Test.Hspec (Spec, describe, it, shouldBe) 5 | 6 | spec :: Spec 7 | spec = do 8 | describe "part 1" $ 9 | it "examples" $ do 10 | day9a "{}" `shouldBe` 1 11 | day9a "{{{}}}" `shouldBe` 6 12 | day9a "{{},{}}" `shouldBe` 5 13 | day9a "{{{},{},{{}}}}" `shouldBe` 16 14 | day9a "{,,,}" `shouldBe` 1 15 | day9a "{{},{},{},{}}" `shouldBe` 9 16 | day9a "{{},{},{},{}}" `shouldBe` 9 17 | day9a "{{},{},{},{}}" `shouldBe` 3 18 | describe "part 2" $ 19 | it "examples" $ do 20 | day9b "<>" `shouldBe` 0 21 | day9b "" `shouldBe` 17 22 | day9b "<<<<>" `shouldBe` 3 23 | day9b "<{!>}>" `shouldBe` 2 24 | day9b "" `shouldBe` 0 25 | day9b ">" `shouldBe` 0 26 | day9b "<{o\"i!a,<{i" `shouldBe` 10 27 | -------------------------------------------------------------------------------- /test/Main.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -F -pgmF hspec-discover #-} 2 | --------------------------------------------------------------------------------