{-# Language QuasiQuotes, ImportQualifiedPost #-}
module Main where
import Data.Ix (inRange)
import Data.Maybe (fromJust)
import Data.Set (Set)
import Data.Set qualified as Set
import Advent (format)
import Advent.Search (bfs)
import Advent.Coord3 (Coord3(..), boundingBox)
main :: IO ()
IO ()
main =
do input <- [format|2022 18 (%u,%u,%u%n)*|]
let cubes = [Coord3] -> Set Coord3
forall a. Ord a => [a] -> Set a
Set.fromList (((Int, Int, Int) -> Coord3) -> [(Int, Int, Int)] -> [Coord3]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Int, Int) -> Coord3
toC3 [(Int, Int, Int)]
input)
let air = Set Coord3 -> Set Coord3
findAir Set Coord3
cubes
print (length [() | c <- Set.toList cubes, n <- neigh c, Set.notMember n cubes])
print (length [() | c <- Set.toList cubes, n <- neigh c, Set.member n air ])
findAir :: Set Coord3 -> Set Coord3
findAir :: Set Coord3 -> Set Coord3
findAir Set Coord3
cubes = [Coord3] -> Set Coord3
forall a. Ord a => [a] -> Set a
Set.fromList ((Coord3 -> [Coord3]) -> Coord3 -> [Coord3]
forall a. Ord a => (a -> [a]) -> a -> [a]
bfs Coord3 -> [Coord3]
step (Coord3
hi Coord3 -> Coord3 -> Coord3
forall a. Num a => a -> a -> a
+ Coord3
1))
where
(Coord3
lo, Coord3
hi) = Maybe (Coord3, Coord3) -> (Coord3, Coord3)
forall a. HasCallStack => Maybe a -> a
fromJust (Set Coord3 -> Maybe (Coord3, Coord3)
forall (f :: * -> *).
Foldable f =>
f Coord3 -> Maybe (Coord3, Coord3)
boundingBox Set Coord3
cubes)
box :: (Coord3, Coord3)
box = (Coord3
lo Coord3 -> Coord3 -> Coord3
forall a. Num a => a -> a -> a
- Coord3
1, Coord3
hi Coord3 -> Coord3 -> Coord3
forall a. Num a => a -> a -> a
+ Coord3
1)
step :: Coord3 -> [Coord3]
step Coord3
c = [Coord3
n | Coord3
n <- Coord3 -> [Coord3]
neigh Coord3
c, (Coord3, Coord3) -> Coord3 -> Bool
forall a. Ix a => (a, a) -> a -> Bool
inRange (Coord3, Coord3)
box Coord3
n, Coord3 -> Set Coord3 -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.notMember Coord3
n Set Coord3
cubes]
neigh :: Coord3 -> [Coord3]
neigh :: Coord3 -> [Coord3]
neigh (C3 Int
x Int
y Int
z) = [Int -> Int -> Int -> Coord3
C3 (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
y Int
z, Int -> Int -> Int -> Coord3
C3 (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
y Int
z, Int -> Int -> Int -> Coord3
C3 Int
x (Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
z, Int -> Int -> Int -> Coord3
C3 Int
x (Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
z, Int -> Int -> Int -> Coord3
C3 Int
x Int
y (Int
zInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1), Int -> Int -> Int -> Coord3
C3 Int
x Int
y (Int
zInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)]
toC3 :: (Int, Int, Int) -> Coord3
toC3 :: (Int, Int, Int) -> Coord3
toC3 (Int
x,Int
y,Int
z) = Int -> Int -> Int -> Coord3
C3 Int
x Int
y Int
z