This commit is contained in:
Christian
2023-10-26 15:19:42 +02:00
parent 167ce73a4c
commit 133b7e3a38
6 changed files with 2899 additions and 0 deletions

81
src/Days/D18.hs Normal file
View File

@@ -0,0 +1,81 @@
{-# LANGUAGE ImportQualifiedPost #-}
module Days.D18 where
import Common
import Data.Set (Set)
import Data.Set qualified as Set
import Data.Tuple.Extra (uncurry3)
import Parse
import Text.Megaparsec.Char (char)
parser :: Parser [(Int, Int, Int)]
parser = someLines point
where
point = (,,) <$> int <* char ',' <*> int <* char ',' <*> int
mins :: [(Int, Int, Int)] -> (Int, Int, Int)
mins =
foldr1
(\(a', b', c') (a, b, c) -> (min a' a, min b' b, min c' c))
maxs :: [(Int, Int, Int)] -> (Int, Int, Int)
maxs =
foldr1
(\(a', b', c') (a, b, c) -> (max a' a, max b' b, max c' c))
adjacent :: (Int, Int, Int) -> [(Int, Int, Int)]
adjacent (x, y, z) =
[ (x - 1, y, z),
(x + 1, y, z),
(x, y - 1, z),
(x, y + 1, z),
(x, y, z - 1),
(x, y, z + 1)
]
part1 :: [(Int, Int, Int)] -> Int
part1 l =
let s = Set.fromList l
in length
. filter (\v -> not $ Set.member v s)
. concatMap adjacent
$ l
part2 :: [(Int, Int, Int)] -> Int
part2 points =
let (x_max, y_max, z_max) = maxs points
(x_min, y_min, z_min) = mins points
insideSearchSpace (x, y, z) =
x_min - 1 <= x
&& x <= x_max + 1
&& y_min - 1 <= y
&& y <= y_max + 1
&& z_min - 1 <= z
&& z <= z_max + 1
start = (x_min - 1, y_min - 1, z_min - 1)
in go insideSearchSpace [start] (Set.singleton start) 0
where
pointSet :: Set (Int, Int, Int)
pointSet = Set.fromList points
go _ [] _ result = result
go inside active_ seen_ result_ =
uncurry3 (go inside)
. foldr
( \p (active, seen, result) ->
if Set.member p seen
then (active, seen, result)
else
if Set.member p pointSet
then (active, seen, result + 1)
else (p : active, Set.insert p seen, result)
)
([], seen_, result_)
. filter inside
. concatMap adjacent
$ active_
day :: Day
day = parsecDay parser (definitive . part1, definitive . part2)

View File

@@ -29,6 +29,7 @@ import Days.D14 qualified as D14
import Days.D15 qualified as D15
import Days.D16 qualified as D16
import Days.D17 qualified as D17
import Days.D18 qualified as D18
import Data.ByteString.Char8 qualified as BS
import Data.Text.IO qualified as T
@@ -58,4 +59,5 @@ days =
, [D15.day]
, [D16.day]
, [D17.day]
, [D18.day]
]