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: nopieto
~/.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
import Day1 (day1a, day1b)
import Day2 (day2a, day2b)
import Day3 (day3a, day3b)
import Day4 (day4a, day4b)
import Day5 (day5a, day5b)
import Day6 (day6a, day6b)
import Day7 (day7a, day7b)
import Day8 (day8a, day8b)
import Day9 (day9a, day9b)
import Day10 (day10a, day10b)
import Day11 (day11a, day11b)
import Day12 (day12a, day12b)
import Day13 (day13a, day13b)
import Day14 (day14a, day14b)
import Day15 (day15a, day15b)
import Day16 (day16a, day16b)
import Day17 (day17a, day17b)
import Day18 (day18a, day18b)
import Day19 (day19a, day19b)
import Day20 (day20a, day20b)
import Day21 (day21a, day21b)
import Day22 (day22a, day22b)
import Day23 (day23a, day23b)
import Day24 (day24a, day24b)
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]