Day 16 - Part 1

Signed-off-by: Anthony Oteri <anthony.oteri@gmail.com>
This commit is contained in:
Anthony Oteri
2023-12-18 12:34:29 -05:00
parent 5b5da8e223
commit 5c5bb4f8d8
10 changed files with 500 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
[package]
name = "day-16"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
itertools = { workspace = true }
nom = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
miette = { workspace = true }
thiserror = { workspace = true }
dhat = { workspace = true }
glam = { workspace = true }
[dev-dependencies]
divan = { workspace = true }
env_logger = { workspace = true }
test-log = { workspace = true }
[[bench]]
name = "day-16"
path = "benches/benchmark.rs"
harness = false
[features]
dhat-heap = []
+15
View File
@@ -0,0 +1,15 @@
use day_16::*;
fn main() {
divan::main();
}
#[divan::bench]
fn part1() {
part1::process(divan::black_box(include_str!("../input.txt"))).unwrap();
}
#[divan::bench]
fn part2() {
part2::process(divan::black_box(include_str!("../input.txt"))).unwrap();
}
+110
View File
@@ -0,0 +1,110 @@
\.\............/........|............/.-....................|............|.......-..............//....../../..
......\.-/..|...............-...-\......../.............-.../.............../........-................../../..
.........\..\......................................................../\.......\.............................-.
....|.........-..................|..../....-......................................|.../...............|.../...
.....|...|..-....|................/............./......./............../|.......|.....|.................../...
.........-............../.|.-...\..........................|..................//............-\......|.........
.........|...................||.........-.|/.......---...-...........\........\.-...\..../......|.............
.......|-................................................................./........../..../...................
......-......|......././...............................\.....\.........|...........|..\-............|\........
|...\.............................-...\\-.................|................................-.........|........
...\....|.|........................-.........................\..|............................-....|...........
\.........|..|./....................../..........-......|...-....................\....-../...\.-.....|/.......
......\./................|...................-....../..................................|.......-....-.........
......-.........................................|....\..................../-./-.......|........./.............
................|...|...\....\....-....//........./...../.....-..............|\.|..\.........\......./\....\.\
.\...|.....|......./....-...........|.............-..\...-..-....................|.../.....-...........--.....
......................................-................../..............\.\\........../.../................\..
.-..........|..|......................|....|.-|.....................-..../............|......./..../..\/.-.\..
..\..\.............../-......-................-......................................\....../......|..........
.........\.....\.......................................-../........./-....-.................\....../..../.....
......-..\..-.............|...................|....../.......\../........../.....-............................
.............|../.\...\....|...............|.........../..|-....../........../..../|.|.\........|........\..|.
..\............|...../...................\......................./...-.......-..........................-.....
....|......................|......../.|.\.../......|...|..-.....................|................../..\.......
.....................................................-................/\..-....|..........................-.\.
................../...\..........\...........\............................................./.../.........|.|..
.....-......................................./....-........|.-........................|.........\.....\.......
...............\/\..........|.|................................|.\......\......\............|...-.............
..................................\.......-.........|-........../...........\\..\.|../......|........\..|.....
..............-...........\.....\\./......................./...-...........-..........................././....
...-..............-..........................\..........|...........-/........../.../...|.....................
...\..............-......./-...........|............./.......-./........-..-....|......./\.-.......\./........
.........|......././..\.-......./............-....-..................|....-......../........-.........\.......
....|.........................../....................-..................-...\|............................|...
.-........-...........|..............................|.........................................\......-......-
............./......../..-....\...............................././.......|................................|...
.|\../......-./........./...............-./..............\../..............|....|........./...................
..................................................|............................-..............................
.............-...................\.......|........|.............../......-....|......../.../.-...\|...........
.................../..............-|........................|.............\..\.........................././...
...../.........../..-.......|........../.......|........................./......|......./..........|..........
../...-........../...........................-.|..\../..................\.....-...........|...................
.........\.......-.......-.\.|......|.......||......|.\....-...-.................-..........-..\..............
................................\./.......\/............-................./.....\......../....................
/...........-......|..|....../.....\.........|.....................................\...................|....-.
...........\.............../.......\......................................................................\..-
....../...................-..................|-\......................-..................\....................
/............./...........|.....|............/.................................-....................-......\|.
...............\..|..............|............\../.../..........................\\................|......./...
....--/............|......|......-........-...../........./.........../-..\..|........-.......................
|.-....-.........................|../................\................../......\..../.\..|...../.../|.........
....................................../.........\........-....................../.-..-.\.....././.../.....\..\
......\...../............./................-...........\.................../.....-../......-..................
....../............../...........|......|..................................|...................|..............
......-../.../.|.........././..........\.......\........./......|..............\.................-.........../
...../...|........//...../.................\................../.\.............-............/.........../......
..............-.....|................\................/.........|.....\.......\....................\.....\....
..........|..........-.../..................\.-.......................................\..-.........|..........
....|..................-.....|..................|...........-......./.....-......../...|........\....\-.|.....
.......................-......./......................./.-.-.........|.....|.................|................
...|................/......-.....|....-..-.........-|....|..................../.../....-......\.......-......\
............-.............................-...................../..............|.|.......-....................
-....-..............|................./......../.\............./../............../..-...-...........|.........
.|............|..........-................./................|.....................|./....\......./.....\......
..........|\.|...................-.............\......|..-..\.......\..........\........|......-.../........\.
\.......\....................\..............|................................|..............-.../.............
......../-....................|...............-........................\................\..............-......
...|..-.............//.-.............../........-........../..|.............\|../....................-........
..../.\.-.-|.....\.-|..../.....\..|.........../........................-.....................-..........|.....
...../-..........\.........-....................\.............................\............|-..\..........|...
...-...../....................../-......\...|.....-........................../.|.........|.......\..\.....\../
...................\...../......................./...-.....\.-.........-...../.|...................|......./..
../.....|..|..\.........|.../.................../..-............\../........\.....\.....................\.....
.........................../...\.|........\...||..........\......\.-....|.........\-..\.......................
../.........|............................/../-||..............|-........\............\....\.\................|
../....|....................|.....|-.......|.................../...\.-.\.............-.................-......
....|..............................................................-|.........................................
..................\-.\/.........|../|....../|..\...-...\.........|/............./...\...\.....................
.\.........-../....|-......................./................/\..\........................................./..
./......................-...............|...............|................-.......................\............
................\..........././............................-....\/..........-.../../....|.........-....|...../
.-..-..|\..\/........\./....|.......................\.........../.....|......./-.-..../..../..................
\.....|........................../.|...../.-...............|.../\...|.........|.\|....../.-......|............
.........-|............./..../.\.|//.......-....-...........\.........-..-.........\....\..........|..........
....................|.......-../.....\-..........\................-..................\.-........|.............
.....|.\-........................./........................................../.......-.\....-......../........
...................|..............\..|/................................|/..../........../..|.................|
.......\...|./......../..........-............-....|...........-/.\...-......./....\......./........\....../..
...\............\..........\../................./....-......|..........................................\......
............|......|......../.............\...|.....................\.\\......................................
-.-.-......\.......|..........-.|.....|\....\/..............-/..........|............|......./.........-......
......................../...|................./......\............../..............-/.......\.....\\..........
...|.|.-..-./..................../................................-....\|........./...-..|........\......-....
....\....-../.........|....|........-./..\../...|...../-.|.|....\................................./...|......-
..............\../..............|.|................\......./.............../.\......|.....|..\...../....../...
............|....\......|........|.......\.................................................../.-..............
.|............|...\....................../............................................\.......|.-.-...........
.....-.\|......\.............|............|....-.........\....|.............................../....\....-.|...
............|./.........................\...|..............................\...|..|..............|...-........
.-.....|..................|....-.............-..\..-...............-....-..................-..................
..\......-.-./..................................-............\........./........-.-.............-............-
..../.\--...............//..................................||................\.................|......|......
..|./...\......................|.........../........\.....-....-.................................../-....\....
.........-........\..............................|.......|......../...........|....../......|..\.|..../.......
....../....-....|\............|.....|..\../||....................................\.....................-......
.....\.....--...././......................-........\\............-...............\....-....|................./
........./........../...-................/...........-............................................-........./.
.........-..-...|/..\.........................\............\..-........-.........-...............\......|./.-.
|......................-.....-..-.........../-..................|.....|.........\./........./...-/............
..............-...........|-....-.../.............-........./...../.................../.......--.|....-..../..
+21
View File
@@ -0,0 +1,21 @@
use day_16::part1::process;
use miette::Context;
#[cfg(feature = "dhat-heap")]
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
#[tracing::instrument]
fn main() -> miette::Result<()> {
#[cfg(feature = "dhat-heap")]
let _profiler = dhat::Profiler::new_heap();
#[cfg(not(feature = "dhat-heap"))]
tracing_subscriber::fmt::init();
let file = include_str!("../../input.txt");
let result = process(file).context("process part 1")?;
println!("{}", result);
Ok(())
}
+21
View File
@@ -0,0 +1,21 @@
use day_16::part2::process;
use miette::Context;
#[cfg(feature = "dhat-heap")]
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;
#[tracing::instrument]
fn main() -> miette::Result<()> {
#[cfg(feature = "dhat-heap")]
let _profiler = dhat::Profiler::new_heap();
#[cfg(not(feature = "dhat-heap"))]
tracing_subscriber::fmt::init();
let file = include_str!("../../input.txt");
let result = process(file).context("process part 1")?;
println!("{}", result);
Ok(())
}
+9
View File
@@ -0,0 +1,9 @@
use miette::Diagnostic;
use thiserror::Error;
#[derive(Error, Diagnostic, Debug)]
pub enum AocError {
#[error(transparent)]
#[diagnostic(code(aoc::io_error))]
IoError(#[from] std::io::Error),
}
+4
View File
@@ -0,0 +1,4 @@
pub mod error;
pub mod part1;
pub mod part2;
+263
View File
@@ -0,0 +1,263 @@
use crate::error::AocError;
use glam::IVec2;
use itertools::Itertools;
use nom::bytes::complete::is_a;
use nom::character::complete::line_ending;
use nom::multi::separated_list1;
use nom::IResult;
use std::collections::HashMap;
use std::collections::HashSet;
#[derive(Debug, Clone)]
enum Tile {
Empty,
RightMirror,
LeftMirror,
HorizontalSplit,
VerticalSplit,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
enum Direction {
North,
South,
East,
West,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
struct Beam {
direction: Direction,
position: IVec2,
}
fn parse(input: &str) -> IResult<&str, HashMap<IVec2, Tile>> {
let (input, rows) = separated_list1(line_ending, is_a(r".|\/-"))(input)?;
let grid = rows
.into_iter()
.enumerate()
.flat_map(|(y, row)| {
row.chars().enumerate().map(move |(x, tile)| {
let position = IVec2::new(x as i32, y as i32);
let tile = match tile {
'.' => Tile::Empty,
'|' => Tile::VerticalSplit,
'/' => Tile::RightMirror,
'\\' => Tile::LeftMirror,
'-' => Tile::HorizontalSplit,
_ => unreachable!(),
};
(position, tile)
})
})
.collect::<HashMap<IVec2, Tile>>();
Ok((input, grid))
}
fn step(grid: &HashMap<IVec2, Tile>, beams: &Vec<Beam>) -> Vec<Beam> {
beams
.iter()
.flat_map(|beam| {
let position = match beam.direction {
Direction::North => beam.position + IVec2::new(0, -1),
Direction::South => beam.position + IVec2::new(0, 1),
Direction::East => beam.position + IVec2::new(1, 0),
Direction::West => beam.position + IVec2::new(-1, 0),
};
match grid.get(&position) {
Some(Tile::VerticalSplit) => match beam.direction {
Direction::North | Direction::South => vec![Beam {
direction: beam.direction.clone(),
position,
}],
Direction::East | Direction::West => vec![
Beam {
direction: Direction::North,
position,
},
Beam {
direction: Direction::South,
position,
},
],
},
Some(Tile::HorizontalSplit) => match beam.direction {
Direction::East | Direction::West => vec![Beam {
direction: beam.direction.clone(),
position,
}],
Direction::North | Direction::South => vec![
Beam {
direction: Direction::East,
position,
},
Beam {
direction: Direction::West,
position,
},
],
},
Some(Tile::RightMirror) => match beam.direction {
Direction::North => vec![Beam {
direction: Direction::East,
position,
}],
Direction::South => vec![Beam {
direction: Direction::West,
position,
}],
Direction::East => vec![Beam {
direction: Direction::North,
position,
}],
Direction::West => vec![Beam {
direction: Direction::South,
position,
}],
},
Some(Tile::LeftMirror) => match beam.direction {
Direction::North => vec![Beam {
direction: Direction::West,
position,
}],
Direction::South => vec![Beam {
direction: Direction::East,
position,
}],
Direction::East => vec![Beam {
direction: Direction::South,
position,
}],
Direction::West => vec![Beam {
direction: Direction::North,
position,
}],
},
Some(Tile::Empty) | None => vec![Beam {
direction: beam.direction.clone(),
position,
}],
}
.to_vec()
})
.collect_vec()
}
fn check_bounds(_grid: &HashMap<IVec2, Tile>, beams: &Vec<Beam>, boundary: &IVec2) -> Vec<Beam> {
beams
.iter()
.filter(|beam| {
beam.position.x <= boundary.x
&& beam.position.y <= boundary.y
&& beam.position.x >= 0
&& beam.position.y >= 0
})
.cloned()
.collect_vec()
}
fn check_history(beams: &Vec<Beam>, visited: &HashSet<Beam>) -> Vec<Beam> {
beams
.iter()
.filter(|beam| !visited.contains(beam))
.cloned()
.collect_vec()
}
fn visualize(grid: &HashMap<IVec2, Tile>, visited: &HashSet<Beam>) {
let boundary = grid.keys().fold(IVec2::new(0, 0), |max, position| {
IVec2::new(max.x.max(position.x), max.y.max(position.y))
});
for y in 0..=boundary.y {
for x in 0..=boundary.x {
let position = IVec2::new(x, y);
if visited.contains(&Beam {
direction: Direction::North,
position,
}) {
print!("^");
} else if visited.contains(&Beam {
direction: Direction::South,
position,
}) {
print!("v");
} else if visited.contains(&Beam {
direction: Direction::East,
position,
}) {
print!(">");
} else if visited.contains(&Beam {
direction: Direction::West,
position,
}) {
print!("<");
} else if let Some(tile) = grid.get(&position) {
match tile {
Tile::Empty => print!("."),
Tile::VerticalSplit => print!("|"),
Tile::HorizontalSplit => print!("-"),
Tile::RightMirror => print!("/"),
Tile::LeftMirror => print!("\\"),
}
} else {
print!(" ");
}
}
println!();
}
}
#[tracing::instrument]
pub fn process(input: &str) -> miette::Result<u64, AocError> {
let (input, grid) = parse(input).unwrap();
debug_assert!(input.is_empty(), "Not all input was parsed");
let boundary = grid.keys().fold(IVec2::new(0, 0), |max, position| {
IVec2::new(max.x.max(position.x), max.y.max(position.y))
});
let mut visited: HashSet<Beam> = HashSet::new();
let mut beams: Vec<Beam> = vec![Beam {
direction: Direction::East,
position: IVec2::new(-1, 0),
}];
//visited.extend(beams.iter().cloned());
loop {
beams = step(&grid, &beams);
beams = check_bounds(&grid, &beams, &boundary);
beams = check_history(&beams, &visited);
visited.extend(beams.iter().cloned());
if beams.is_empty() {
break;
}
}
#[cfg(test)]
visualize(&grid, &visited);
let energized = visited
.iter()
.map(|node| node.position)
.collect::<HashSet<IVec2>>();
Ok(energized.len() as u64)
}
#[cfg(test)]
mod tests {
use super::*;
#[test_log::test]
fn test_process() -> miette::Result<()> {
let input = include_str!("../test-input.txt");
assert_eq!(46, process(input)?);
Ok(())
}
}
+18
View File
@@ -0,0 +1,18 @@
use crate::error::AocError;
#[tracing::instrument]
pub fn process(input: &str) -> miette::Result<u64, AocError> {
Ok(0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test_log::test]
fn test_process() -> miette::Result<()> {
let input = include_str!("../test-input.txt");
assert_eq!(0, process(input)?);
Ok(())
}
}
+10
View File
@@ -0,0 +1,10 @@
.|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|....