aoc2017
aoc2017 copied to clipboard
Advent of Code 2017 - my answers
Advent of Code 2017
my answers in Haskell
This project builds with The Haskell Tool Stack.
Setup:
curl -sSL https://get.haskellstack.org/ | sh -s -
stack setup
If you encounter linker errors with the commands below, try
stack setup --ghc-build=nopie
or addingghc-build: nopie
to
~/.stack/config.yaml
.
Run the HSpec test suite:
stack test aoc2017:test:aoc2017-test
Run criterion benchmarks:
stack bench aoc2017:bench:aoc2017-bench
Print solutions for the inputs provided in local data files:
stack build aoc2017:exe:aoc2017-exe
stack exec aoc2017-exe
Animate the Day 11 path (rendered at Gyfcat):
stack build aoc2017:exe:aoc2017-day11
stack exec aoc2017-day11
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
Animate the Day 14 grid (rendered at Gyfcat):
stack build aoc2017:exe:aoc2017-day14
stack exec aoc2017-day14
ffmpeg -framerate 60 -i 'day11-%04d.png' -c:v libx264 -pix_fmt yuv420p -profile:v baseline -level 3.0 -movflags +faststart -y day11.mp4
Generate Haddock API documentation (rendered at ephemient.github.io/aoc2017):
stack haddock aoc2017:lib
Day 1: Inverse Captcha
import Day1 (day1a, day1b)
Day 2: Corruption Checksum
import Day2 (day2a, day2b)
Day 3: Spiral Memory
import Day3 (day3a, day3b)
Day 4: High-Entropy Passphrases
import Day4 (day4a, day4b)
Day 5: A Maze of Twisty Trampolines, All Alike
import Day5 (day5a, day5b)
Day 6: Memory Reallocation
import Day6 (day6a, day6b)
Day 7: Recursive Circus
import Day7 (day7a, day7b)
Day 8: I Heard You Like Registers
import Day8 (day8a, day8b)
Day 9: Stream Processing
import Day9 (day9a, day9b)
Day 10: Knot Hash
import Day10 (day10a, day10b)
Day 11: Hex Ed
import Day11 (day11a, day11b)
Day 12: Digital Plumber
import Day12 (day12a, day12b)
Day 13: Packet Scanners
import Day13 (day13a, day13b)
Day 14: Disk Defragmentation
import Day14 (day14a, day14b)
Day 15: Dueling Generators
import Day15 (day15a, day15b)
Day 16: Permutation Promenade
import Day16 (day16a, day16b)
Day 17: Spinlock
import Day17 (day17a, day17b)
Day 18: Duet
import Day18 (day18a, day18b)
Day 19: A Series of Tubes
import Day19 (day19a, day19b)
Day 20: Particle Swarm
import Day20 (day20a, day20b)
Day 21: Fractal Art
import Day21 (day21a, day21b)
Day 22: Sporifica Virus
import Day22 (day22a, day22b)
Day 23: Coprocessor Conflagration
import Day23 (day23a, day23b)
Day 24: Electromagnetic Moat
import Day24 (day24a, day24b)
Day 25: The Halting Problem
import Day25 (day25)
import Control.Monad (when)
import Data.Maybe (mapMaybe)
import Paths_aoc2017 (getDataFileName)
import System.Environment (getArgs)
import Text.Read (readMaybe)
getDayInput :: Int -> IO String
getDayInput i = getDataFileName ("day" ++ show i ++ ".txt") >>= readFile
readDayInput :: (Read a) => Int -> IO a
readDayInput = fmap read . getDayInput
maybeBottom :: (a -> String) -> Maybe a -> String
maybeBottom = maybe "(⊥)"
showError :: (Show a) => (b -> String) -> Either a b -> String
showError = either (\err -> "(" ++ show err ++ ")")
run :: Int -> (Int -> IO a) -> (b -> IO ()) -> [a -> b] -> IO ()
run day readIO showIO funcs = do
days <- mapMaybe readMaybe <$> getArgs
when (null days || day `elem` days) $ do
putStrLn $ "Day " ++ show day
contents <- readIO day
mapM_ (showIO . ($ contents)) funcs
putStrLn ""
main :: IO ()
main = do
run 1 getDayInput print [day1a, day1b]
run 2 getDayInput print [day2a, day2b]
run 3 readDayInput print [day3a, day3b]
run 4 getDayInput print [day4a, day4b]
run 5 getDayInput print [day5a, day5b]
run 6 getDayInput (putStrLn . maybeBottom show) [day6a, day6b]
run 7 getDayInput (putStrLn . maybeBottom id) [day7a, fmap show . day7b]
run 8 getDayInput print [day8a, day8b]
run 9 getDayInput print [day9a, day9b]
run 10 getDayInput putStrLn [show . day10a 256, day10b]
run 11 getDayInput print [day11a, day11b]
run 12 getDayInput print [day12a, day12b]
run 13 getDayInput print [day13a, day13b]
run 14 getDayInput print [day14a, day14b]
run 15 getDayInput print [day15a, day15b]
run 16 getDayInput putStrLn [day16a 16, day16b 16 1000000000]
run 17 readDayInput print [day17a, day17b]
run 18 getDayInput print [fromIntegral . day18a, day18b]
run 19 getDayInput putStrLn [day19a, show . day19b]
run 20 getDayInput print [day20a, length . day20b]
run 21 getDayInput print [day21a, day21b]
run 22 getDayInput print [day22a, day22b]
run 23 getDayInput print [day23a, day23b]
run 24 getDayInput print [day24a, day24b]
run 25 getDayInput print [day25]