- commit
- 74af053a50c6371925e64936aca414ee72a46e3a
- parent
- 7a306ce03f2797d2085e4b3df0b2d7c51c18c9d8
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2023-12-18 14:07
refactor
Diffstat
| M | 2023/16/solution.rs | 105 | +++++++++++++++++++++++++++++-------------------------------- |
1 files changed, 50 insertions, 55 deletions
diff --git a/2023/16/solution.rs b/2023/16/solution.rs
@@ -9,10 +9,13 @@ enum Cell {
9 9 MirrorRight,
10 10 }
11 11
12 -1 const RIGHT: u8 = 1;
13 -1 const LEFT: u8 = 2;
14 -1 const UP: u8 = 4;
15 -1 const DOWN: u8 = 8;
-1 12 #[derive(Copy, Clone)]
-1 13 enum Dir {
-1 14 Right = 1,
-1 15 Left = 2,
-1 16 Up = 4,
-1 17 Down = 8,
-1 18 }
16 19
17 20 fn parse_input() -> Vec<Vec<Cell>> {
18 21 return lib::iter_input()
@@ -32,94 +35,86 @@ fn parse_input() -> Vec<Vec<Cell>> {
32 35 .collect();
33 36 }
34 37
35 -1 fn push(map: &Vec<Vec<Cell>>, queue: &mut Vec<(usize, usize, u8)>, x: usize, y: usize, dir: u8) {
-1 38 fn push(map: &Vec<Vec<Cell>>, queue: &mut Vec<(usize, usize, Dir)>, x: usize, y: usize, dir: Dir) {
36 39 match dir {
37 -1 LEFT => {
-1 40 Dir::Left => {
38 41 if x > 0 {
39 42 queue.push((x - 1, y, dir));
40 43 }
41 -1 },
42 -1 RIGHT => {
-1 44 }
-1 45 Dir::Right => {
43 46 if x + 1 < map[0].len() {
44 47 queue.push((x + 1, y, dir));
45 48 }
46 -1 },
47 -1 UP => {
-1 49 }
-1 50 Dir::Up => {
48 51 if y > 0 {
49 52 queue.push((x, y - 1, dir));
50 53 }
51 -1 },
52 -1 DOWN => {
-1 54 }
-1 55 Dir::Down => {
53 56 if y + 1 < map.len() {
54 57 queue.push((x, y + 1, dir));
55 58 }
56 -1 },
57 -1 _ => unreachable!(),
58 -1 }
-1 59 }
-1 60 };
59 61 }
60 62
61 -1 fn count(map: &Vec<Vec<Cell>>, start: (usize, usize, u8)) -> usize {
-1 63 fn count(map: &Vec<Vec<Cell>>, start: (usize, usize, Dir)) -> usize {
62 64 let mut visited = vec![vec![0; map[0].len()]; map.len()];
63 65 let mut queue = vec![start];
64 66
65 67 while let Some((x, y, dir)) = queue.pop() {
66 -1 if visited[y][x] & dir != 0 {
-1 68 if visited[y][x] & (dir as u8) != 0 {
67 69 continue;
68 -1 } else {
69 -1 visited[y][x] |= dir;
70 70 }
71 71
72 72 match map[y][x] {
73 -1 Cell::Empty => match dir {
74 -1 RIGHT => push(&map, &mut queue, x, y, dir),
75 -1 LEFT => push(&map, &mut queue, x, y, dir),
76 -1 UP => push(&map, &mut queue, x, y, dir),
77 -1 DOWN => push(&map, &mut queue, x, y, dir),
78 -1 _ => unreachable!(),
79 -1 },
-1 73 Cell::Empty => {
-1 74 push(&map, &mut queue, x, y, dir);
-1 75 }
80 76 Cell::SplitHorizontal => {
81 77 if visited[y][x] != 0 {
82 78 continue;
83 79 }
84 80 match dir {
85 -1 RIGHT => push(&map, &mut queue, x, y, dir),
86 -1 LEFT => push(&map, &mut queue, x, y, dir),
87 -1 UP | DOWN => {
88 -1 push(&map, &mut queue, x, y, LEFT);
89 -1 push(&map, &mut queue, x, y, RIGHT);
-1 81 Dir::Right | Dir::Left => {
-1 82 push(&map, &mut queue, x, y, dir);
-1 83 }
-1 84 Dir::Up | Dir::Down => {
-1 85 push(&map, &mut queue, x, y, Dir::Left);
-1 86 push(&map, &mut queue, x, y, Dir::Right);
90 87 }
91 -1 _ => unreachable!(),
92 88 };
93 -1 },
-1 89 }
94 90 Cell::SplitVertical => {
95 91 if visited[y][x] != 0 {
96 92 continue;
97 93 }
98 94 match dir {
99 -1 UP => push(&map, &mut queue, x, y, dir),
100 -1 DOWN => push(&map, &mut queue, x, y, dir),
101 -1 LEFT | RIGHT => {
102 -1 push(&map, &mut queue, x, y, UP);
103 -1 push(&map, &mut queue, x, y, DOWN);
-1 95 Dir::Up | Dir::Down => {
-1 96 push(&map, &mut queue, x, y, dir);
-1 97 }
-1 98 Dir::Left | Dir::Right => {
-1 99 push(&map, &mut queue, x, y, Dir::Up);
-1 100 push(&map, &mut queue, x, y, Dir::Down);
104 101 }
105 -1 _ => unreachable!(),
106 102 };
107 -1 },
-1 103 }
108 104 Cell::MirrorRight => match dir {
109 -1 UP => push(&map, &mut queue, x, y, RIGHT),
110 -1 RIGHT => push(&map, &mut queue, x, y, UP),
111 -1 DOWN => push(&map, &mut queue, x, y, LEFT),
112 -1 LEFT => push(&map, &mut queue, x, y, DOWN),
113 -1 _ => unreachable!(),
-1 105 Dir::Up => push(&map, &mut queue, x, y, Dir::Right),
-1 106 Dir::Right => push(&map, &mut queue, x, y, Dir::Up),
-1 107 Dir::Down => push(&map, &mut queue, x, y, Dir::Left),
-1 108 Dir::Left => push(&map, &mut queue, x, y, Dir::Down),
114 109 },
115 110 Cell::MirrorLeft => match dir {
116 -1 DOWN => push(&map, &mut queue, x, y, RIGHT),
117 -1 LEFT => push(&map, &mut queue, x, y, UP),
118 -1 UP => push(&map, &mut queue, x, y, LEFT),
119 -1 RIGHT => push(&map, &mut queue, x, y, DOWN),
120 -1 _ => unreachable!(),
-1 111 Dir::Down => push(&map, &mut queue, x, y, Dir::Right),
-1 112 Dir::Left => push(&map, &mut queue, x, y, Dir::Up),
-1 113 Dir::Up => push(&map, &mut queue, x, y, Dir::Left),
-1 114 Dir::Right => push(&map, &mut queue, x, y, Dir::Down),
121 115 },
122 116 }
-1 117 visited[y][x] |= dir as u8;
123 118 }
124 119
125 120 let mut sum = 0;
@@ -137,17 +132,17 @@ fn count(map: &Vec<Vec<Cell>>, start: (usize, usize, u8)) -> usize {
137 132 fn main() {
138 133 let map = parse_input();
139 134
140 -1 let sum1 = count(&map, (0, 0, RIGHT));
-1 135 let sum1 = count(&map, (0, 0, Dir::Right));
141 136 println!("part1: {}", sum1);
142 137
143 138 let mut sum2 = 0;
144 139 for x in 0..map[0].len() {
145 -1 sum2 = sum2.max(count(&map, (x, 0, DOWN)));
146 -1 sum2 = sum2.max(count(&map, (x, map.len() - 1, UP)));
-1 140 sum2 = sum2.max(count(&map, (x, 0, Dir::Down)));
-1 141 sum2 = sum2.max(count(&map, (x, map.len() - 1, Dir::Up)));
147 142 }
148 143 for y in 0..map.len() {
149 -1 sum2 = sum2.max(count(&map, (0, y, RIGHT)));
150 -1 sum2 = sum2.max(count(&map, (map[0].len() - 1, y, LEFT)));
-1 144 sum2 = sum2.max(count(&map, (0, y, Dir::Right)));
-1 145 sum2 = sum2.max(count(&map, (map[0].len() - 1, y, Dir::Left)));
151 146 }
152 147 println!("part2: {}", sum2);
153 148 }