Day 11
[advent-of-code-18.git] / src / advent11 / advent11-map.hs
1 {-# LANGUAGE OverloadedStrings #-}
2
3 import Data.List
4 import qualified Data.Map.Strict as M
5 -- import Data.Map.Strict ((!))
6 -- import qualified Data.Set as S
7 -- import Data.Function (on)
8 import Data.Ord (comparing)
9
10 type Coord = (Integer, Integer) -- x, y
11 type Grid = M.Map Coord Integer
12
13 key = 5719
14 -- key = 42
15
16 main :: IO ()
17 main = do
18 let g = makeGrid key
19 print $ part1 g
20 print $ part2 g
21
22
23 part1 grid = keyOfMaxValue sg
24 where sg = allSubCellPower 3 grid
25
26
27 part2 grid = maximumBy (comparing snd) $ [bestInGrid size grid | size <- [3..300]]
28
29 -- bestSubCell size grid =
30
31 makeGrid :: Integer -> Grid
32 makeGrid key = M.fromList [((x, y), powerLevel x y key) | x <- [1..300], y <- [1..300] ]
33
34 powerLevel :: Integer -> Integer -> Integer -> Integer
35 powerLevel x y key = ((interim `div` 100) `mod` 10) - 5
36 where rackID = x + 10
37 interim = ((rackID) * y + key) * rackID
38
39 subCellPower :: Integer -> Integer -> Integer -> Grid -> Integer
40 subCellPower size x y grid = M.foldr (+) 0 subGrid
41 where subGrid = M.filterWithKey inBounds grid
42 inBounds (kx, ky) _ = (kx >= x) && (kx < x+size) && (ky >= y) && (ky < y+size)
43
44 allSubCellPower :: Integer -> Grid -> Grid
45 allSubCellPower size grid = M.fromList [((x, y), subCellPower size x y grid)| x <- [1..(301-size)], y <- [1..(301-size)]]
46
47
48 keyAndMaxValue :: Ord b => M.Map a b -> (a, b)
49 keyAndMaxValue m = M.foldrWithKey mergeKV (M.findMin m) m
50 where mergeKV k v (bestK, bestV) =
51 if v > bestV then (k, v) else (bestK, bestV)
52
53 keyOfMaxValue :: Ord b => M.Map a b -> a
54 keyOfMaxValue m = fst $ keyAndMaxValue m
55
56 bestInGrid :: Integer -> Grid -> ((Integer, Integer, Integer), Integer)
57 bestInGrid size grid = ((x, y, size), p)
58 where ((x, y), p) = keyAndMaxValue $ allSubCellPower size grid