mirror of
https://github.com/anthonyoteri/advent-of-code-2023.git
synced 2026-06-05 18:46:54 -04:00
@@ -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 = []
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
\.\............/........|............/.-....................|............|.......-..............//....../../..
|
||||
......\.-/..|...............-...-\......../.............-.../.............../........-................../../..
|
||||
.........\..\......................................................../\.......\.............................-.
|
||||
....|.........-..................|..../....-......................................|.../...............|.../...
|
||||
.....|...|..-....|................/............./......./............../|.......|.....|.................../...
|
||||
.........-............../.|.-...\..........................|..................//............-\......|.........
|
||||
.........|...................||.........-.|/.......---...-...........\........\.-...\..../......|.............
|
||||
.......|-................................................................./........../..../...................
|
||||
......-......|......././...............................\.....\.........|...........|..\-............|\........
|
||||
|...\.............................-...\\-.................|................................-.........|........
|
||||
...\....|.|........................-.........................\..|............................-....|...........
|
||||
\.........|..|./....................../..........-......|...-....................\....-../...\.-.....|/.......
|
||||
......\./................|...................-....../..................................|.......-....-.........
|
||||
......-.........................................|....\..................../-./-.......|........./.............
|
||||
................|...|...\....\....-....//........./...../.....-..............|\.|..\.........\......./\....\.\
|
||||
.\...|.....|......./....-...........|.............-..\...-..-....................|.../.....-...........--.....
|
||||
......................................-................../..............\.\\........../.../................\..
|
||||
.-..........|..|......................|....|.-|.....................-..../............|......./..../..\/.-.\..
|
||||
..\..\.............../-......-................-......................................\....../......|..........
|
||||
.........\.....\.......................................-../........./-....-.................\....../..../.....
|
||||
......-..\..-.............|...................|....../.......\../........../.....-............................
|
||||
.............|../.\...\....|...............|.........../..|-....../........../..../|.|.\........|........\..|.
|
||||
..\............|...../...................\......................./...-.......-..........................-.....
|
||||
....|......................|......../.|.\.../......|...|..-.....................|................../..\.......
|
||||
.....................................................-................/\..-....|..........................-.\.
|
||||
................../...\..........\...........\............................................./.../.........|.|..
|
||||
.....-......................................./....-........|.-........................|.........\.....\.......
|
||||
...............\/\..........|.|................................|.\......\......\............|...-.............
|
||||
..................................\.......-.........|-........../...........\\..\.|../......|........\..|.....
|
||||
..............-...........\.....\\./......................./...-...........-..........................././....
|
||||
...-..............-..........................\..........|...........-/........../.../...|.....................
|
||||
...\..............-......./-...........|............./.......-./........-..-....|......./\.-.......\./........
|
||||
.........|......././..\.-......./............-....-..................|....-......../........-.........\.......
|
||||
....|.........................../....................-..................-...\|............................|...
|
||||
.-........-...........|..............................|.........................................\......-......-
|
||||
............./......../..-....\...............................././.......|................................|...
|
||||
.|\../......-./........./...............-./..............\../..............|....|........./...................
|
||||
..................................................|............................-..............................
|
||||
.............-...................\.......|........|.............../......-....|......../.../.-...\|...........
|
||||
.................../..............-|........................|.............\..\.........................././...
|
||||
...../.........../..-.......|........../.......|........................./......|......./..........|..........
|
||||
../...-........../...........................-.|..\../..................\.....-...........|...................
|
||||
.........\.......-.......-.\.|......|.......||......|.\....-...-.................-..........-..\..............
|
||||
................................\./.......\/............-................./.....\......../....................
|
||||
/...........-......|..|....../.....\.........|.....................................\...................|....-.
|
||||
...........\.............../.......\......................................................................\..-
|
||||
....../...................-..................|-\......................-..................\....................
|
||||
/............./...........|.....|............/.................................-....................-......\|.
|
||||
...............\..|..............|............\../.../..........................\\................|......./...
|
||||
....--/............|......|......-........-...../........./.........../-..\..|........-.......................
|
||||
|.-....-.........................|../................\................../......\..../.\..|...../.../|.........
|
||||
....................................../.........\........-....................../.-..-.\.....././.../.....\..\
|
||||
......\...../............./................-...........\.................../.....-../......-..................
|
||||
....../............../...........|......|..................................|...................|..............
|
||||
......-../.../.|.........././..........\.......\........./......|..............\.................-.........../
|
||||
...../...|........//...../.................\................../.\.............-............/.........../......
|
||||
..............-.....|................\................/.........|.....\.......\....................\.....\....
|
||||
..........|..........-.../..................\.-.......................................\..-.........|..........
|
||||
....|..................-.....|..................|...........-......./.....-......../...|........\....\-.|.....
|
||||
.......................-......./......................./.-.-.........|.....|.................|................
|
||||
...|................/......-.....|....-..-.........-|....|..................../.../....-......\.......-......\
|
||||
............-.............................-...................../..............|.|.......-....................
|
||||
-....-..............|................./......../.\............./../............../..-...-...........|.........
|
||||
.|............|..........-................./................|.....................|./....\......./.....\......
|
||||
..........|\.|...................-.............\......|..-..\.......\..........\........|......-.../........\.
|
||||
\.......\....................\..............|................................|..............-.../.............
|
||||
......../-....................|...............-........................\................\..............-......
|
||||
...|..-.............//.-.............../........-........../..|.............\|../....................-........
|
||||
..../.\.-.-|.....\.-|..../.....\..|.........../........................-.....................-..........|.....
|
||||
...../-..........\.........-....................\.............................\............|-..\..........|...
|
||||
...-...../....................../-......\...|.....-........................../.|.........|.......\..\.....\../
|
||||
...................\...../......................./...-.....\.-.........-...../.|...................|......./..
|
||||
../.....|..|..\.........|.../.................../..-............\../........\.....\.....................\.....
|
||||
.........................../...\.|........\...||..........\......\.-....|.........\-..\.......................
|
||||
../.........|............................/../-||..............|-........\............\....\.\................|
|
||||
../....|....................|.....|-.......|.................../...\.-.\.............-.................-......
|
||||
....|..............................................................-|.........................................
|
||||
..................\-.\/.........|../|....../|..\...-...\.........|/............./...\...\.....................
|
||||
.\.........-../....|-......................./................/\..\........................................./..
|
||||
./......................-...............|...............|................-.......................\............
|
||||
................\..........././............................-....\/..........-.../../....|.........-....|...../
|
||||
.-..-..|\..\/........\./....|.......................\.........../.....|......./-.-..../..../..................
|
||||
\.....|........................../.|...../.-...............|.../\...|.........|.\|....../.-......|............
|
||||
.........-|............./..../.\.|//.......-....-...........\.........-..-.........\....\..........|..........
|
||||
....................|.......-../.....\-..........\................-..................\.-........|.............
|
||||
.....|.\-........................./........................................../.......-.\....-......../........
|
||||
...................|..............\..|/................................|/..../........../..|.................|
|
||||
.......\...|./......../..........-............-....|...........-/.\...-......./....\......./........\....../..
|
||||
...\............\..........\../................./....-......|..........................................\......
|
||||
............|......|......../.............\...|.....................\.\\......................................
|
||||
-.-.-......\.......|..........-.|.....|\....\/..............-/..........|............|......./.........-......
|
||||
......................../...|................./......\............../..............-/.......\.....\\..........
|
||||
...|.|.-..-./..................../................................-....\|........./...-..|........\......-....
|
||||
....\....-../.........|....|........-./..\../...|...../-.|.|....\................................./...|......-
|
||||
..............\../..............|.|................\......./.............../.\......|.....|..\...../....../...
|
||||
............|....\......|........|.......\.................................................../.-..............
|
||||
.|............|...\....................../............................................\.......|.-.-...........
|
||||
.....-.\|......\.............|............|....-.........\....|.............................../....\....-.|...
|
||||
............|./.........................\...|..............................\...|..|..............|...-........
|
||||
.-.....|..................|....-.............-..\..-...............-....-..................-..................
|
||||
..\......-.-./..................................-............\........./........-.-.............-............-
|
||||
..../.\--...............//..................................||................\.................|......|......
|
||||
..|./...\......................|.........../........\.....-....-.................................../-....\....
|
||||
.........-........\..............................|.......|......../...........|....../......|..\.|..../.......
|
||||
....../....-....|\............|.....|..\../||....................................\.....................-......
|
||||
.....\.....--...././......................-........\\............-...............\....-....|................./
|
||||
........./........../...-................/...........-............................................-........./.
|
||||
.........-..-...|/..\.........................\............\..-........-.........-...............\......|./.-.
|
||||
|......................-.....-..-.........../-..................|.....|.........\./........./...-/............
|
||||
..............-...........|-....-.../.............-........./...../.................../.......--.|....-..../..
|
||||
@@ -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(())
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
pub mod error;
|
||||
|
||||
pub mod part1;
|
||||
pub mod part2;
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
.|...\....
|
||||
|.-.\.....
|
||||
.....|-...
|
||||
........|.
|
||||
..........
|
||||
.........\
|
||||
..../.\\..
|
||||
.-.-/..|..
|
||||
.|....-|.\
|
||||
..//.|....
|
||||
Reference in New Issue
Block a user