{-# Language QuasiQuotes, ImportQualifiedPost #-}
module Main (main) where
import Advent (format, pickOne)
import Advent.Box (Box(Dim, Pt), size, unionBoxes, intersectBox)
import Data.List (tails)
import Data.Maybe (isNothing)
main :: IO ()
IO ()
main =
do [(Int, Int, Int, Int, Int)]
input <- [format|2018 3 (#%u %@ %u,%u: %ux%u%n)*|]
let boxes :: [(Int, Box ('S ('S 'Z)))]
boxes = [(Int
i, Int -> Int -> Box ('S 'Z) -> Box ('S ('S 'Z))
forall (n :: Nat). Int -> Int -> Box n -> Box ('S n)
Dim Int
x (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
sx) (Int -> Int -> Box 'Z -> Box ('S 'Z)
forall (n :: Nat). Int -> Int -> Box n -> Box ('S n)
Dim Int
y (Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
sy) Box 'Z
Pt)) | (Int
i,Int
x,Int
y,Int
sx,Int
sy) <- [(Int, Int, Int, Int, Int)]
input]
Int -> IO ()
forall a. Show a => a -> IO ()
print ([Box ('S ('S 'Z))] -> Int
forall (n :: Nat). [Box n] -> Int
part1 (((Int, Box ('S ('S 'Z))) -> Box ('S ('S 'Z)))
-> [(Int, Box ('S ('S 'Z)))] -> [Box ('S ('S 'Z))]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Box ('S ('S 'Z))) -> Box ('S ('S 'Z))
forall a b. (a, b) -> b
snd [(Int, Box ('S ('S 'Z)))]
boxes))
Int -> IO ()
forall a. Show a => a -> IO ()
print ([(Int, Box ('S ('S 'Z)))] -> Int
forall i (n :: Nat). [(i, Box n)] -> i
part2 [(Int, Box ('S ('S 'Z)))]
boxes)
part1 :: [Box n] -> Int
part1 :: forall (n :: Nat). [Box n] -> Int
part1 [Box n]
boxes =
[Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ((Box n -> Int) -> [Box n] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Box n -> Int
forall (n :: Nat). Box n -> Int
size ([Box n] -> [Box n]
forall (a :: Nat). [Box a] -> [Box a]
unionBoxes
[Box n
q | Box n
p:[Box n]
ps <- [Box n] -> [[Box n]]
forall a. [a] -> [[a]]
tails [Box n]
boxes, Just Box n
q <- (Box n -> Maybe (Box n)) -> [Box n] -> [Maybe (Box n)]
forall a b. (a -> b) -> [a] -> [b]
map (Box n -> Box n -> Maybe (Box n)
forall (n :: Nat). Box n -> Box n -> Maybe (Box n)
intersectBox Box n
p) [Box n]
ps]))
part2 :: [(i, Box n)] -> i
part2 :: forall i (n :: Nat). [(i, Box n)] -> i
part2 [(i, Box n)]
boxes =
[i] -> i
forall a. HasCallStack => [a] -> a
head [i
i | ((i
i,Box n
p),[(i, Box n)]
ps) <- [(i, Box n)] -> [((i, Box n), [(i, Box n)])]
forall a. [a] -> [(a, [a])]
pickOne [(i, Box n)]
boxes, ((i, Box n) -> Bool) -> [(i, Box n)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Maybe (Box n) -> Bool
forall a. Maybe a -> Bool
isNothing (Maybe (Box n) -> Bool)
-> ((i, Box n) -> Maybe (Box n)) -> (i, Box n) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Box n -> Box n -> Maybe (Box n)
forall (n :: Nat). Box n -> Box n -> Maybe (Box n)
intersectBox Box n
p (Box n -> Maybe (Box n))
-> ((i, Box n) -> Box n) -> (i, Box n) -> Maybe (Box n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i, Box n) -> Box n
forall a b. (a, b) -> b
snd) [(i, Box n)]
ps]