summaryrefslogtreecommitdiff
path: root/day13/day13.hs
blob: 4ca7b65ad52a3a448165076333a3421a75abda1e (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
import Data.List
import Data.List.Split
import Data.Maybe
import Text.Read

type Cost = Int
type Vec = (Int, Int)
type Machine = (Vec, Vec, Vec)

mul :: Int -> Vec -> Vec
mul s (x, y) = (s*x, s*y)
add :: Vec -> Vec -> Vec
add (x, y) (z, w) = (x+z, y+w)

consume1 :: [String] -> Machine
consume1 (a:b:p:_) =
  (parseVec "+," a, parseVec "+," b, parseVec "=," p)
  where
    toVec [x, y] = (x,y)
    parseVec spl str = toVec $ catMaybes $ map (readMaybe::String->Maybe Int) $ splitOneOf spl str

consume :: String -> [Machine]
consume file =
  map consume1 macs
  where
    macs = chunksOf 4 $ lines file

winnable :: Machine -> [Vec]
winnable (a, b, p) =
  filter winner opts
  where
    winner (x, y) = (x `mul` a) `add` (y `mul` b) == p
    opts = [(na, nb) | na <- [0..100], nb <- [0..100]]

cost :: Vec -> Cost
cost (a, b) = 3*a + b

cheapest1 :: Cost -> [Vec] -> Cost
cheapest1 cst [] = cst
cheapest1 cst (h:t)
  | hcst < cst = cheapest1 hcst t
  | otherwise  = cheapest1 cst t
  where
    hcst = cost h

cheapest :: [Vec] -> Cost
cheapest [] = 0
cheapest v = cheapest1 (maxBound :: Int) v

part1 :: [Machine] -> Cost
part1 = sum . map cheapest . map winnable

main = do
  file <- readFile "day13.input"
  let machines = consume file
  putStrLn ("Part 1: " ++ (show $ part1 machines))
  --putStrLn ("Part 2: " ++ (show $ part2 machines))