diff --git a/2025/09.rs b/2025/09.rs index 8397215..d99ea97 100644 --- a/2025/09.rs +++ b/2025/09.rs @@ -1,8 +1,19 @@ ---cargo +[profile.dev] +opt-level = 3 --- static CONTENT: &'static str = include_str!("./inputs/09_1.txt"); +const PRINT: bool = false; + +#[derive(Debug, PartialEq, Clone, Copy)] +enum Cell { + Empty, + Red, + Green, +} + fn main() { let points: Vec<(usize, usize)> = CONTENT.lines().map(|l| l.trim()).filter(|l| !l.is_empty()).map(|l| { let (first, second) = l.split_once(',').unwrap(); @@ -12,12 +23,82 @@ fn main() { (first, second) }).collect(); - println!("Points:\n{:?}", points); + // println!("Points:\n{:?}", points); + + let grid_width: usize = points.iter().map(|(x, _)| *x).max().unwrap()+1; + let grid_height: usize = points.iter().map(|(y, _)| *y).max().unwrap()+1; + + let mut grid = vec![Cell::Empty;grid_width*grid_height]; + for parts in points.windows(2).chain(core::iter::once(&[points.last().copied().unwrap(), points.first().copied().unwrap()] as &[(usize, usize)])) { + let start = parts[0]; + let end = parts[1]; + + let g_points = line_point_iter(start, end); + + grid[start.1 *grid_width+ start.0] = Cell::Red; + for (x,y) in g_points { + grid[y*grid_width+x] = Cell::Green; + } + } + print_grid(&grid, grid_width, grid_height); + + let inner_point = points.windows(2) + .filter(|p| { + let start = p[0]; + let end = p[1]; + + start.0 == end.0 + }).filter_map(|p| { + let start = p[0]; + let end = p[1]; + + line_point_iter(start, end).next() + }).flat_map(|(x, y)| { + [(x-1, y), (x+1, y)] + }).filter(|(x, y)| { + (0..grid_width).contains(x) + }).find(|(x, y)| { + let c = (0..*x).map(|x| grid[y*grid_width + x]).filter(|c| *c == Cell::Green).count(); + + c == 1 + }).unwrap(); + + let mut queue = vec![inner_point]; + while let Some((x, y)) = queue.pop() { + if !(0..grid_width).contains(&x) { + continue; + } + if !(0..grid_height).contains(&y) { + continue; + } + + if grid[y*grid_width+x] != Cell::Empty { + continue; + } + + grid[y*grid_width+x] = Cell::Green; + + queue.extend([(x-1, y), (x+1, y), (x, y-1), (x, y+1)]); + } + + println!("After filling"); + print_grid(&grid, grid_width, grid_height); let mut rects: Vec<((usize, usize), (usize, usize), usize)> = points.iter() .flat_map(|p| core::iter::repeat(*p).zip(points.iter().copied())) .filter(|(f, s)| f != s) .map(|(f, s)| (f, s, (f.0.abs_diff(s.0)+1) * (f.1.abs_diff(s.1)+1))) + .filter(|(f, s, _)| { + let x0 = f.0.min(s.0); + let x1 = f.0.max(s.0); + + let y0 = f.1.min(s.1); + let y1 = f.1.max(s.1); + + (x0..=x1).flat_map(|x| { + core::iter::repeat(x).zip(y0..=y1) + }).all(|(x, y)| grid[y*grid_width+x] != Cell::Empty) + }) .collect(); rects.sort_by_key(|(_, _, a)| *a); @@ -26,3 +107,32 @@ fn main() { println!("Largest: {:?}", rects.last().unwrap()); } + +fn print_grid(grid: &[Cell], width: usize, height: usize) { + if !PRINT { + return; + } + + for y in 0..height { + for x in 0..width { + match grid[y*width+x] { + Cell::Empty => print!("."), + Cell::Red => print!("#"), + Cell::Green => print!("X"), + }; + } + println!(); + } +} + +fn line_point_iter(start: (usize, usize), end: (usize, usize)) -> Box> { + if start.0 == end.0 { + let s = start.1.min(end.1); + let e = start.1.max(end.1); + Box::new(core::iter::repeat(start.0).zip(s..e).skip(1)) + } else { + let s = start.0.min(end.0); + let e = start.0.max(end.0); + Box::new((s..e).zip(core::iter::repeat(start.1)).skip(1)) + } +}