diff --git a/2015/Day21.hs b/2015/Day21.hs index f2136b0..01f8482 100644 --- a/2015/Day21.hs +++ b/2015/Day21.hs @@ -2,16 +2,22 @@ module Main where import Utilities +-- Input processing + +type Input = PlayerState + data PlayerState = Player { hit_points :: Int, damage_score :: Int, armor_score :: Int } -parse :: String -> PlayerState -parse s = Player h d a - where - [h, d, a] = readNumbers s +parse :: String -> Input +parse s = case readNumbers s of + [h, d, a] -> Player h d a + _ -> error "bad input" + +-- Part One data Item = Item { name :: String, diff --git a/2018/Day22.hs b/2018/Day22.hs index f08f880..b1edd20 100644 --- a/2018/Day22.hs +++ b/2018/Day22.hs @@ -10,11 +10,12 @@ import Data.Array type Input = (Int, Position) parse :: String -> Input -parse s = (runParser depth ld, runParser target lt) +parse s = case lines s of + [ld, lt] -> (runParser depth ld, runParser target lt) + _ -> error "bad input" where depth = string "depth: " *> nat target = (,) <$ string "target: " <*> nat <* char ',' <*> nat - [ld, lt] = lines s type Position = (Int, Int) diff --git a/2018/Day24.hs b/2018/Day24.hs index f40a314..d745458 100644 --- a/2018/Day24.hs +++ b/2018/Day24.hs @@ -46,16 +46,16 @@ data AttackType = Fire | Cold | Slashing | Bludgeoning | Radiation deriving (Show, Eq, Enum, Bounded) parse :: String -> Input -parse s = - State { - immuneSystem = - makeArmy (map (runParser unit_group) (tail immune_system_lines)), - infection = - makeArmy (map (runParser unit_group) (tail infection_lines)) - } +parse s = case paragraphs s of + [p1, p2] -> + State { + immuneSystem = + makeArmy (map (runParser unit_group) (tail (lines p1))), + infection = + makeArmy (map (runParser unit_group) (tail (lines p2))) + } + _ -> error "bad input" where - ls = lines s - (immune_system_lines, "":infection_lines) = span (not . null) ls unit_group = Group <$> nat <* string " units each with " <*> unit_type unit_type = diff --git a/2019/Day03.hs b/2019/Day03.hs index 3e5dd02..f41728c 100644 --- a/2019/Day03.hs +++ b/2019/Day03.hs @@ -19,9 +19,10 @@ data Direction = R | U | L | D deriving (Bounded, Enum, Show) parse :: String -> Input -parse s = (w1, w2) +parse s = case lines s of + [l1, l2] -> (runParser wire l1, runParser wire l2) + _ -> error "bad input" where - [w1, w2] = map (runParser wire) (lines s) wire = sepBy1 segment (char ',') segment = Segment <$> enumValue <*> nat diff --git a/2020/Day16.hs b/2020/Day16.hs index b218984..2d13446 100644 --- a/2020/Day16.hs +++ b/2020/Day16.hs @@ -27,17 +27,19 @@ data Range = Range Int Int type Ticket = [Int] parse :: String -> Input -parse s = Input { - field_rules = map (runParser rule) p1, - your_ticket = runParser ticket (p2!!1), - others = map (runParser ticket) (tail p3) - } +parse s = case map lines (paragraphs s) of + [p1, p2, p3] -> + Input { + field_rules = map (runParser rule) p1, + your_ticket = runParser ticket (p2!!1), + others = map (runParser ticket) (tail p3) + } + _ -> error "bad input" where rule = (,) <$> some (satisfy (/= ':')) <* string ": " <*> ranges ranges = (,) <$> range <* string " or " <*> range range = Range <$> nat <* char '-' <*> nat ticket = sepBy1 nat (char ',') - [p1, p2, p3] = map lines (paragraphs s) -- Part One diff --git a/2020/Day20.hs b/2020/Day20.hs index 0d1bad5..cd558b7 100644 --- a/2020/Day20.hs +++ b/2020/Day20.hs @@ -21,9 +21,10 @@ parse :: String -> Input parse = Map.fromList . map parseCamera . paragraphs parseCamera :: String -> (Int, Tile) -parseCamera s = (runParser tileno header, parseTile rest) +parseCamera s = case lines s of + header:rest -> (runParser tileno header, parseTile rest) + _ -> error "bad input" where - header:rest = lines s tileno = string "Tile " *> nat <* char ':' parseTile :: [String] -> Tile diff --git a/2020/Day22.hs b/2020/Day22.hs index 5eb78e2..7a69942 100644 --- a/2020/Day22.hs +++ b/2020/Day22.hs @@ -14,10 +14,11 @@ type Decks = (Deck, Deck) type Deck = Seq Int parse :: String -> Input -parse s = (numbers p1, numbers p2) +parse s = case paragraphs s of + [p1, p2] -> (numbers p1, numbers p2) + _ -> error "bad input" where numbers = Seq.fromList . map read . tail . lines - [p1, p2] = paragraphs s -- Part One diff --git a/2020/Day25.hs b/2020/Day25.hs index 536c683..e87b211 100644 --- a/2020/Day25.hs +++ b/2020/Day25.hs @@ -8,9 +8,9 @@ import Number type Input = (Int, Int) parse :: String -> Input -parse s = (x, y) - where - x:y:_ = map read (lines s) +parse s = case map read (lines s) of + [x, y] -> (x, y) + _ -> error "bad input" -- Part One @@ -28,9 +28,9 @@ base = 7 -- -- find the value c ^ log_d = base ^ (log_d*log_c) = d ^ log_c. solve1 :: Input -> Int -solve1 (d, c) = modularPower modulus c log_d - where - Just log_d = modularLogarithm modulus base d +solve1 (d, c) = case modularLogarithm modulus base d of + Just log_d -> modularPower modulus c log_d + Nothing -> error "no solution" testInput :: String testInput = "\ diff --git a/2021/Day13.hs b/2021/Day13.hs index 8f36a5f..c42eb9a 100644 --- a/2021/Day13.hs +++ b/2021/Day13.hs @@ -14,14 +14,15 @@ data Fold = FoldX Int | FoldY Int type Input = ([Position], [Fold]) parse :: String -> Input -parse s = - (map (runParser pos) (lines sp), map (runParser fold_instr) (lines sf)) +parse s = case paragraphs s of + [sp, sf] -> + (map (runParser pos) (lines sp), map (runParser fold_instr) (lines sf)) + _ -> error "bad input" where pos = Position <$> nat <* char ',' <*> nat fold_instr = FoldX <$ string "fold along x=" <*> nat <|> FoldY <$ string "fold along y=" <*> nat - [sp, sf] = paragraphs s -- Part One diff --git a/2021/Day20.hs b/2021/Day20.hs index 5ed6c4f..23fa8d1 100644 --- a/2021/Day20.hs +++ b/2021/Day20.hs @@ -13,12 +13,13 @@ type Pixels = Set Position type Input = (Algorithm, Pixels) parse :: String -> Input -parse s = (algo, pixels) - where - [p1, p2] = paragraphs s - algo = Set.fromList - [n | (n, c) <- zip [0..] (filter (/= '\n') p1), c == '#'] - pixels = Set.fromList [p | (p, c) <- readGrid p2, c == '#'] +parse s = case paragraphs s of + [p1, p2] -> (algo, pixels) + where + algo = Set.fromList + [n | (n, c) <- zip [0..] (filter (/= '\n') p1), c == '#'] + pixels = Set.fromList [p | (p, c) <- readGrid p2, c == '#'] + _ -> error "bad input" -- Part One diff --git a/2021/Day21.hs b/2021/Day21.hs index aa2a67b..3f7f689 100644 --- a/2021/Day21.hs +++ b/2021/Day21.hs @@ -11,9 +11,10 @@ import qualified Data.Map as Map type Input = (Int, Int) parse :: String -> Input -parse s = (runParser startPos l1, runParser startPos l2) +parse s = case lines s of + [l1, l2] -> (runParser startPos l1, runParser startPos l2) + _ -> error "bad input" where - [l1, l2] = lines s startPos = string "Player " *> digit *> string " starting position: " *> nat -- Part One diff --git a/2022/Day22.hs b/2022/Day22.hs index 838e68c..a714278 100644 --- a/2022/Day22.hs +++ b/2022/Day22.hs @@ -26,15 +26,17 @@ data FieldMap = FieldMap { deriving (Show) parse :: String -> Input -parse s = (field_map, runParser path path_line) +parse s = case paragraphs s of + [map_text, path_text] -> (field_map, runParser path path_line) + where + field_map = FieldMap { + open = Set.fromList [p | (p, c) <- pcs, c == '.'], + walls = Set.fromList [p | (p, c) <- pcs, c == '#'] + } + pcs = readGrid map_text + path_line = head (lines path_text) + _ -> error "bad input" where - field_map = FieldMap { - open = Set.fromList [p | (p, c) <- pcs, c == '.'], - walls = Set.fromList [p | (p, c) <- pcs, c == '#'] - } - pcs = readGrid map_text - [map_text, path_text] = paragraphs s - path_line = head (lines path_text) path = (,) <$> nat <*> many ((,) <$> enumValue <*> nat) -- Part One