day(18): add part 1
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
2b1ef62387
commit
aa100460a2
4 changed files with 139 additions and 0 deletions
1
samples/day18.txt
Symbolic link
1
samples/day18.txt
Symbolic link
|
@ -0,0 +1 @@
|
|||
day18_1.txt
|
14
samples/day18_1.txt
Normal file
14
samples/day18_1.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
R 6 (#70c710)
|
||||
D 5 (#0dc571)
|
||||
L 2 (#5713f0)
|
||||
D 2 (#d2c081)
|
||||
R 2 (#59c680)
|
||||
D 2 (#411b91)
|
||||
L 5 (#8ceee2)
|
||||
U 2 (#caa173)
|
||||
L 1 (#1b58a2)
|
||||
U 2 (#caa171)
|
||||
R 2 (#7807d2)
|
||||
U 3 (#a77fa3)
|
||||
L 2 (#015232)
|
||||
U 2 (#7a21e3)
|
6
samples/day18_2.txt
Normal file
6
samples/day18_2.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
R 3 (#70c710)
|
||||
D 1 (#0dc571)
|
||||
R 3 (#5713f0)
|
||||
U 1 (#d2c081)
|
||||
R 3 (#59c680)
|
||||
D 2 (#411b91)
|
118
src/bin/day18.rs
Normal file
118
src/bin/day18.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
use std::{collections::VecDeque, str::FromStr};
|
||||
|
||||
use aoc_2023::*;
|
||||
use itertools::iproduct;
|
||||
|
||||
type Output1 = usize;
|
||||
type Output2 = Output1;
|
||||
|
||||
struct Step {
|
||||
direction: Vector2D<isize>,
|
||||
count: isize,
|
||||
color: String,
|
||||
}
|
||||
|
||||
impl FromStr for Step {
|
||||
type Err = &'static str;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut parts = s.split_ascii_whitespace();
|
||||
|
||||
let direction = match parts.next().unwrap() {
|
||||
"U" => Vector2D::new(0, -1),
|
||||
"D" => Vector2D::new(0, 1),
|
||||
"L" => Vector2D::new(-1, 0),
|
||||
"R" => Vector2D::new(1, 0),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let count = parts.next().unwrap().parse().unwrap();
|
||||
let color = parts
|
||||
.next()
|
||||
.unwrap()
|
||||
.trim_matches(|c| c == '(' || c == ')')
|
||||
.to_owned();
|
||||
|
||||
Ok(Step {
|
||||
direction,
|
||||
count,
|
||||
color,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn flood_fill(m: &mut [Vec<char>], start: Vector2D<isize>, original: char, fill: char) -> usize {
|
||||
let mut filled_in = 0;
|
||||
|
||||
let mut q: VecDeque<Vector2D<isize>> = VecDeque::from([start]);
|
||||
m[start] = fill;
|
||||
filled_in += 1;
|
||||
|
||||
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);
|
||||
m[neighbour] = fill;
|
||||
filled_in += 1;
|
||||
}
|
||||
}
|
||||
|
||||
filled_in
|
||||
}
|
||||
|
||||
struct Day18 {
|
||||
plan: Vec<Step>,
|
||||
}
|
||||
impl Solution<Output1, Output2> for Day18 {
|
||||
fn new<P: AsRef<Path>>(pathname: P) -> Self {
|
||||
Self {
|
||||
plan: file_to_structs(pathname),
|
||||
}
|
||||
}
|
||||
|
||||
fn part_1(&mut self) -> Output1 {
|
||||
let n = self.plan.iter().map(|s| s.count).sum::<isize>();
|
||||
|
||||
let mut map = vec![vec!['.'; 2 * n as usize]; 2 * n as usize];
|
||||
let mut position = Vector2D::new(n, n);
|
||||
|
||||
for s in &self.plan {
|
||||
for _ in 0..s.count {
|
||||
map[position] = '#';
|
||||
position = position + s.direction;
|
||||
}
|
||||
}
|
||||
|
||||
flood_fill(&mut map, Vector2D::new(0, 0), '.', '+');
|
||||
|
||||
while let Some((y, x)) =
|
||||
iproduct!(0..2 * n as usize, 0..2 * n 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::<String>()).join("\n")
|
||||
// );
|
||||
|
||||
map.iter()
|
||||
.map(|r| r.iter().filter(|&&c| c == '#').count())
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part_2(&mut self) -> Output2 {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// Day18::run("sample")
|
||||
Day18::main()
|
||||
}
|
||||
|
||||
test_sample!(day_18, Day18, 62, 952408144115);
|
Loading…
Reference in a new issue