Tweaked some parsing code
[advent-of-code-21.git] / advent07 / Main.hs
1 -- Writeup at https://work.njae.me.uk/2021/12/07/advent-of-code-2021-day-7/
2
3 import Data.List.Split
4
5 main :: IO ()
6 main =
7 do text <- readFile "data/advent07.txt"
8 let subs = map (read @Int) $ splitOn "," text
9 print $ part1 subs
10 print $ part2 subs
11
12 part1 = bestFuel loss1
13 part2 = bestFuel loss2
14
15 bestFuel :: ([Int] -> Int -> Int) -> [Int] -> Int
16 bestFuel loss subs = loss subs best
17 where meanSub = (sum subs) `div` (length subs)
18 best = gradientDescend loss subs meanSub
19
20 loss1 :: [Int] -> Int -> Int
21 loss1 subs target = sum $ map diff subs
22 where diff s = abs (target - s)
23
24 loss2 :: [Int] -> Int -> Int
25 loss2 subs target = sum $ map triangleDiff subs
26 where diff s = abs (target - s)
27 triangleDiff s = ((diff s) * ((diff s) + 1)) `div` 2
28
29 gradientDescend :: ([Int] -> Int -> Int) -> [Int] -> Int -> Int
30 gradientDescend loss subs guess =
31 if | lossLower < lossHere -> gradientDescend loss subs (guess - 1)
32 | lossHigher < lossHere -> gradientDescend loss subs (guess + 1)
33 | otherwise -> guess
34 where lossHere = loss subs guess
35 lossLower = loss subs (guess - 1)
36 lossHigher = loss subs (guess + 1)