use std::collections::HashSet; #[path = "../lib.rs"] mod lib; fn render(blocked: &HashSet<(usize, usize)>) { let min_x = blocked.iter().map(|(x, _)| *x).min().unwrap(); let max_x = blocked.iter().map(|(x, _)| *x).max().unwrap(); let max_y = blocked.iter().map(|(_, y)| *y).max().unwrap(); for y in 0..=max_y { for x in min_x..=max_x { if blocked.contains(&(x, y)) { print!("#"); } else { print!("."); } } print!("\n"); } print!("\n"); } fn main() { let paths: Vec> = lib::iter_input().map(|line| { return line.split(" -> ").map(|pair| { let (x, y) = lib::split_once(pair, ',').unwrap(); return ( x.parse().unwrap(), y.parse().unwrap(), ); }).collect(); }).collect(); let mut blocked = HashSet::new(); for path in paths.iter() { for i in 0..path.len() - 1 { let (x1, y1) = path[i]; let (x2, y2) = path[i + 1]; for y in y1.min(y2)..=y1.max(y2) { for x in x1.min(x2)..=x1.max(x2) { blocked.insert((x, y)); } } } } let max_y = blocked.iter().map(|(_, y)| *y).max().unwrap(); render(&blocked); let mut path = vec![(500, 0)]; let mut count = 0; let mut part1 = true; while path.len() > 0 { let (mut x, mut y) = path.pop().unwrap(); loop { if y == max_y + 1 { if part1 { render(&blocked); println!("part1: {}", count); part1 = false; } blocked.insert((x, y)); count += 1; break; } else if !blocked.contains(&(x, y + 1)) { path.push((x, y)); y += 1; } else if !blocked.contains(&(x - 1, y + 1)) { path.push((x, y)); x -= 1; y += 1; } else if !blocked.contains(&(x + 1, y + 1)) { path.push((x, y)); x += 1; y += 1; } else { blocked.insert((x, y)); count += 1; break; } } } render(&blocked); println!("part2: {}", count); }