Skip to content

Commit 28d2b0e

Browse files
committed
Create an array variant
1 parent 8c2e3e2 commit 28d2b0e

File tree

2 files changed

+86
-9
lines changed

2 files changed

+86
-9
lines changed

16.hs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Data.Map qualified as M
1+
import Data.Array qualified as A
22
import Data.Set qualified as S
33
import Data.Maybe (fromJust)
44
import Control.Arrow ((&&&))
@@ -7,13 +7,15 @@ main :: IO ()
77
main = interact $ (++ "\n") . show . (p1 &&& p2) . parse
88

99
type Ix = (Int, Int)
10-
data Grid = Grid { chars :: M.Map Ix Char, mi :: Ix }
10+
data Grid = Grid { chars :: A.Array Ix Char, mx, my :: Int }
1111

1212
parse :: String -> Grid
13-
parse = mkC . concatMap (uncurry f) . zip [0..] . lines
14-
where f y = map (uncurry g) . zip [0..]
15-
where g x = ((x, y),)
16-
mkC xs = Grid (M.fromList xs) (fst $ last xs)
13+
parse = mkC . lines
14+
where
15+
mkC xs = let mx = length (xs !! 0) - 1
16+
my = length xs - 1
17+
axs = [((x, y), xs !! y !! x) | x <- [0..mx], y <- [0..my]]
18+
in Grid (A.array ((0, 0), (mx, my)) axs) mx my
1719

1820
p1 :: Grid -> Int
1921
p1 = (`energized` ((0, 0), R))
@@ -25,7 +27,7 @@ data Direction = R | L | U | D deriving (Ord, Eq)
2527
type Beam = (Ix, Direction)
2628

2729
energized :: Grid -> Beam -> Int
28-
energized Grid { chars, mi = (mx, my) } start =
30+
energized Grid { chars, mx, my } start =
2931
count $ trace S.empty [start]
3032
where
3133
count = S.size . S.map fst
@@ -54,7 +56,7 @@ energized Grid { chars, mi = (mx, my) } start =
5456
else ([b], [])
5557

5658
inBounds ((x, y), _) = x >= 0 && y >= 0 && x <= mx && y <= my
57-
char b = fromJust $ M.lookup (fst b) chars
59+
char b = chars A.! fst b
5860
isHorizontal (_, d) = d == L || d == R
5961
isVertical = not . isHorizontal
6062
step ((x, y), R) = ((x + 1, y), R)
@@ -69,7 +71,7 @@ energized Grid { chars, mi = (mx, my) } start =
6971
reflectR ((x, y), _) = ((x + 1, y), R)
7072

7173
edges :: Grid -> [Beam]
72-
edges Grid { mi = (mx, my) } = concat [
74+
edges Grid { mx, my } = concat [
7375
[b | y <- [0..my], b <- [((0, y), R), ((mx, y), L)]],
7476
[((x, 0), D) | x <- [0..mx]],
7577
[((x, my), U) | x <- [0..mx]]]

16.map.hs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import Data.Map qualified as M
2+
import Data.Set qualified as S
3+
import Data.Maybe (fromJust)
4+
import Control.Arrow ((&&&))
5+
6+
main :: IO ()
7+
main = interact $ (++ "\n") . show . (p1 &&& p2) . parse
8+
9+
type Ix = (Int, Int)
10+
data Grid = Grid { chars :: M.Map Ix Char, mi :: Ix }
11+
12+
parse :: String -> Grid
13+
parse = mkC . concatMap (uncurry f) . zip [0..] . lines
14+
where f y = map (uncurry g) . zip [0..]
15+
where g x = ((x, y),)
16+
mkC xs = Grid (M.fromList xs) (fst $ last xs)
17+
18+
p1 :: Grid -> Int
19+
p1 = (`energized` ((0, 0), R))
20+
21+
p2 :: Grid -> Int
22+
p2 grid = maximum $ map (energized grid) $ edges grid
23+
24+
data Direction = R | L | U | D deriving (Ord, Eq)
25+
type Beam = (Ix, Direction)
26+
27+
energized :: Grid -> Beam -> Int
28+
energized Grid { chars, mi = (mx, my) } start =
29+
count $ trace S.empty [start]
30+
where
31+
count = S.size . S.map fst
32+
trace processed [] = processed
33+
trace processed (b:bs)
34+
| S.member b processed = trace processed bs
35+
| otherwise =
36+
let (ray, beams) = until b (char b)
37+
in trace (foldl (\s b -> S.insert b s) processed ray)
38+
(bs ++ filter inBounds beams)
39+
40+
until b '|' | isHorizontal b = ([b], splitV b)
41+
until b '-' | isVertical b = ([b], splitH b)
42+
until b@(_, d) '\\'
43+
| d == R = ([b], [reflectD b])
44+
| d == L = ([b], [reflectU b])
45+
| d == U = ([b], [reflectL b])
46+
| d == D = ([b], [reflectR b])
47+
until b@(_, d) '/'
48+
| d == R = ([b], [reflectU b])
49+
| d == L = ([b], [reflectD b])
50+
| d == U = ([b], [reflectR b])
51+
| d == D = ([b], [reflectL b])
52+
until b _ = let n = step b in
53+
if inBounds n then let (ray, beams) = until n (char n) in (b : ray, beams)
54+
else ([b], [])
55+
56+
inBounds ((x, y), _) = x >= 0 && y >= 0 && x <= mx && y <= my
57+
char b = fromJust $ M.lookup (fst b) chars
58+
isHorizontal (_, d) = d == L || d == R
59+
isVertical = not . isHorizontal
60+
step ((x, y), R) = ((x + 1, y), R)
61+
step ((x, y), L) = ((x - 1, y), L)
62+
step ((x, y), U) = ((x, y - 1), U)
63+
step ((x, y), D) = ((x, y + 1), D)
64+
splitH ((x, y), _) = [((x - 1, y), L), ((x + 1, y), R)]
65+
splitV ((x, y), _) = [((x, y - 1), U), ((x, y + 1), D)]
66+
reflectU ((x, y), _) = ((x, y - 1), U)
67+
reflectD ((x, y), _) = ((x, y + 1), D)
68+
reflectL ((x, y), _) = ((x - 1, y), L)
69+
reflectR ((x, y), _) = ((x + 1, y), R)
70+
71+
edges :: Grid -> [Beam]
72+
edges Grid { mi = (mx, my) } = concat [
73+
[b | y <- [0..my], b <- [((0, y), R), ((mx, y), L)]],
74+
[((x, 0), D) | x <- [0..mx]],
75+
[((x, my), U) | x <- [0..mx]]]

0 commit comments

Comments
 (0)