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))
|