1
0
Fork 0

day(18): add part 1

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2023-12-18 14:16:58 +01:00
parent 2b1ef62387
commit aa100460a2
Signed by: mfocko
GPG key ID: 7C47D46246790496
4 changed files with 139 additions and 0 deletions

1
samples/day18.txt Symbolic link
View file

@ -0,0 +1 @@
day18_1.txt

14
samples/day18_1.txt Normal file
View 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
View 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
View 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);