my answers in Haskell (see also Kotlin branch and Python gist)
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]