#[path = "../lib.rs"] mod lib; #[derive(Copy, Clone, PartialEq)] enum Dir { Up, Right, Down, Left, } fn parse_input() -> (usize, usize, Vec>) { let mut map = vec![]; let mut x0 = 0; let mut y0 = 0; for (y, line) in lib::iter_input().enumerate() { let mut row = vec![]; for (x, c) in line.chars().enumerate() { row.push(match c { '.' => false, '#' => true, _ => { x0 = x; y0 = y; false } }); } map.push(row); } return (x0, y0, map); } fn get_next(pos: (usize, usize, Dir), map: &Vec>) -> Option<(usize, usize, Dir)> { match pos { (x, y, Dir::Up) => { if y == 0 { return None; } else if map[y - 1][x] { return Some((x, y, Dir::Right)); } else { return Some((x, y - 1, Dir::Up)); } } (x, y, Dir::Right) => { if x + 1 == map[0].len() { return None; } else if map[y][x + 1] { return Some((x, y, Dir::Down)); } else { return Some((x + 1, y, Dir::Right)); } } (x, y, Dir::Down) => { if y + 1 == map.len() { return None; } else if map[y + 1][x] { return Some((x, y, Dir::Left)); } else { return Some((x, y + 1, Dir::Down)); } } (x, y, Dir::Left) => { if x == 0 { return None; } else if map[y][x - 1] { return Some((x, y, Dir::Up)); } else { return Some((x - 1, y, Dir::Left)); } } }; } fn check_loop(pos0: (usize, usize, Dir), map: &Vec>) -> bool { let mut path = vec![pos0]; let mut pos = pos0; loop { if let Some(next) = get_next(pos, map) { if path.iter().any(|v| *v == next) { return true; } path.push(next); pos = next; } else { return false; } } } fn main() { let (x0, y0, mut map) = parse_input(); let w = map[0].len(); let h = map.len(); let mut pos = (x0, y0, Dir::Up); let mut visited = vec![vec![false; w]; h]; let mut count1 = 0; let mut count2 = 0; loop { if !visited[pos.1][pos.0] { count1 += 1; visited[pos.1][pos.0] = true; } match get_next(pos, &map) { Some((x2, y2, dir2)) => { if (x2, y2) != (pos.0, pos.1) && (x2, y2) != (x0, y0) && !visited[y2][x2] { map[y2][x2] = true; if check_loop(pos, &map) { count2 += 1; } map[y2][x2] = false; } pos = (x2, y2, dir2); } None => { break; } }; } println!("part1: {}", count1); println!("part2: {}", count2); }