day(18): use tricks from day(10) to solve part 2
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
69287d8a30
commit
9a5d814792
1 changed files with 31 additions and 56 deletions
|
@ -1,6 +1,7 @@
|
||||||
use std::{collections::VecDeque, str::FromStr};
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
use itertools::iproduct;
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
use aoc_2023::*;
|
use aoc_2023::*;
|
||||||
|
|
||||||
|
@ -48,73 +49,47 @@ impl Step {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flood_fill(m: &mut [Vec<char>], start: Vector2D<isize>, original: char, fill: char) -> usize {
|
fn dir_to_u8(u: (isize, isize)) -> u8 {
|
||||||
let mut filled_in = 0;
|
match u {
|
||||||
|
(0, 1) => 1,
|
||||||
let mut q: VecDeque<Vector2D<isize>> = VecDeque::from([start]);
|
(0, -1) => 2,
|
||||||
m[start] = fill;
|
(1, 0) => 4,
|
||||||
filled_in += 1;
|
(-1, 0) => 8,
|
||||||
|
_ => unreachable!(),
|
||||||
while let Some(p) = q.pop_front() {
|
|
||||||
for (dx, dy) in [(0, 1), (0, -1), (1, 0), (-1, 0)] {
|
|
||||||
let neighbour = p + Vector2D::new(dx, dy);
|
|
||||||
if !in_range(m, &neighbour) || m[neighbour] != original {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
q.push_back(neighbour);
|
fn opposite(u: (isize, isize)) -> (isize, isize) {
|
||||||
m[neighbour] = fill;
|
(-u.0, -u.1)
|
||||||
filled_in += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filled_in
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve(plan: &[Step]) -> usize {
|
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 hole: BTreeMap<Vector2D<isize>, u8> = BTreeMap::new();
|
||||||
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);
|
|
||||||
|
|
||||||
|
let mut position = Vector2D::new(0, 0);
|
||||||
for s in plan.iter() {
|
for s in plan.iter() {
|
||||||
let direction = s.direction();
|
let direction = s.direction();
|
||||||
|
|
||||||
for _ in 0..s.count {
|
for _ in 0..s.count {
|
||||||
map[position] = '#';
|
*hole.entry(position).or_insert(0) |= dir_to_u8(s._direction);
|
||||||
position = position + direction;
|
position = position + direction;
|
||||||
|
*hole.entry(position).or_insert(0) |= dir_to_u8(opposite(s._direction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flood_fill(&mut map, Vector2D::new(0, 0), '.', '+');
|
let mut counter = 0;
|
||||||
|
let mut in_between = 0;
|
||||||
while let Some((y, x)) =
|
let mut x_prev = 0;
|
||||||
iproduct!(0..height as usize, 0..width as usize).find(|&(y, x)| map[y][x] == '.')
|
for (v, directions) in hole.iter() {
|
||||||
{
|
if in_between != 0 && x_prev < v.x() {
|
||||||
flood_fill(&mut map, Vector2D::new(x as isize, y as isize), '.', '#');
|
// debug!("{} {}", v.x(), x_prev);
|
||||||
|
counter += (v.x() - x_prev) as usize - 1;
|
||||||
|
}
|
||||||
|
in_between ^= directions & 3;
|
||||||
|
x_prev = v.x();
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug!(
|
counter + hole.len()
|
||||||
// "Map:\n{}",
|
|
||||||
// map.iter().map(|r| r.iter().collect::<String>()).join("\n")
|
|
||||||
// );
|
|
||||||
|
|
||||||
map.iter()
|
|
||||||
.map(|r| r.iter().filter(|&&c| c == '#').count())
|
|
||||||
.sum()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Day18 {
|
struct Day18 {
|
||||||
|
@ -150,7 +125,7 @@ impl Solution<Output1, Output2> for Day18 {
|
||||||
|
|
||||||
Step {
|
Step {
|
||||||
_direction,
|
_direction,
|
||||||
count: number >> 8,
|
count: number >> 4,
|
||||||
color: String::new(),
|
color: String::new(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue