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