aboutsummaryrefslogtreecommitdiff
path: root/2020/16a.hs
blob: 0342e5d07fca827a3bb0c04a326bd59da47bf9f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
module Day16A where

import System.Environment (getArgs)
import Text.Printf
import Data.List.Split (splitOn)


-- name, (lo, hi)
type FieldDef = (String, [(Int, Int)])

-- (fields, your ticket, nearby tickets)
type Input = ([FieldDef], [Int], [[Int]])

parseTicketLine :: String -> [Int]
parseTicketLine = map read . splitOn ","

parseRange :: String -> (Int, Int)
parseRange x = (head ns, last ns)
        where ns = map read $ splitOn "-" x

parseFieldDef :: String -> FieldDef
parseFieldDef x = (n, ranges)
      where [n, rs] = splitOn ": " x
            ranges = map parseRange $ splitOn " or " rs

parseFields :: [String] -> [FieldDef]
parseFields = inner . head . splitOn [""]
                where inner = map parseFieldDef


findYourTicket :: [String] -> [Int]
findYourTicket ("your ticket:":xs) = parseTicketLine (head xs)
findYourTicket (_:xs) = findYourTicket xs
findYourTicket [] = error "Couldn't find your ticket"

findOtherTickets :: [String] -> [[Int]]
findOtherTickets ("nearby tickets:":xs) = map parseTicketLine xs
findOtherTickets (_:xs) = findOtherTickets xs
findOtherTickets [] = error "Couldn't find nearby tickets"


-- Parse the input
parseInput :: String -> Input
parseInput xs = (parseFields ls, findYourTicket ls, findOtherTickets ls)
      where ls = lines xs

-- Parse a file given the path
-- Returns list of instructions
parseFromFile :: String -> IO Input
parseFromFile s = do 
                   contents <- readFile s;
                   return $ parseInput contents;

fieldValid :: FieldDef -> Int -> Bool
fieldValid (_, rs) x = any (\(l,h) -> x >= l && x <= h) rs

invalidValues :: Input -> [Int]
invalidValues (cs, _, ts) = concat [filter (\x -> not (any (`fieldValid` x) cs)) t | t <- ts]

-- runghc --ghc-arg='-package split' 16a.hs inputs/day16
main :: IO ()
main = do 
        args <- getArgs;
        i <- parseFromFile (head args);
        let vs = invalidValues i;

        printf "Answer = %d\n" (sum vs) :: IO ();

        return ();