Skip to content

ephemient/aoc2018

Repository files navigation

my answers in Haskell (see also Kotlin branch and Python gist)

Build Status

This project builds with The Haskell Tool Stack.

Setup:

curl -sSL https://get.haskellstack.org/ | sh -s -
stack setup

Run the HSpec test suite:

stack test aoc2018:test:aoc2018-test

Run criterion benchmarks:

stack bench aoc2018:bench:aoc2018-bench

Print solutions for the inputs provided in local data files:

stack build aoc2018:exe:aoc2018-exe --exec aoc2018-exe

Generate Haddock API documentation (rendered at ephemient.github.io/aoc2018):

stack haddock aoc2018:lib

Run hlint source code suggestions:

stack build hlint --exec 'hlint src test bench'

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 (day10)
import Day11 (day11a, day11b)
import Day12 (day12)
import Day13 (day13a, day13b)
import Day14 (day14a, day14b)
import Day15 (day15a, day15b)
import Day16 (day16a, day16b)
import Day17 (day17a, day17b)
import Day18 (day18)
import Day19 (day19)
import Day20 (day20a, day20b)
import Day21 (day21a, day21b)
import Day22 (day22a, day22b)
import Day23 (day23a, day23b)
import Day24 (day24a, day24b)
import Day25 (day25a)

import Control.Monad (when)
import Data.Maybe (mapMaybe)
import Paths_aoc2018 (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 putStrLn [show . day1a, maybeBottom show . day1b]
    run 2 getDayInput putStrLn [show . day2a, maybeBottom id . day2b]
    run 3 getDayInput (putStrLn . maybeBottom show) [day3a, day3b]
    run 4 getDayInput (putStrLn . maybeBottom show) [day4a, day4b]
    run 5 getDayInput print [day5a, day5b]
    run 6 getDayInput (putStrLn . maybeBottom show) [day6a, day6b 10000]
    run 7 getDayInput putStrLn [day7a, show . day7b 60 5]
    run 8 getDayInput (putStrLn . maybeBottom show) [day8a, day8b]
    run 9 getDayInput (putStrLn . maybeBottom show) [day9a, day9b]
    run 10 getDayInput (putStrLn . maybeBottom (\(i, s) -> s ++ show i)) [day10]
    run 11 getDayInput putStrLn [day11a, day11b]
    run 12 getDayInput (putStrLn . maybeBottom show) [day12 20, day12 50000000000]
    run 13 getDayInput putStrLn [day13a, day13b]
    run 14 getDayInput putStrLn [day14a, show . day14b]
    run 15 getDayInput (print . uncurry (*)) [day15a, snd . day15b]
    run 16 getDayInput (putStrLn . maybeBottom show) [day16a, day16b]
    run 17 getDayInput (putStrLn . maybeBottom show) [day17a, day17b]
    run 18 getDayInput print [day18 10, day18 1000000000]
    run 19 getDayInput (putStrLn . maybeBottom show) [day19 0, day19 1]
    run 20 getDayInput print [day20a, day20b]
    run 21 getDayInput (putStrLn . maybeBottom show) [day21a, day21b]
    run 22 getDayInput (putStrLn . maybeBottom show) [day22a, day22b]
    run 23 getDayInput (putStrLn . maybeBottom show) [day23a, day23b]
    run 24 getDayInput (putStrLn . maybeBottom show) [day24a, day24b]
    run 25 getDayInput print [day25a]