@@ -8,9 +8,9 @@ import qualified Data.IntMap.Strict as M
8
8
type Point = (Int , Int , Int )
9
9
-- Areas are half-open!
10
10
type Area = (Point , Point )
11
- type Step = ( Bool , Area )
11
+ type Grid = A. UArray Point Bool
12
12
13
- parse :: String -> Step
13
+ parse :: String -> ( Bool , Area )
14
14
parse s | (' o' : ' n' : ' ' : s') <- s = (True , f s')
15
15
| (' o' : ' f' : ' f' : ' ' : s') <- s = (False , f s')
16
16
where
@@ -27,34 +27,35 @@ intersection (a, b) (l, h) = (f max a l, f min b h)
27
27
28
28
valid ((lx,ly,lz),(hx,hy,hz)) = lx < hx && ly < hy && lz < hz
29
29
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
59
31
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