diff --git a/inputs/day16.txt b/inputs/day16.txt new file mode 100644 index 0000000..2b0a13f --- /dev/null +++ b/inputs/day16.txt @@ -0,0 +1,110 @@ +\..|...................|........\..............\.................-......./........./...\..........-......./... +........../...-/......\.|............../.................\...........\........-.........|.....\.-.|........... +...............-...........|......|...|......../.......\............../.................................../... +..................................|............../..|.|.../............./..\\........|...|..............\..|.. +...........................-...-...-.......................-.....-.-....\.......-............................/ +........-...|.......|./../......................./.........................\.................../.....\........ +\..\............-.\.........|../................................\....\......................./.............-.. +|\...|....\................\...|........\-..............|............\.........\.\..|.|....................... +.....\.........\......|...-...............................-.............-../.../..--......\.....\............. +................|...........................|..........\...........././.................../............../.... +.............................\......\.../..|................---................-......\....|...-............-. +..........|........./......\|...|.......|........\......\....-....\...-...../................/..-..../......-. +...|............./.................\../....|...\../.................|...|..|......|........................... +..................................-......../.....|............................................................ +...................-.............|...-.........../...........................-..............-...............|. +..-.............../.............................-......-.....-.............|-...../....................../.... +....||...../.........................................-...........................................--./-.......\ +...................\..........-......./..............|\........................../.-.|..............-..-/...|. +.-............-............../..-........../.......................\...-...||........./.-.....-....../........ +.......-.......-........................................../\\.......|......./../..\........\..-.........../../ +....../../.......................\.........\-....\.|..................\......................./...-\.......... +\.......-........\...-.....................\....-........./-...|......|.......-........................\...\.. +...|\.................................../..../..........|......-......../-..|......./..........\../..|......-\ +..........\...........................|..-........-/-......../....|...............................\.....|..... +..............\......-............................-.../........|........................./........-........... +.............-..\.//.....................-....-......|....../....-............................/..............| +\........../....|................./.....\......\.../.................|........\............../................ +.....-........-/|.........\.....-./............|...\.|......|.......|...................\\.....\.............- +................|.-...-.....................|..........-....\....\......../...............................././ +...........|.......\..............\......................................./........-.......................... +...........................-..../............|............................|...........\....................... +....................|..........|..................../...........\.....|.........-............\.\...-..\....... +................................-......-......\.....-/......\...\................/................-........... +..|.....\..\......|../....................................................\\......-...../..../..............// +.........\.................\..\..-.-..................\.....\..\.....\..........-............................. +...................\............/..\............|.............../..\............................|\.\...../.... +......|...............\.......|......|/........|....-.......|...........-.../.\....\.....|./.......|.......... +....\/|................-.-..........|.................../..............|../-...|/..........|.................. +..|........./-\.............|...|............|......\...................\..../.........|...............|.-.... +...................-................\....|/....-...|......./....../..........-|............/......\../..\\.... +...........................-..........................................-...|.|................\../...........-. +......../.....|.........-.......|........./-............|../.......|......-.-.-.......................-..|-... +.........|-...............|............./.....|........../..|........\..........|/.............../-........... +...\.....|..|...........\....-...\/.........................................|...................\......-.-.... +.../...-...|.............|.....\...|.................................../..............\.................../... +..........-.........../....|.....|..-.........../.................................-..................\....\/.. +....../..............\../......../.....-./....|../.\....-.................../............................../.\ +......-.|..........................\...............|.......-...-....../.............//...\|................/.. +................/.........|........................|......./..|......../-...........................\....|.... +........../...|.........\...........-./......\\...........\......|-......|...\...............\................ +../.........................|.................-/...........--.........\.../........................\.........\ +........\..|...|.............../...................-.........|.................\..|......./.........-.....-|.. +\.../.......|.............|-.../.................\...\..........\...|..........\....../......-................ +............|.|....\..--............-/-..................../........................-../..\..-................ +.....................................|.................../.................................|..../..-......\... +....|..............|..-.....|../.........................................|........\.................|......... +..............\..|...............\....||........../................................\................./.\...... +.....................-../......./....../.................................-............\........../............ +.....|.............../......-.\.|........-...................|.....-........\...-.............-....-.......-.. +..../.....|..............\../..............................\........|....................|..............\..... +....\................-........\../......|..../......................-.....|............../.../........../..... +....-...........................-.............|...........\..|........|.......\././.....|./..........\........ +/....................\..............\.............................-......................../\......../....-... +......\..................-............................................./.\...../.............\....-....\.\.... +..................................\-............................/.......|........................-|........... +.................../.../.......|./............\.........\....-.-....-../\.........|........./...\............. +......./.../....|...../|......................|.....|.....|.........|...........\......-.\..................|. +..././...........................|.......\.|......-........./................................................. +........|.|.......................-....................././.......||...........|/....-....\.......|......\/... +.\.\.....|....\......-....|...|.....//........|..-.........-.................-........./...................... +.|.....................\............-.................................|..../.............-....../.........../. +.|..\..../...............\..................../...\............................-....../................../.|.. +./.\............................/.............-...../-................\.........\.............|...../......... +..........\...............................\............../.........\.....-/........./|........................ +.............\..|....|..................................\.........|./......................\.........-........ +../.....|-............|...\................|...-....-........./........|.-..........\......................... +........-............./...........--................../...............................|..|.\....\............. +\.............-\.........................-|......|/.........\............/...........-.../.\........\..\.../.. +......................|........\....-../.............|......|.-...................................-|../...-... +.............|...|.....-...........|.....-...............|...\........................./..\....\.............. +..............|.............-.........../....-..................................|......./........|............ +...........|.-..../......................................\....-...\-......../........-..........-......-.....| +../...........-............-.../|...........-.-.............\.............................|.............-..... +.........../...-............../........./...................................../......-.......\\............... +........................./.||......|...../.......|....|..................-..........|......\.................. +............/....-./..-...........|...-..........\....../...\/.......|\.....\....|........../..\.\............ +.......................................-.../.......|............|........|...\..........\.....-............... +/..\|.............-...-.................................\........\...................\......|....-............ +..................\............../........................./.........|..........\...\......\..........|......| +.../.................................................../...|............../....\...\...../........|.......-... +..................-.-..........................\.................-......................-..\.........-........ +...................../\.....\.............\.............../................\.|............../........./....... +....................|../.\./......................................-.../.......\............................... +|........................-..............................................|...............................-..... +....\.\...........\......|.........\/|..|....|.....\............-...../.............................\\........ +......\....|......\|.....-..................\........\.......................-............-.|..............|.. +....|.....././.......................|......../...........-.|............./......-.|....../.....\......|....\. +.........\........|.......\..........|........./..................\.........................|................- +.....\..........\.....-......../...|-........../...\/|........................................................ +.../.....................\../.........\.|.........-..........\...............................|...............\ +.........-...........................................-.|...........\......//............../..|.\............/. +.-|../...../.........|............./..........................|..-.\......\............\................../... +../....../.................|..............\.........|.\......\...../.......\............\./.......|....../..\. +......../.-..-......\.........................\|...................................-....../................... +......................-....|........./\................|......\..-\....../.......\.................\/.-\...... +............\...|...............|............./...........................................\....-.-............ +\.........|.............................|............/.........-.....\........\|...-..-..\/.../......./....... +.............................\.|...............\....\..\-.....................\......-...../......\..../.....\ +..\-......\.\........-........../........\...............\..................../....-....\.\.|.|............... +................|./........../.................................-.............|...................\............ diff --git a/src/bin/day16.rs b/src/bin/day16.rs new file mode 100644 index 0000000..6386bb2 --- /dev/null +++ b/src/bin/day16.rs @@ -0,0 +1,165 @@ +#![allow(clippy::enum_variant_names)] +#![forbid(elided_lifetimes_in_paths, unsafe_code)] + +use aoc23::read; +use chumsky::prelude::*; +use std::collections::HashSet; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +enum Mirror { + NoMirror, + Forward, + Backward, + Horizontal, + Vertical +} + +impl Mirror { + fn parser() -> impl Parser> { + choice(( + just('.').map(|_| Self::NoMirror), + just('/').map(|_| Self::Forward), + just('\\').map(|_| Self::Backward), + just('-').map(|_| Self::Horizontal), + just('|').map(|_| Self::Vertical) + )) + } +} + +fn parser() -> impl Parser>, Error = Simple> { + Mirror::parser() + .repeated() + .then_ignore(just("\n")) + .repeated() + .then_ignore(end()) +} + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +enum Direction { + Left, + Right, + Up, + Down +} + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +struct Beam { + row: usize, + col: usize, + dir: Direction +} + +impl Beam { + fn step(mut self) -> Option { + use Direction::*; + + match self.dir { + Left => { + self.col = self.col.checked_sub(1)?; + }, + Right => { + self.col += 1; + }, + Up => { + self.row = self.row.checked_sub(1)?; + }, + Down => { + self.row += 1; + } + } + Some(self) + } +} + +fn continue_beam( + grid: &[Vec], + energized: &mut HashSet<(usize, usize)>, + visited: &mut HashSet, + beam: Beam, + _indent: usize +) { + if let Some(beam) = beam.step() { + if !visited.contains(&beam) { + follow_beam(grid, energized, visited, beam, _indent); + } + } +} + +fn follow_beam( + grid: &[Vec], + energized: &mut HashSet<(usize, usize)>, + visited: &mut HashSet, + mut beam: Beam, + _indent: usize +) { + use Direction::*; + use Mirror::*; + + assert!(!visited.contains(&beam)); + visited.insert(beam); + + let mirror = grid.get(beam.row).and_then(|row| row.get(beam.col)); + for _ in 0 .. _indent { + eprint!(" "); + } + eprintln!("\\- {beam:?}: {mirror:?}"); + + match (mirror, beam.dir) { + // we left the grid + (None, _) => return, + // we pass the beam through + (Some(NoMirror), _) + | (Some(Horizontal), Left) + | (Some(Horizontal), Right) + | (Some(Vertical), Up) + | (Some(Vertical), Down) => {}, + // we reflect the beam (/) + (Some(Forward), Right) => beam.dir = Up, + (Some(Forward), Down) => beam.dir = Left, + (Some(Forward), Left) => beam.dir = Down, + (Some(Forward), Up) => beam.dir = Right, + // we reflect the beam (\) + (Some(Backward), Right) => beam.dir = Down, + (Some(Backward), Up) => beam.dir = Left, + (Some(Backward), Left) => beam.dir = Up, + (Some(Backward), Down) => beam.dir = Right, + // we split the beam + (Some(Horizontal), Up) | (Some(Horizontal), Down) => { + beam.dir = Left; + continue_beam(grid, energized, visited, beam, _indent + 1); + beam.dir = Right; + }, + (Some(Vertical), Left) | (Some(Vertical), Right) => { + beam.dir = Up; + continue_beam(grid, energized, visited, beam, _indent + 1); + beam.dir = Down; + } + } + energized.insert((beam.row, beam.col)); + continue_beam(grid, energized, visited, beam, _indent + 1); + + for _ in 0 .. _indent { + eprint!(" "); + } + eprintln!(" -/ {beam:?}: {mirror:?}"); +} + +fn main() -> anyhow::Result<()> { + let grid = read("inputs/day16.txt", parser())?; + let mut energized = HashSet::new(); + let mut visited = HashSet::new(); + follow_beam( + &grid, + &mut energized, + &mut visited, + Beam { + row: 0, + col: 0, + dir: Direction::Right + }, + 0 + ); + println!("{}", energized.len()); + + Ok(()) +}