- commit
- 9d096be059fc0df2a322a48dfc7649a78ac975c1
- parent
- ee2b0b6598ed8ab2200e5afbd853ea978fe9f3da
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2022-12-22 10:14
hardcode (wrong result)
Diffstat
M | 2022/22/solution.rs | 272 | ++++++++++++++++++++++++++++++++++++++++++++++--------------- |
1 files changed, 207 insertions, 65 deletions
diff --git a/2022/22/solution.rs b/2022/22/solution.rs
@@ -1,31 +1,27 @@1 -1 use std::collections::HashSet;2 -13 1 #[path = "../lib.rs"] mod lib; 4 25 -1 fn get_input() -> (HashSet<(usize, usize)>, Vec<(usize, usize)>, Vec<(usize, bool)>) {6 -1 let mut walls = HashSet::new();7 -1 let mut offsets = vec![];-1 3 #[derive(PartialEq)] -1 4 enum Tile { -1 5 Free, -1 6 Wall, -1 7 Out, -1 8 } -1 9 -1 10 fn get_input() -> (Vec<Vec<Tile>>, Vec<(usize, bool)>) { -1 11 let mut map = vec![]; 8 12 let mut path = vec![];9 -1 let mut map = true;-1 13 let mut map_done = false; 10 1411 -1 for (y, line) in lib::iter_input().enumerate() {12 -1 let mut offset = 0;-1 15 for line in lib::iter_input() { 13 16 if line == "" {14 -1 map = false;15 -1 } else if map {16 -1 for (x, c) in line.chars().enumerate() {17 -1 match c {18 -1 ' ' => {19 -1 offset = x;20 -1 },21 -1 '#' => {22 -1 walls.insert((x, y));23 -1 }24 -1 '.' => {},25 -1 _ => unreachable!(),26 -1 };27 -1 }28 -1 offsets.push((offset, line.len()));-1 17 map_done = true; -1 18 } else if !map_done { -1 19 map.push(line.chars().map(|c| match c { -1 20 '.' => Tile::Free, -1 21 '#' => Tile::Wall, -1 22 ' ' => Tile::Out, -1 23 _ => unreachable!(), -1 24 }).collect()); 29 25 } else { 30 26 let mut s = String::new(); 31 27 for c in line.chars() { @@ -41,20 +37,17 @@ fn get_input() -> (HashSet<(usize, usize)>, Vec<(usize, usize)>, Vec<(usize, boo 41 37 } 42 38 } 43 3944 -1 return (walls, offsets, path);-1 40 return (map, path); 45 41 } 46 4247 -1 fn main() {48 -1 let (walls, offsets, path) = get_input();49 -1 println!("walls: {:?}", walls);50 -1 println!("offsets: {:?}", offsets);51 -1 println!("path: {:?}", path);-1 43 fn part1(map: &Vec<Vec<Tile>>, path: &Vec<(usize, bool)>) -> usize { -1 44 let height = map.len(); 52 45 53 46 let mut y = 0;54 -1 let mut x = offsets[y].0;-1 47 let mut x = 0; 55 48 let mut dir = 0; 56 4957 -1 while walls.contains(&(x, y)) {-1 50 while map[y][x] != Tile::Free { 58 51 x += 1; 59 52 } 60 53 @@ -65,51 +58,43 @@ fn main() { 65 58 66 59 match dir { 67 60 0 => {68 -1 let (offset, len) = offsets[y];69 -1 if x2 + 1 < len {70 -1 x2 += 1;71 -1 } else {72 -1 x2 = offset;-1 61 let width = map[y2].len(); -1 62 x2 = (x2 + 1) % width; -1 63 while map[y2][x2] == Tile::Out { -1 64 x2 = (x2 + 1) % width; 73 65 } 74 66 }, 75 67 1 => {76 -1 let offset = offsets.iter().enumerate().find(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap();77 -1 let len = offsets.iter().enumerate().rfind(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap() + 1;78 -1 println!(" {} {}", offset, len);79 -180 -1 if y2 + 1 < len {81 -1 y2 += 1;82 -1 } else {83 -1 y2 = offset;-1 68 y2 = (y2 + 1) % height; -1 69 while map[y2].len() <= x || map[y2][x2] == Tile::Out { -1 70 y2 = (y2 + 1) % height; 84 71 } 85 72 }, 86 73 2 => {87 -1 let (offset, len) = offsets[y];88 -1 if x2 > offset {89 -1 x2 -= 1;90 -1 } else {91 -1 x2 = len - 1;-1 74 let width = map[y2].len(); -1 75 x2 = (x2 + width - 1) % width; -1 76 while map[y2][x2] == Tile::Out { -1 77 x2 = (x2 + width - 1) % width; 92 78 } 93 79 }, 94 80 3 => {95 -1 let offset = offsets.iter().enumerate().find(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap();96 -1 let len = offsets.iter().enumerate().rfind(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap() + 1;97 -1 println!(" {} {}", offset, len);98 -199 -1 if y2 > offset {100 -1 y2 -= 1;101 -1 } else {102 -1 y2 = len - 1;-1 81 y2 = (y2 + height - 1) % height; -1 82 while map[y2].len() <= x || map[y2][x2] == Tile::Out { -1 83 y2 = (y2 + height - 1) % height; 103 84 } 104 85 }, 105 86 _ => unreachable!(), 106 87 } 107 88108 -1 if walls.contains(&(x2, y2)) {109 -1 break;110 -1 } else {111 -1 x = x2;112 -1 y = y2;-1 89 match map[y2][x2] { -1 90 Tile::Free => { -1 91 x = x2; -1 92 y = y2; -1 93 }, -1 94 Tile::Wall => { -1 95 break; -1 96 }, -1 97 Tile::Out => unreachable!(), 113 98 } 114 99 } 115 100 @@ -118,10 +103,167 @@ fn main() { 118 103 } else { 119 104 dir = (dir + 3) % 4; 120 105 } -1 106 } -1 107 -1 108 return 1000 * (y + 1) + 4 * (x + 1) + dir; -1 109 } -1 110 -1 111 fn wrap2(x: usize, y: usize, dir: usize) -> (usize, usize, usize) { -1 112 // hardcoded cube topology -1 113 -1 114 let dx = x % 50; -1 115 let dy = y % 50; -1 116 -1 117 return match (x / 50, y / 50, dir) { -1 118 (1, 0, 0) => ( -1 119 x + 1, y, dir -1 120 ), -1 121 (1, 0, 1) => ( -1 122 x, y + 1, dir -1 123 ), -1 124 (1, 0, 2) => ( -1 125 0 * 50, -1 126 (3 * 50 - 1) - dy, -1 127 0, -1 128 ), -1 129 (1, 0, 3) => ( -1 130 0 * 50, -1 131 3 * 50 + dx, -1 132 0, -1 133 ), -1 134 (2, 0, 0) => ( -1 135 2 * 50 - 1, -1 136 (3 * 50 - 1) - dy, -1 137 2, -1 138 ), -1 139 (2, 0, 1) => ( -1 140 2 * 50 - 1, -1 141 (2 * 50 - 1) - dx, -1 142 2, -1 143 ), -1 144 (2, 0, 2) => ( -1 145 x - 1, y, dir -1 146 ), -1 147 (2, 0, 3) => ( -1 148 0 * 50 + dx, -1 149 4 * 50 - 1, -1 150 3, -1 151 ), -1 152 (1, 1, 0) => ( -1 153 2 * 50 + dy, -1 154 1 * 50 - 1, -1 155 3, -1 156 ), -1 157 (1, 1, 1) => ( -1 158 x, y + 1, dir -1 159 ), -1 160 (1, 1, 2) => ( -1 161 0 * 50 + dy, -1 162 2 * 50, -1 163 1, -1 164 ), -1 165 (1, 1, 3) => ( -1 166 x, y - 1, dir, -1 167 ), -1 168 (0, 2, 0) => ( -1 169 x + 1, y, dir -1 170 ), -1 171 (0, 2, 1) => ( -1 172 x, y + 1, dir -1 173 ), -1 174 (0, 2, 2) => ( -1 175 1 * 50, -1 176 (1 * 50 - 1) - dy, -1 177 0, -1 178 ), -1 179 (0, 2, 3) => ( -1 180 1 * 50, -1 181 1 * 50 + dy, -1 182 0, -1 183 ), -1 184 (1, 2, 0) => ( -1 185 3 * 50 - 1, -1 186 (1 * 50 - 1) - dy, -1 187 2, -1 188 ), -1 189 (1, 2, 1) => ( -1 190 1 * 50 - 1, -1 191 3 * 50 + dy, -1 192 2, -1 193 ), -1 194 (1, 2, 2) => ( -1 195 x - 1, y, dir -1 196 ), -1 197 (1, 2, 3) => ( -1 198 x, y - 1, dir -1 199 ), -1 200 (0, 3, 0) => ( -1 201 1 * 50 + dy, -1 202 3 * 50 - 1, -1 203 3, -1 204 ), -1 205 (0, 3, 1) => ( -1 206 2 * 50 + dx, -1 207 0 * 50, -1 208 1, -1 209 ), -1 210 (0, 3, 2) => ( -1 211 1 * 50 + dx, -1 212 0 * 50, -1 213 1, -1 214 ), -1 215 (0, 3, 3) => ( -1 216 x, y - 1, dir -1 217 ), -1 218 _ => unreachable!(), -1 219 }; -1 220 } -1 221 -1 222 fn part2(map: &Vec<Vec<Tile>>, path: &Vec<(usize, bool)>) -> usize { -1 223 let mut y = 0; -1 224 let mut x = 0; -1 225 let mut dir = 0; -1 226 -1 227 while map[y][x] != Tile::Free { -1 228 x += 1; -1 229 } -1 230 -1 231 for (steps, turn) in path.iter() { -1 232 for _ in 0..*steps { -1 233 let (x2, y2, dir2) = match dir { -1 234 0 => if (x + 1) % 50 == 0 { wrap2(x, y, dir) } else { (x + 1, y, dir) }, -1 235 1 => if (y + 1) % 50 == 0 { wrap2(x, y, dir) } else { (x, y + 1, dir) }, -1 236 2 => if x % 50 == 0 { wrap2(x, y, dir) } else { (x - 1, y, dir) }, -1 237 3 => if y % 50 == 0 { wrap2(x, y, dir) } else { (x, y - 1, dir) }, -1 238 _ => unreachable!(), -1 239 }; -1 240 -1 241 match map[y2][x2] { -1 242 Tile::Free => { -1 243 x = x2; -1 244 y = y2; -1 245 dir = dir2; -1 246 }, -1 247 Tile::Wall => { -1 248 break; -1 249 }, -1 250 Tile::Out => unreachable!(), -1 251 } -1 252 } 121 253122 -1 println!("{},{}", x, y);-1 254 if *turn { -1 255 dir = (dir + 1) % 4; -1 256 } else { -1 257 dir = (dir + 3) % 4; -1 258 } 123 259 } 124 260125 -1 println!("{},{} {}", x, y, dir);126 -1 println!("part1: {}", 1000 * y + 4 * x + dir);-1 261 return 1000 * (y + 1) + 4 * (x + 1) + dir; -1 262 } -1 263 -1 264 fn main() { -1 265 let (map, path) = get_input(); -1 266 -1 267 println!("part1: {}", part1(&map, &path)); -1 268 println!("part2: {}", part2(&map, &path)); 127 269 }