-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDay11.hs
35 lines (29 loc) · 1.45 KB
/
Day11.hs
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
{-|
Module: Day11
Description: <https://adventofcode.com/2018/day/11 Day 11: Chronal Charge>
-}
{-# LANGUAGE TypeApplications, ViewPatterns #-}
module Day11 (day11a, day11b) where
import Control.Arrow ((***), second)
import Control.Parallel.Strategies (parMap, rpar)
import Data.Array.Unboxed (IArray, Ix, UArray, (!), bounds, listArray, range)
import Data.Char (isDigit)
import Data.List (maximumBy, scanl')
import Data.Ord (comparing)
size :: Int
size = 300
tabulate :: (IArray a e, Integral e) => e -> a (Int, Int) e
tabulate z = listArray ((0, 0), (size, size)) $ scanl build (repeat 0) [1..] >>= take (size + 1)
where build prev y = zipWith (+) prev $ scanl' (acc y) 0 [1..]
acc y prev x = prev + let r = x + 10 in ((r * y + z) * r) `div` 100 `mod` 10 - 5
maxBox :: (IArray a e, Num e, Ord e, Ix i, Num i) => a (i, i) e -> i -> ((i, i, i), e)
maxBox a n = maximumBy (comparing snd)
[((x + 1, y + 1, n), box p) | p@(y, x) <- range $ second (subtract n *** subtract n) $ bounds a]
where box (y, x) = a ! (y, x) - a ! (y, x + n) - a ! (y + n, x) + a ! (y + n, x + n)
day11a :: String -> String
day11a (tabulate @UArray @Int . read . filter isDigit -> table) = show x ++ "," ++ show y
where ((x, y, _), _) = maxBox table 3
day11b :: String -> String
day11b (tabulate @UArray @Int . read . filter isDigit -> table) =
show x ++ "," ++ show y ++ "," ++ show n
where ((x, y, n), _) = maximumBy (comparing snd) $ parMap rpar (maxBox table) [1..size]