main.rs
1 use std::{collections::HashSet, str}; 2 3 #[derive(Debug, PartialEq, Eq, Clone, Copy)] 4 enum Tile { 5 Obstacle, 6 Void, 7 } 8 9 fn main() { 10 let input = str::from_utf8(include_bytes!("input")).unwrap(); 11 let mut map: Vec<Vec<Tile>> = vec![]; 12 let mut guard: (i32, i32) = (0, 0); 13 let mut guard_2: (i32, i32) = (0, 0); 14 for (i, line) in input.lines().enumerate() { 15 let mut new_line: Vec<Tile> = vec![]; 16 for (j, r#char) in line.chars().enumerate() { 17 match r#char { 18 '#' => new_line.push(Tile::Obstacle), 19 '^' => { 20 guard = (i as i32, j as i32); 21 guard_2 = (i as i32, j as i32); 22 new_line.push(Tile::Void) 23 } 24 _ => new_line.push(Tile::Void), 25 } 26 } 27 map.push(new_line); 28 } 29 let mut positions: HashSet<(i32, i32)> = HashSet::new(); 30 positions.insert((guard.0, guard.1)); 31 let mut guard_vec: (i32, i32) = (-1, 0); 32 'game: loop { 33 if 0 <= guard.0 + guard_vec.0 34 && guard.0 + guard_vec.0 < map.len() as i32 35 && 0 <= guard.1 + guard_vec.1 36 && guard.1 + guard_vec.1 < map[0].len() as i32 37 { 38 match map[(guard.0 + guard_vec.0) as usize][(guard.1 + guard_vec.1) as usize] { 39 Tile::Obstacle => match guard_vec { 40 (0, 1) => guard_vec = (1, 0), 41 (1, 0) => guard_vec = (0, -1), 42 (0, -1) => guard_vec = (-1, 0), 43 (-1, 0) => guard_vec = (0, 1), 44 _ => todo!(), 45 }, 46 Tile::Void => { 47 guard.0 += guard_vec.0; 48 guard.1 += guard_vec.1; 49 positions.insert((guard.0, guard.1)); 50 } 51 } 52 } else { 53 break 'game; 54 } 55 } 56 println!("Part 1 : {}", positions.len()); 57 let mut sum = 0; 58 for i in 0..*(&map.len()) { 59 for j in 0..*(&map[0].len()) { 60 let mut guard: (i32, i32) = guard_2; 61 if map[i][j] == Tile::Obstacle || i as i32 == guard.0 && j as i32 == guard.1 { 62 continue; 63 } 64 let mut map_copy: Vec<Vec<Tile>> = map.clone(); 65 map_copy[i][j] = Tile::Obstacle; 66 let mut positions: HashSet<((i32, i32), (i32, i32))> = HashSet::new(); 67 let mut guard_vec: (i32, i32) = (-1, 0); 68 'game: loop { 69 if positions.contains(&(guard, guard_vec)) { 70 sum += 1; 71 break 'game; 72 } 73 if 0 <= guard.0 + guard_vec.0 74 && guard.0 + guard_vec.0 < map_copy.len() as i32 75 && 0 <= guard.1 + guard_vec.1 76 && guard.1 + guard_vec.1 < map_copy[0].len() as i32 77 { 78 positions.insert((guard, guard_vec)); 79 match map_copy[(guard.0 + guard_vec.0) as usize] 80 [(guard.1 + guard_vec.1) as usize] 81 { 82 Tile::Obstacle => { 83 match guard_vec { 84 (0, 1) => guard_vec = (1, 0), 85 (1, 0) => guard_vec = (0, -1), 86 (0, -1) => guard_vec = (-1, 0), 87 (-1, 0) => guard_vec = (0, 1), 88 _ => todo!(), 89 } 90 } 91 Tile::Void => { 92 guard.0 += guard_vec.0; 93 guard.1 += guard_vec.1; 94 } 95 } 96 } else { 97 break 'game; 98 } 99 } 100 } 101 } 102 println!("Part 2 : {}", sum); 103 }