Skip to content

Commit 451ffe0

Browse files
committed
Further day 22 optimizations I apparently forgot about (??)
1 parent 8e46b8e commit 451ffe0

File tree

1 file changed

+33
-32
lines changed

1 file changed

+33
-32
lines changed

2021/22/Main.hs

+33-32
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import qualified Data.IntMap.Strict as M
88
type Point = (Int, Int, Int)
99
-- Areas are half-open!
1010
type Area = (Point, Point)
11-
type Step = (Bool, Area)
11+
type Grid = A.UArray Point Bool
1212

13-
parse :: String -> Step
13+
parse :: String -> (Bool, Area)
1414
parse s | ('o':'n':' ':s') <- s = (True , f s')
1515
| ('o':'f':'f':' ':s') <- s = (False, f s')
1616
where
@@ -27,34 +27,35 @@ intersection (a, b) (l, h) = (f max a l, f min b h)
2727

2828
valid ((lx,ly,lz),(hx,hy,hz)) = lx < hx && ly < hy && lz < hz
2929

30-
main = do
31-
steps <- map parse <$> lines <$> readFile "input.txt"
32-
let steps' = filter (valid . snd) $ map bounds steps
33-
let (x',y',z') = unzip3 $ foldMap (\(_,(a,b)) -> [a,b]) steps
34-
let [x, y, z ] = map nubSort [x', y', z']
35-
let ![ax,ay,az] = let f l = A.listArray (0, length l - 1) l
36-
f :: [Int] -> A.UArray Int Int
37-
in [f x, f y, f z]
38-
let ![mx,my,mz] = map M.fromList [zip x [0..], zip y [0..], zip z [0..]]
39-
let grid = A.listArray ((0,0,0),(length x,length y,length z)) $ repeat False
40-
grid :: A.UArray Point Bool
41-
let step g (o,((lx,ly,lz),(hx,hy,hz))) = g'
42-
where [sx, sy, sz] = [mx M.! lx, my M.! ly, mz M.! lz]
43-
[ex, ey, ez] = map pred [mx M.! hx, my M.! hy, mz M.! hz]
44-
l = [((x,y,z),o) | x <- [sx..ex], y <- [sy..ey], z <- [sz..ez]]
45-
g' = A.accum seq g l :: A.UArray Point Bool
46-
let size (ix,iy,iz) = product [ex - sx, ey - sy, ez - sz]
47-
where [sx, sy, sz] = [ax A.! ix, ay A.! iy, az A.! iz]
48-
[ex, ey, ez] = [ax A.! succ ix, ay A.! succ iy, az A.! succ iz]
49-
-- This long version reduces runtime from ~58 sec to ~12
50-
-- A.assocs is very slow :(
51-
let count :: A.UArray Point Bool -> Int
52-
count g = sum [ size (x,y,z)
53-
| x <- [0..length x-1]
54-
, y <- [0..length y-1]
55-
, z <- [0..length z-1]
56-
, g A.! (x,y,z)
57-
]
58-
mapM_ (print . count . foldl step grid) [steps', steps]
30+
solve steps = count $ foldl step grid steps
5931
where
60-
bounds (o,a) = (o, intersection ((-50,-50,-50),(51,51,51)) a)
32+
(x',y',z') = unzip3 $ foldMap (\(_,(a,b)) -> [a,b]) steps
33+
[x, y, z ] = map nubSort [x', y', z']
34+
[xl,yl,zl] = map length [x , y , z ]
35+
![ax,ay,az] = let f l = A.listArray (0, length l - 1) l
36+
f :: [Int] -> A.UArray Int Int
37+
in [f x, f y, f z]
38+
![mx,my,mz] = map M.fromList [zip x [0..], zip y [0..], zip z [0..]]
39+
grid :: Grid
40+
grid = A.listArray ((0,0,0),(xl-1,yl-1,zl-1)) $ repeat False
41+
step g (o,((lx,ly,lz),(hx,hy,hz))) = g A.// l :: Grid
42+
where [sx, sy, sz] = [mx M.! lx, my M.! ly, mz M.! lz]
43+
[ex, ey, ez] = map pred [mx M.! hx, my M.! hy, mz M.! hz]
44+
l = [((x,y,z),o) | x <- [sx..ex], y <- [sy..ey], z <- [sz..ez]]
45+
size (ix,iy,iz) = product [ex - sx, ey - sy, ez - sz]
46+
where [sx, sy, sz] = [ax A.! ix, ay A.! iy, az A.! iz]
47+
[ex, ey, ez] = [ax A.! succ ix, ay A.! succ iy, az A.! succ iz]
48+
-- This long version reduces runtime from ~58 sec to ~12
49+
-- A.assocs is very slow :(
50+
count :: Grid -> Int
51+
count g = sum [ size (x,y,z)
52+
| x <- [0..xl - 1]
53+
, y <- [0..yl - 1]
54+
, z <- [0..zl - 1]
55+
, g A.! (x,y,z)
56+
]
57+
58+
main = map parse <$> lines <$> readFile "input.txt"
59+
>>= \steps -> let steps' = filter (valid . snd) $ map bounds steps
60+
in mapM_ (print . solve) [steps', steps]
61+
where bounds (o,a) = (o, intersection ((-50,-50,-50),(51,51,51)) a)

0 commit comments

Comments
 (0)