diff --git a/src/bin/day18.rs b/src/bin/day18.rs index 5318213..e98ed73 100644 --- a/src/bin/day18.rs +++ b/src/bin/day18.rs @@ -1,8 +1,9 @@ use std::{collections::VecDeque, str::FromStr}; -use aoc_2023::*; use itertools::iproduct; +use aoc_2023::*; + type Output1 = usize; type Output2 = Output1; @@ -70,6 +71,52 @@ fn flood_fill(m: &mut [Vec], start: Vector2D, original: char, fill: filled_in } +fn solve(plan: &[Step]) -> usize { + let (min_x, max_x, min_y, max_y) = plan.iter().fold((0, 0, 0, 0), |dimensions, s| { + let (mut lx, mut ux, mut ly, mut uy) = dimensions; + + match s._direction { + (0, 1) => uy += s.count, + (0, -1) => ly += s.count, + (1, 0) => ux += s.count, + (-1, 0) => lx += s.count, + _ => unreachable!(), + } + + (lx, ux, ly, uy) + }); + let (width, height) = (min_x + max_x + 1, min_y + max_y + 1); + debug!("Dimensions: {}×{}", width, height); + + let mut map = vec![vec!['.'; width as usize]; height as usize]; + let mut position = Vector2D::new(min_x, min_y); + + for s in plan.iter() { + let direction = s.direction(); + for _ in 0..s.count { + map[position] = '#'; + position = position + direction; + } + } + + flood_fill(&mut map, Vector2D::new(0, 0), '.', '+'); + + while let Some((y, x)) = + iproduct!(0..height as usize, 0..width as usize).find(|&(y, x)| map[y][x] == '.') + { + flood_fill(&mut map, Vector2D::new(x as isize, y as isize), '.', '#'); + } + + // debug!( + // "Map:\n{}", + // map.iter().map(|r| r.iter().collect::()).join("\n") + // ); + + map.iter() + .map(|r| r.iter().filter(|&&c| c == '#').count()) + .sum() +} + struct Day18 { plan: Vec, } @@ -81,62 +128,34 @@ impl Solution for Day18 { } fn part_1(&mut self) -> Output1 { - let (min_x, max_x, min_y, max_y) = self.plan.iter().fold((0, 0, 0, 0), |dimensions, s| { - let (mut lx, mut ux, mut ly, mut uy) = dimensions; - - match s._direction { - (0, 1) => uy += s.count, - (0, -1) => ly += s.count, - (1, 0) => ux += s.count, - (-1, 0) => lx += s.count, - _ => unreachable!(), - } - - (lx, ux, ly, uy) - }); - let (width, height) = (min_x + max_x + 1, min_y + max_y + 1); - - debug!("Dimensions: {}×{}", width, height); - - let mut map = vec![vec!['.'; width as usize]; height as usize]; - let mut position = Vector2D::new(min_x, min_y); - // debug!("Initial position: {:?}", position); - - // let (mut min_x, mut max_x, mut min_y, mut max_y) = (isize::MAX, isize::MIN, isize::MAX, isize::MIN); - for s in &self.plan { - let direction = s.direction(); - for _ in 0..s.count { - // min_x = std::cmp::min(min_x, position.x()); - // max_x = std::cmp::max(max_x, position.x()); - // min_y = std::cmp::min(min_y, position.y()); - // max_y = std::cmp::max(max_y, position.y()); - - map[position] = '#'; - position = position + direction; - } - } - // debug!("x ∈ ⟨{} ; {}⟩\ty ∈ ⟨{} ; {}⟩", min_x, max_x, min_y, max_y); - - flood_fill(&mut map, Vector2D::new(0, 0), '.', '+'); - - while let Some((y, x)) = - iproduct!(0..height as usize, 0..width as usize).find(|&(y, x)| map[y][x] == '.') - { - flood_fill(&mut map, Vector2D::new(x as isize, y as isize), '.', '#'); - } - - // debug!( - // "Map:\n{}", - // map.iter().map(|r| r.iter().collect::()).join("\n") - // ); - - map.iter() - .map(|r| r.iter().filter(|&&c| c == '#').count()) - .sum() + solve(&self.plan) } fn part_2(&mut self) -> Output2 { - todo!() + solve( + &self + .plan + .iter() + .map(|s| { + let new_step = s.color.trim_matches('#'); + let number = isize::from_str_radix(new_step, 16).unwrap(); + + let _direction = match number % 16 { + 0 => (1, 0), + 1 => (0, 1), + 2 => (-1, 0), + 3 => (0, -1), + _ => unreachable!(), + }; + + Step { + _direction, + count: number >> 8, + color: String::new(), + } + }) + .collect_vec(), + ) } }