#[path = "../lib.rs"] mod lib; fn parse_input() -> Vec<(usize, usize)> { let mut start = (0, 0); let mut map = vec![]; for (y, line) in lib::iter_input().enumerate() { let mut row = vec![]; for (x, c) in line.bytes().enumerate() { row.push(match c { b'#' => false, b'.' => true, b'S' => { start = (x, y); true }, b'E' => true, _ => unreachable!(), }); } map.push(row); } let mut path = vec![]; let (mut x, mut y) = start; loop { path.push((x, y)); map[y][x] = false; if map[y - 1][x] { y -= 1; } else if map[y + 1][x] { y += 1; } else if map[y][x - 1] { x -= 1; } else if map[y][x + 1] { x += 1; } else { break; } } return path; } fn main() { let path = parse_input(); let mut count1 = 0; let mut count2 = 0; for t1 in 0..path.len() { let (x1, y1) = path[t1]; for t2 in (t1 + 102)..(t1 + 121).min(path.len()) { let (x2, y2) = path[t2]; let d = x1.abs_diff(x2) + y1.abs_diff(y2); if t2 >= t1 + d + 100 { if d <= 2 { count1 += 1; } if d <= 20 { count2 += 1; } } } // perf: check t2 >= t1 + d + 100 if we already know it is true // saves ~33% for t2 in (t1 + 121)..path.len() { let (x2, y2) = path[t2]; let d = x1.abs_diff(x2) + y1.abs_diff(y2); if d <= 2 { count1 += 1; } if d <= 20 { count2 += 1; } } } println!("part1: {}", count1); println!("part2: {}", count2); }