Day 16
This commit is contained in:
parent
d9435c84ff
commit
bebd52fcd1
|
@ -0,0 +1,110 @@
|
|||
\.......................|..-.............../../.......|...............\.\.....|..../.............|............
|
||||
........................../....../..............................-............-.-..--.........-...........\/...
|
||||
....\............../...........-...-......|.............................\...............-........-....|.......
|
||||
......\....|................./.\................/..................../.......................|..\......-......
|
||||
.................../..................-./.................../.....-...................|......\.......|\...\./.
|
||||
.....|........../....................\../..\.../.\.......-.............\...........\......|.\..-..........-...
|
||||
..../............/.....\...................../..--\........|......\....-...|.-...../......-........../........
|
||||
..............\.-............./........./....|\.......\..........|.................|.|.................-......
|
||||
.....|..........-................-.../..........-........................\.......|.........................-..
|
||||
.|.-......./....................\........-.............../..\.|.-\...........\./.................-............
|
||||
................|/............................../..-.\..................-..../../...../.../..../..........|...
|
||||
........................./.....................\..\....-....../-.....................\|.........././.-........
|
||||
...\.....................-...../|............--......-..|...../.....|......|.../.\....|.............\|.......\
|
||||
.........-...-.....|.........../...-/........|......./|............-.......-.....\.............\|....../......
|
||||
.....|...|.................|...../.............|.................../..........\|..\......|..|....-............
|
||||
...........................-.........\......\.............\...................-.....-.\.......-.....|.........
|
||||
.................-.............-......./.............-..\./......|....-..-..........-....-............\.......
|
||||
.\..\.......-......|........................\.............-.......................|.........|\.|..\......--/..
|
||||
..........-.....||--........|........-....../...........|../...-.........../.....-.\..........|.......-.......
|
||||
..........\..........|..................\.................-..../............/..........|.......-........../...
|
||||
..--......../..........-..|........./.........-...../........-.................|..\............../.....-......
|
||||
.....\.............|...../......../............./||..........................\............|...................
|
||||
..-.................-|..-....................\.................|...\.....\............./......-.......\.......
|
||||
............-../......\...../.-....-.....-....-./../......\..|..|............................|.../..|.........
|
||||
-................./................................................|...............|....|.....-.....|....../..
|
||||
...........-...................|...........\.......-..\.......-...........|..-....../........|...............|
|
||||
.........|...|-........../...-..........|.........\.....||......./....|...............\......-......\...../...
|
||||
....|.........|............\.-.......................................-.......................|.-..|.\...\.-...
|
||||
.|....|....-/....................\\..........................|........\|...|..............\..|......-.\../....
|
||||
..|.\......|..../.....|.......-....................|.\..\............/......................|.....\../../.....
|
||||
.......|\\.\/......................./.............|................../.........|.....\-.......................
|
||||
......................................../.../................\-..............-................./......\.......
|
||||
............../............/\......./........................./......|............\/..........................
|
||||
......./................|......../.........-............\.../.|....../....|...../..../......../...............
|
||||
...................|............-\........../...\.......\....\.....-.........-./....|.........................
|
||||
.....-..-\.................|\...........................|..........\........-...|.............................
|
||||
..............................-.............-.......\......................../.......\|.......|...-....-......
|
||||
\...................\..../.................\................|......-...-............./.-......................
|
||||
........................./.|./...|..\.-............|.-.....-..........\....-..../.....|.......|...............
|
||||
.................../......../..................|.|...............|.......|\.....|......|...............\/..|..
|
||||
.........|....-......../........-./..|.../..|./...................-........|..................................
|
||||
..|../............-......-.........................-..|....-................-..\....../...........|...........
|
||||
....................-...............|.../.....|..../......../...|.......\.....-.....\..............-..\.-.....
|
||||
...........\.........../............................................\......-................-.......|.....-...
|
||||
..-............./.......-\...........|-..-../............../................................../...............
|
||||
.................\.......\............../.|.......-...\............................................\.-........
|
||||
.\....|....\......|........./.....--......................................|................\..|-..............
|
||||
......../...............-..........................|...........................-.............-\.-..|..........
|
||||
.......|......|/...\........./......../.....\.........\.......................-...........\..\................
|
||||
.-..-../.............|................./../.................\........-......|.\.....||...................\|...
|
||||
/......../....\.....|-..........\..............-.....|............/\......\...//....................\...-/....
|
||||
................-...........-.-\-..........\.-./......../-................./../.\........................./...
|
||||
-.........-.....|.....-..|..|.........|...................-..........\/.-.....................................
|
||||
......./...../......\............-.|...............|..../.........|....\.................../..............|...
|
||||
...........|.......|....|...............\........................\/..\......................................\.
|
||||
......\........-.........................\..........\.............\......................\/.....\..|..........
|
||||
......\...........|.........../..-............./........................../...-......../...............\..|...
|
||||
..|............\../........../............\...|.......................-...............\-../.|...|\.....\......
|
||||
.|....\.|....-|.........\......./.................../.|........|....../.--.\.....\..............-\\.........-.
|
||||
......................./.......\...........|.\............-.....\.............\.........--......../.\..-.|../.
|
||||
......../.............../......\.\....|.............../...........................-........-......../.........
|
||||
.......|\.............|.../|/........../....\.....-....|.............-......./........\..\........\..|......-.
|
||||
.............../...........-.....\..\....-...../...|......\...........................\...|...........|/......
|
||||
.............|....../.................../..|.....................|.......|....//..............\...............
|
||||
......./....\............................-.........................-/......../|......-....|.............../...
|
||||
...........................|...................\...............................-.................|...........\
|
||||
.............................-......./..../...................\.../...........-.|......................||.....
|
||||
\....\....\...-./......../.........\................./................\...................|...........-.......
|
||||
................-.../............/\..................\.\..-....../................./..........|...............
|
||||
......../...\.......................\.......\..\......|.....|../..........\..........-.............|..........
|
||||
../.........................................-\..........-.........|-./.....-...|..|.......\........-...../../.
|
||||
.....|..........-......../|-..............|.................-...........|...\.....................\...........
|
||||
.......|..............\....\.....-............../..\\..\.......-........./.........-..|...|................../
|
||||
..........-.......-.-................../.........\\...../.....|..........\......./.|.............-...........\
|
||||
..................................-..................|...........\../\...../..../...\................/........
|
||||
...-.........................................................\.|..............\..................\............
|
||||
-.|..|...................../../.|.......\.....|.....\.\...\.........-.................................../.....
|
||||
...\./....../........\.......-.................\.........|............-.........../...........\.|.........|.\.
|
||||
..........-...\.............-.-............-.-................/.....................|........|............-...
|
||||
|......./............/..|..............\...............|.......|\................/....|.........|.........\..\
|
||||
.....\../\./.....................-.............\..................|.|.........................................
|
||||
............/......../.../.......\............/.........................\........................\............
|
||||
....../..|.............../....................-.......\................................................|.....\
|
||||
................................../.......././.......\.....|.\......-.........-..||......../........-.//......
|
||||
........................\.......|............-....-...../..............................-............-....|...-
|
||||
.....-.......|......\..|.........-....|......\......../..../.......\..........|....\.............||..\........
|
||||
..........|...........-|.......\.......-....../...../..........||.......................\............-..|.....
|
||||
.................../../..............................|....|................/........|-....|................/..
|
||||
.....................\................/............................/-........./...|.............\...|..|\.....
|
||||
.....\..\..........\......../......|.........-....-..-..|...........\....|./....\.\..\............../.........
|
||||
.......-...............-....../...........-.......................|../...............|...|.........../..../...
|
||||
.............|.../..................\..\..........-........||................\/...........-|..................
|
||||
.............-..............-\.../.................|......\...../..........\...-.....-....../................\
|
||||
.....-....................................-.........\/............../.............................|...........
|
||||
./.|../......\\..........................................|..............\|/..-\..........................\....
|
||||
...........-.........\............./....-........-....-....-.........\..\....-\...-...............--.........-
|
||||
..\.............................\............................./\..........-.............-...-./........../....
|
||||
.................../........\....|..-....|||./..............-......-./....................../..|...|..........
|
||||
......\.........../............|\...|.-................../....................|\..|..\.............-./......|.
|
||||
...........-...................-.|........................\...............|/..-...\...|/\...........|.........
|
||||
............|..../..................................\.......................\........................-........
|
||||
.\..........................|......|......../.|....................../.......\......\.............../.........
|
||||
..........-.../............/..........................|....-......................|.-................|.-......
|
||||
......../............-...|.....|......../-.....-|...|./.......-..................-\...........................
|
||||
...............\.\/.-....././................-.../..../.............../-|.....-.......|......./..--...........
|
||||
..........-\\.|-................./../..|.-.....--................../.................../.|.......-............
|
||||
..\.................-..............-...............\.....|......................./..\.....--........./..../..\
|
||||
.......-....../..............|..................\....|..|..........-.....|.|.-.........................\......
|
||||
..../..\...\....................................||.|......................................|.......\/.........-
|
||||
................\-.-.....||....\.........................-...................................................|
|
|
@ -0,0 +1,388 @@
|
|||
use std::{
|
||||
collections::VecDeque,
|
||||
fmt::{write, Debug},
|
||||
};
|
||||
|
||||
pub fn run() {
|
||||
let input = include_str!("../input/day16.txt");
|
||||
// let input = r#"
|
||||
// .|...\....
|
||||
// |.-.\.....
|
||||
// .....|-...
|
||||
// ........|.
|
||||
// ..........
|
||||
// .........\
|
||||
// ..../.\\..
|
||||
// .-.-/..|..
|
||||
// .|....-|.\
|
||||
// ..//.|....
|
||||
// "#;
|
||||
let contraption: Contraption = input.into();
|
||||
|
||||
let visited = run_beam(
|
||||
Beam {
|
||||
row: 0,
|
||||
col: -1,
|
||||
direction: Direction::Right,
|
||||
},
|
||||
&contraption,
|
||||
);
|
||||
|
||||
dbg!(visited.count());
|
||||
|
||||
dbg!(max_visited(&contraption));
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Contraption {
|
||||
tiles: Vec<Vec<Tile>>,
|
||||
width: usize,
|
||||
height: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Tile {
|
||||
Empty,
|
||||
MirrorPos,
|
||||
MirrorNeg,
|
||||
SplitterVert,
|
||||
SplitterHoriz,
|
||||
}
|
||||
|
||||
impl Tile {
|
||||
fn tile_char(&self) -> char {
|
||||
match self {
|
||||
Tile::Empty => '.',
|
||||
Tile::MirrorPos => '/',
|
||||
Tile::MirrorNeg => '\\',
|
||||
Tile::SplitterVert => '|',
|
||||
Tile::SplitterHoriz => '-',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Contraption {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Contraption(\n")?;
|
||||
for row in self.tiles.iter() {
|
||||
for tile in row {
|
||||
write!(f, "{}", tile.tile_char())?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Contraption {
|
||||
fn from(value: &str) -> Self {
|
||||
let tiles = value
|
||||
.trim()
|
||||
.lines()
|
||||
.map(|l| {
|
||||
l.trim()
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'.' => Tile::Empty,
|
||||
'/' => Tile::MirrorPos,
|
||||
'\\' => Tile::MirrorNeg,
|
||||
'|' => Tile::SplitterVert,
|
||||
'-' => Tile::SplitterHoriz,
|
||||
_ => panic!("unexpected char {:?}", c),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let width = tiles[0].len();
|
||||
let height = tiles.len();
|
||||
Self {
|
||||
tiles,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct Beam {
|
||||
row: isize,
|
||||
col: isize,
|
||||
direction: Direction,
|
||||
}
|
||||
|
||||
impl Beam {
|
||||
fn move_current(&mut self) {
|
||||
self.move_in(self.direction)
|
||||
}
|
||||
|
||||
fn move_in(&mut self, dir: Direction) {
|
||||
match dir {
|
||||
Direction::Up => {
|
||||
self.row -= 1;
|
||||
}
|
||||
Direction::Down => {
|
||||
self.row += 1;
|
||||
}
|
||||
Direction::Left => {
|
||||
self.col -= 1;
|
||||
}
|
||||
Direction::Right => {
|
||||
self.col += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn in_bounds(&self, contraption: &Contraption) -> bool {
|
||||
self.row >= 0
|
||||
&& self.row < contraption.height as isize
|
||||
&& self.col >= 0
|
||||
&& self.col < contraption.width as isize
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
fn is_vertical(&self) -> bool {
|
||||
match self {
|
||||
Direction::Up | Direction::Down => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_horizontal(&self) -> bool {
|
||||
match self {
|
||||
Direction::Left | Direction::Right => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Visited {
|
||||
directions: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl Visited {
|
||||
fn new(width: usize, height: usize) -> Self {
|
||||
Self {
|
||||
directions: vec![vec![0; width]; height],
|
||||
}
|
||||
}
|
||||
|
||||
fn visited_any(&self, row: usize, col: usize) -> bool {
|
||||
self.directions[row][col] != 0
|
||||
}
|
||||
|
||||
fn visited(&self, row: usize, col: usize, dir: Direction) -> bool {
|
||||
(self.directions[row][col] >> (dir as usize)) & 1 == 1
|
||||
}
|
||||
|
||||
fn visit(&mut self, row: usize, col: usize, dir: Direction) {
|
||||
self.directions[row][col] |= 1 << dir as usize;
|
||||
}
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.directions
|
||||
.iter()
|
||||
.map(|row| row.iter().filter(|&&x| x != 0).count())
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
|
||||
fn run_beam(initial: Beam, contraption: &Contraption) -> Visited {
|
||||
let mut visited = Visited::new(contraption.width, contraption.height);
|
||||
let mut beams = VecDeque::from([initial]);
|
||||
|
||||
while let Some(mut beam) = beams.pop_front() {
|
||||
beam.move_current();
|
||||
|
||||
while beam.in_bounds(contraption) {
|
||||
if visited.visited(beam.row as usize, beam.col as usize, beam.direction) {
|
||||
break;
|
||||
}
|
||||
|
||||
visited.visit(beam.row as usize, beam.col as usize, beam.direction);
|
||||
|
||||
match contraption.tiles[beam.row as usize][beam.col as usize] {
|
||||
Tile::Empty => (),
|
||||
Tile::SplitterVert => {
|
||||
if beam.direction.is_horizontal() {
|
||||
beams.push_back(Beam {
|
||||
row: beam.row,
|
||||
col: beam.col,
|
||||
direction: Direction::Up,
|
||||
});
|
||||
beam.direction = Direction::Down;
|
||||
}
|
||||
}
|
||||
Tile::SplitterHoriz => {
|
||||
if beam.direction.is_vertical() {
|
||||
beams.push_back(Beam {
|
||||
row: beam.row,
|
||||
col: beam.col,
|
||||
direction: Direction::Left,
|
||||
});
|
||||
beam.direction = Direction::Right;
|
||||
}
|
||||
}
|
||||
Tile::MirrorPos => {
|
||||
let new_dir = match beam.direction {
|
||||
Direction::Up => Direction::Right,
|
||||
Direction::Down => Direction::Left,
|
||||
Direction::Left => Direction::Down,
|
||||
Direction::Right => Direction::Up,
|
||||
};
|
||||
beam.direction = new_dir;
|
||||
}
|
||||
Tile::MirrorNeg => {
|
||||
let new_dir = match beam.direction {
|
||||
Direction::Up => Direction::Left,
|
||||
Direction::Down => Direction::Right,
|
||||
Direction::Left => Direction::Up,
|
||||
Direction::Right => Direction::Down,
|
||||
};
|
||||
beam.direction = new_dir;
|
||||
}
|
||||
}
|
||||
|
||||
beam.move_current();
|
||||
}
|
||||
}
|
||||
|
||||
visited
|
||||
}
|
||||
|
||||
fn debug_beams(contraption: &Contraption, visited: &Visited, beams: &VecDeque<Beam>) {
|
||||
for row in 0..contraption.height {
|
||||
for col in 0..contraption.width {
|
||||
if let Some(beam) = beams
|
||||
.iter()
|
||||
.find(|b| b.row == row as isize && b.col == col as isize)
|
||||
{
|
||||
let c = match beam.direction {
|
||||
Direction::Up => '^',
|
||||
Direction::Down => 'V',
|
||||
Direction::Left => '<',
|
||||
Direction::Right => '>',
|
||||
};
|
||||
print!("{}", c);
|
||||
} else if visited.visited_any(row, col) {
|
||||
print!("#");
|
||||
} else {
|
||||
print!("{}", contraption.tiles[row][col].tile_char());
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
fn max_visited(contraption: &Contraption) -> usize {
|
||||
let mut max = 0;
|
||||
for col in 0..contraption.width {
|
||||
max = max.max(
|
||||
run_beam(
|
||||
Beam {
|
||||
row: -1,
|
||||
col: col as isize,
|
||||
direction: Direction::Down,
|
||||
},
|
||||
contraption,
|
||||
)
|
||||
.count(),
|
||||
);
|
||||
max = max.max(
|
||||
run_beam(
|
||||
Beam {
|
||||
row: contraption.height as isize,
|
||||
col: col as isize,
|
||||
direction: Direction::Up,
|
||||
},
|
||||
contraption,
|
||||
)
|
||||
.count(),
|
||||
);
|
||||
}
|
||||
for row in 0..contraption.height {
|
||||
max = max.max(
|
||||
run_beam(
|
||||
Beam {
|
||||
row: row as isize,
|
||||
col: -1,
|
||||
direction: Direction::Right,
|
||||
},
|
||||
contraption,
|
||||
)
|
||||
.count(),
|
||||
);
|
||||
max = max.max(
|
||||
run_beam(
|
||||
Beam {
|
||||
row: row as isize,
|
||||
col: contraption.width as isize,
|
||||
direction: Direction::Left,
|
||||
},
|
||||
contraption,
|
||||
)
|
||||
.count(),
|
||||
);
|
||||
}
|
||||
max
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_run_beam() {
|
||||
let contraption: Contraption = r#"
|
||||
.|...\....
|
||||
|.-.\.....
|
||||
.....|-...
|
||||
........|.
|
||||
..........
|
||||
.........\
|
||||
..../.\\..
|
||||
.-.-/..|..
|
||||
.|....-|.\
|
||||
..//.|....
|
||||
"#
|
||||
.into();
|
||||
|
||||
let visited = run_beam(
|
||||
Beam {
|
||||
row: 0,
|
||||
col: -1,
|
||||
direction: Direction::Right,
|
||||
},
|
||||
&contraption,
|
||||
);
|
||||
|
||||
assert_eq!(visited.count(), 46);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_max_visited() {
|
||||
let contraption: Contraption = r#"
|
||||
.|...\....
|
||||
|.-.\.....
|
||||
.....|-...
|
||||
........|.
|
||||
..........
|
||||
.........\
|
||||
..../.\\..
|
||||
.-.-/..|..
|
||||
.|....-|.\
|
||||
..//.|....
|
||||
"#
|
||||
.into();
|
||||
|
||||
assert_eq!(max_visited(&contraption), 51);
|
||||
}
|
||||
}
|
|
@ -16,7 +16,8 @@ mod day12;
|
|||
mod day13;
|
||||
mod day14;
|
||||
mod day15;
|
||||
mod day16;
|
||||
|
||||
fn main() {
|
||||
day15::run();
|
||||
day16::run();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue