-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day22.hs
113 lines (99 loc) · 2.53 KB
/
Day22.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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
module Day22
( part1
, part2
) where
import Data.Maybe (Maybe (Just, Nothing), mapMaybe)
import Helpers.Parsers (alpha, complexParser, numsAsStrings)
import Linear.V3 (V3 (..))
data Cuboid =
Cuboid
{ lower :: Pos
, upper :: Pos
, active :: Bool
}
deriving (Show)
type Pos = V3 Int
lowThreshold = -50
highThreshold = 50
cuboidIntersection :: Cuboid -> Cuboid -> Maybe Cuboid
cuboidIntersection c1 c2
| maxMinX <= minMaxX && maxMinY <= minMaxY && maxMinZ <= minMaxZ =
Just $
Cuboid (V3 maxMinX maxMinY maxMinZ) (V3 minMaxX minMaxY minMaxZ) activity
| otherwise = Nothing
where
(V3 x0 y0 z0) = lower c1
(V3 x1 y1 z1) = lower c2
(V3 x2 y2 z2) = upper c1
(V3 x3 y3 z3) = upper c2
maxMinX = max x0 x1
maxMinY = max y0 y1
maxMinZ = max z0 z1
minMaxX = min x2 x3
minMaxY = min y2 y3
minMaxZ = min z2 z3
-- to adapt
activity = not (active c2)
step :: Cuboid -> [Cuboid] -> [Cuboid]
step cuboid
| active cuboid = (cuboid :) . mapMaybe (cuboidIntersection cuboid)
| otherwise = mapMaybe (cuboidIntersection cuboid)
toCuboid :: [[String]] -> Cuboid
toCuboid [[x], pos] = Cuboid (V3 x0 y0 z0) (V3 x1 y1 z1) (x == "on")
where
[x0, x1, y0, y1, z0, z1] = map read pos
reboot :: [Cuboid] -> [Cuboid]
reboot = foldl (\cs c -> step c cs ++ cs) []
volume :: Cuboid -> Int
volume (Cuboid (V3 x0 y0 z0) (V3 x1 y1 z1) ac) =
onoff * (x1 - x0 + 1) * (y1 - y0 + 1) * (z1 - z0 + 1)
where
onoff
| ac = 1
| otherwise = -1
ons :: [Cuboid] -> Int
ons = sum . map volume
threshold :: Cuboid -> Maybe Cuboid
threshold (Cuboid (V3 x0 y0 z0) (V3 x1 y1 z1) ac)
| x0 > highThreshold ||
y0 > highThreshold ||
z0 > highThreshold ||
x1 < lowThreshold || y1 < lowThreshold || z1 < lowThreshold = Nothing
| otherwise =
Just .
Cuboid
(V3 (max x0 lowThreshold) (max y0 lowThreshold) (max z0 lowThreshold))
(V3 (min x1 highThreshold) (min y1 highThreshold) (min z1 highThreshold)) $
ac
part1 :: Bool -> String -> String
part1 _ =
show .
ons .
reboot .
mapMaybe (threshold . toCuboid) .
complexParser
[" "]
[ alpha
, numsAsStrings
, numsAsStrings
, numsAsStrings
, numsAsStrings
, numsAsStrings
, numsAsStrings
]
part2 :: Bool -> String -> String
part2 _ =
show .
ons .
reboot .
map toCuboid .
complexParser
[" "]
[ alpha
, numsAsStrings
, numsAsStrings
, numsAsStrings
, numsAsStrings
, numsAsStrings
, numsAsStrings
]