day(16): add solution
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
57d3761793
commit
fffaaf0637
2 changed files with 132 additions and 0 deletions
10
samples/day16.txt
Normal file
10
samples/day16.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.|...\....
|
||||||
|
|.-.\.....
|
||||||
|
.....|-...
|
||||||
|
........|.
|
||||||
|
..........
|
||||||
|
.........\
|
||||||
|
..../.\\..
|
||||||
|
.-.-/..|..
|
||||||
|
.|....-|.\
|
||||||
|
..//.|....
|
122
src/bin/day16.rs
Normal file
122
src/bin/day16.rs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
|
use aoc_2023::*;
|
||||||
|
|
||||||
|
type Output1 = usize;
|
||||||
|
type Output2 = Output1;
|
||||||
|
|
||||||
|
type Position = Vector2D<isize>;
|
||||||
|
|
||||||
|
fn direction(d: &Position) -> i32 {
|
||||||
|
match (d.x(), d.y()) {
|
||||||
|
(1, _) => 1,
|
||||||
|
(_, 1) => 2,
|
||||||
|
(-1, _) => 4,
|
||||||
|
(_, -1) => 8,
|
||||||
|
_ => unreachable!("invalid direction"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next(c: char, d: Position) -> Vec<Position> {
|
||||||
|
match c {
|
||||||
|
'|' if d.x() != 0 => vec![Vector2D::new(0, 1), Vector2D::new(0, -1)],
|
||||||
|
'-' if d.y() != 0 => vec![Vector2D::new(1, 0), Vector2D::new(-1, 0)],
|
||||||
|
'/' => vec![Vector2D::new(-d.y(), -d.x())],
|
||||||
|
'\\' => vec![Vector2D::new(d.y(), d.x())],
|
||||||
|
_ => vec![d],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn draw_energized(map: &[Vec<i32>]) {
|
||||||
|
// let mut formatted = String::new();
|
||||||
|
|
||||||
|
// for row in map {
|
||||||
|
// for &c in row {
|
||||||
|
// formatted += if c != 0 { "#" } else { "." };
|
||||||
|
// }
|
||||||
|
// formatted += "\n";
|
||||||
|
// }
|
||||||
|
|
||||||
|
// debug!("Energized:\n{}", formatted);
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct Day16 {
|
||||||
|
map: Vec<Vec<char>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Day16 {
|
||||||
|
fn solve(&self, start_pos: Position, start_dir: Position) -> usize {
|
||||||
|
let mut visited = vec![vec![0; self.map[0].len()]; self.map.len()];
|
||||||
|
|
||||||
|
let mut q: VecDeque<(Position, Position)> = VecDeque::new();
|
||||||
|
q.push_back((start_pos, start_dir));
|
||||||
|
visited[start_pos] |= direction(&start_dir);
|
||||||
|
|
||||||
|
while let Some((p, d)) = q.pop_front() {
|
||||||
|
for dp in next(self.map[p], d) {
|
||||||
|
if !in_range(&self.map, &(p + dp)) || visited[p + dp] & direction(&dp) != 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
visited[p + dp] |= direction(&dp);
|
||||||
|
q.push_back((p + dp, dp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw_energized(&visited);
|
||||||
|
|
||||||
|
visited
|
||||||
|
.iter()
|
||||||
|
.map(|row| row.iter().filter(|&&c| c != 0).count())
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Solution<Output1, Output2> for Day16 {
|
||||||
|
fn new<P: AsRef<Path>>(pathname: P) -> Self {
|
||||||
|
Self {
|
||||||
|
map: file_to_string(pathname)
|
||||||
|
.lines()
|
||||||
|
.map(|l| l.chars().collect())
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_1(&mut self) -> Output1 {
|
||||||
|
self.solve(Vector2D::new(0, 0), Vector2D::new(1, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_2(&mut self) -> Output2 {
|
||||||
|
(0..self.map.len())
|
||||||
|
.into_par_iter()
|
||||||
|
.flat_map(|y| {
|
||||||
|
vec![
|
||||||
|
(Vector2D::new(0, y as isize), Vector2D::new(1, 0)),
|
||||||
|
(
|
||||||
|
Vector2D::new(self.map[y].len() as isize - 1, y as isize),
|
||||||
|
Vector2D::new(-1, 0),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.chain((0..self.map[0].len()).into_par_iter().flat_map(|x| {
|
||||||
|
vec![
|
||||||
|
(Vector2D::new(x as isize, 0), Vector2D::new(0, 1)),
|
||||||
|
(
|
||||||
|
Vector2D::new(x as isize, self.map.len() as isize - 1),
|
||||||
|
Vector2D::new(0, -1),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}))
|
||||||
|
.map(|(start_pos, start_dir)| self.solve(start_pos, start_dir))
|
||||||
|
.max()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
Day16::main()
|
||||||
|
}
|
||||||
|
|
||||||
|
test_sample!(day_16, Day16, 46, 51);
|
Loading…
Reference in a new issue