Compare commits

..

3 Commits

5 changed files with 372 additions and 1 deletions

7
16/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day16"
version = "0.1.0"

4
16/Cargo.toml Normal file
View File

@ -0,0 +1,4 @@
[package]
name = "day16"
version = "0.1.0"
edition = "2021"

110
16/input Normal file
View File

@ -0,0 +1,110 @@
\.....................\.......................|..../......-.........../.|.....\.............|..........|..\...
.../...................\..................../...|.......|........||...................../...........\.........
././....|......./................\............|..\...........-....../............../|........-................
....\..\...........-/..|......|......\............|............../.................-........./...-...|.......\
..................................|.\.......|...../.........................-...../......\..|...............\.
.....\.............................................|../.\............../--.......................\............
|.......-.|........\.................\..............|........./....\.........|...................\-.-...|.....
....\........./....-.........................--.....\..../......................|.\......................\...-
\..-..../.....|..........\......................-|......|...................../...../........./...........-...
........................\.\|......../........../......................\.............|./../....................
.....\...................|.............................|......-........|.........-./.../.|....................
..-................./.........................................\..\........-..-........-.......\../............
-................-............................\................./..--................-............../.|.......
..-.....|.............|................./.......-.-........................-............-...........\.........
..........|..........................-...|..\...............................................\-....\...........
/................../..........|....\..-......................../....\...\..........-....../.........../.....\.
................\....-................-|.\...-...........-.....-........\..........................\..........
...................................\../..|.../../...........................\.........../.\-......|.........-.
/....|....|..........................\............./.....|/................./....-......................-.....
....-.............../.....|...........|../......\../.............../........................|............./...
......./..............|./../.................-.\.........../.....................|.........../........\.......
...................-...............\/.......|........|....................../.......................-/......\.
................\...../....-/......-.........-.....\/.\...............\....../...-....|......|.........\......
....-.........-.........................-......................../.......|...............................\....
......../..................|...../......\..\..-|-..../..............|......../............|.-.......-.........
......./............-..........-............................../.........................|\..-..-\.\......-..\.
.\-.....|......................-..\................/.-................|.\..............\..................|...
-..........................-............../.|.-......\......-..-...../......./................................
....|.................................................\....|..........\...................-......|........./..
................../...........-..............\......................................|.-........|..............
...-............|..............-...........-.\.......................|..|..../......................../.|....-
.......-..-......./...../.........-.......\.....-.../............-./......../.../............-.....|...|......
...............|.........../..........|/..........|..........-.-...../...../..|..........\.....-./.|./....|...
.........|......................\.|.....|......................-.-........|.............................-...|.
.-...|..\...-...............\..............\......./........-............/.-..\........../...../....-....\....
...........\.-.......|.......|....-.............|-.|........../..../...\....\............|.|..|\..............
.....................|.\....|......|../...\......|........................\......|.......-./..../.............
......................\--................................\.................|................-.................
-...............\...-.....................................-.\...../....\...........................|..........
.....|.......\.......................-/...\..-.........-..../\|..................\........-...................
..|........./....|..-./..\..\................-|..........\../......\...............\............\............|
......-................../.............|.............\................................-..\...../........-.....
....................../......../..\.-.........................|....\..|...\...../../.....|............../.....
...\................................/..............................\........|.........\.-............\........
/.................../................-...........-.|.............\.................................|.....-....
.|...-..|/./../.........-./.............................................../..........-.........-.|./..........
..../..................|......................|../..........\........-......../.........\...|.................
........./..................|..-..........|\............\......-..-..\...|....|.....................|....-....
.....|/....|........\.........-................../..........|............|...........-.....|......./......//..
..........\.|../...|........................\.........\.|......||....-...............\\.....|.|..............|
............-................|.....-....||......../.../.......................|..\...........\................
...............-..../......-..../.......|-.....-.....\..................................../..|................
/......-...............\/...././..................\..................\..........-......................|......
...................\.....\.................\...|.................-............/........-..............\./.....
.-.\....\........\........-../.-............../...../..-..|...................../.-.....\.....-........../..\.
|...|...............................|............../.............../....................|...../...............
....../....../...|..............-.-........-..|.../....................\|.....\......................|....../.
...\\.......|...|-............|..........-...........................................\/...../..-.-............
.........|.............|..|......\............\...............|......\......\.............\...\-.......\.....\
...........\..-.|.......|\..\..................-........\/...............................-....................
...\.................\..............................................\...............\.......-.../.............
..\.............\....---....................//.......................................|./.............../\.....
.\...........|..................................\........-......|.........\.................-........-........
..............-...............-.../....-........|.....-../......................./..../........../../--..\....
.........-......\......-.........../...\./.|.................\...................--..-........|..\......\....|
....../.........................................|...../........../..............\\...-/.......-......\..\.....
.........../...\.|..................../.\.................|......\.\..|.........../...../.....\.\...........|.
..../\..-...../.............................../..../............................-...-......\...........\......
..-..\.............................\...........|..........|.........|..........................-......./......
-..|.................-\.....\...............\/.....|...........................././...\......\.......\...-....
......\..............|..|..............-............../....................-....\\........\....|..............
|.............\....\./.....-|-....\.....\..............\/........-.|..|...........-..\......-..../.......|....
............................-.......................|........................../................|.............
/................|../............\/.....\/....-.....\......\...../|..\..........|............../..............
.|....../...../....................../..|.....................-................./...../-.........-............
......................\|........../......./..\........\.........-......../.........../.|/.......\.../.........
...............\......-|............\..\....../.........\.....|...|\............/............\.\..|.......\...
......|...........\....../....\./......./-....\../.......\...-...............\./...\.....-.......-..../.......
...|..|.............................\.....-.|........./......../......................-......./............\..
.....|........\.........|...-.-.........\..../....../..-.......-...............\..../.....-..../..............
........./.\/........................-..........\.....................|.......-..............\./.\............
..../................/................................|.....||..............\........-...............|........
....\./.........../\-.....-...\............//.\..............\...../................|.....\..-................
..../|........./............|.....................|......................-..|...............................\.
..................\............................\.......\.........-.............|...../.-.............-......|.
..............|.-...........................\.\./.......\........../...\................/....-................
.......|................/-............\............/...........-..../...........\......../...\.......\........
..............|..../......................-...........-..\.................................................-..
..............................-..-................-.......-.................-..........\.../...............|..
......-.........-........................./.....................\....|........................................
.....\........./.....-.................../................|...................|........................|......
........../.../........................./.|................-...........\...........-....|.....................
.....-.......\././/.......|..............|......../..\...........\.............................-......|../-.-.
........|-....-....................\.....|\...\/.....\........\......./..........|.\-..|......................
../...-...-...|...../............\.......................-..........\...\.....-...\...............|....../...|
............|..\....|..................\/...................../../....|...................|.............../...
.............-................./............|.......|............\....................................\.-.....
-...../|..............-......\..../..................|..\....-............................................\...
........|.........-........\................/....\..................../.|...................................|.
.....|................./.........-|\...-...................|....-................-......../...............|..-
.|.........|...........|...-.............................\............................|................\......
....|.....-......|......./.-.|...........\..-........|.........................-....-..-.....|................
........................................\.....................-.../........................../../..........|..
-................/....\.......//....-........................../.\.........-......./..|\..........\...........
-............................./......................................../-...........................\|........
........................................../-.....//......\......\...........\........|./....../.......--......
../..............-....../......../................../......./....-...........|../.......\.\.......-......./..\
..............-............../......|.........-...............|................................-..........\...
.....................\..........|..\......|...............................................-...................
...../..|.../.........|.../.......-...................................\.....................................|.

250
16/src/main.rs Normal file
View File

@ -0,0 +1,250 @@
use std::collections::HashSet;
use std::fmt::Display;
use std::fs::File;
use std::io::{BufRead, BufReader, Lines};
use std::iter::repeat;
use std::time::Instant;
// BOILERPLATE
type InputIter = Lines<BufReader<File>>;
fn get_input() -> InputIter {
let f = File::open("input").unwrap();
let br = BufReader::new(f);
br.lines()
}
fn main() {
let start = Instant::now();
let ans1 = problem1(get_input());
let duration = start.elapsed();
println!("Problem 1 solution: {} [{}s]", ans1, duration.as_secs_f64());
let start = Instant::now();
let ans2 = problem2(get_input());
let duration = start.elapsed();
println!("Problem 2 solution: {} [{}s]", ans2, duration.as_secs_f64());
}
// PARSE
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
enum FromDirection {
Left,
Above,
Right,
Below,
}
impl Display for FromDirection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Above => f.write_str("above"),
Self::Below => f.write_str("below"),
Self::Left => f.write_str("left"),
Self::Right => f.write_str("right"),
}
}
}
struct Contraption {
tiles: Vec<Vec<char>>,
}
struct VisitState {
energized: Vec<Vec<bool>>,
visited_rays: HashSet<((i64, i64), FromDirection)>,
}
impl VisitState {
fn score(&self) -> u64 {
self.energized.iter().flatten().filter(|c| **c).count() as u64
}
fn dump(&self) {
println!("Score {}:", self.score());
for line in &self.energized {
println!(
" {}",
String::from_iter(line.iter().map(|b| if *b { '#' } else { '.' }))
);
}
}
}
impl Contraption {
fn cast_ray<'a>(
&'a mut self,
state: &'a mut VisitState,
pos: (i64, i64),
dir: FromDirection,
) {
let mut new_rays = self.cast_ray_inner(state, pos, dir);
loop {
new_rays = new_rays
.iter()
.flat_map(|(pos, dir)| self.cast_ray_inner(state, *pos, *dir))
.collect();
if new_rays.len() == 0 {
break;
}
}
}
fn cast_ray_inner<'a>(
&'a mut self,
state: &'a mut VisitState,
mut pos: (i64, i64),
mut dir: FromDirection,
) -> Vec<((i64, i64), FromDirection)> {
let width = state.energized[0].len();
let height = state.energized.len();
let mut new_rays = Vec::new();
while pos.0 >= 0 && pos.1 >= 0 && pos.0 < width as i64 && pos.1 < height as i64 {
// visit pos
state.energized[pos.1 as usize][pos.0 as usize] = true;
if !state.visited_rays.insert((pos, dir)) {
break;
}
(pos, dir) = match self.tiles[pos.1 as usize][pos.0 as usize] {
'.' => match dir {
FromDirection::Left => ((pos.0 + 1, pos.1), dir),
FromDirection::Right => ((pos.0 - 1, pos.1), dir),
FromDirection::Above => ((pos.0, pos.1 + 1), dir),
FromDirection::Below => ((pos.0, pos.1 - 1), dir),
},
'/' => match dir {
// from left, go up, from below
FromDirection::Left => ((pos.0, pos.1 - 1), FromDirection::Below),
// from up, go left, from the right
FromDirection::Above => ((pos.0 - 1, pos.1), FromDirection::Right),
// from right, go down, from above
FromDirection::Right => ((pos.0, pos.1 + 1), FromDirection::Above),
// from below, go right, from left
FromDirection::Below => ((pos.0 + 1, pos.1), FromDirection::Left),
},
'\\' => match dir {
FromDirection::Left => ((pos.0, pos.1 + 1), FromDirection::Above),
FromDirection::Above => ((pos.0 + 1, pos.1), FromDirection::Left),
FromDirection::Right => ((pos.0, pos.1 - 1), FromDirection::Below),
FromDirection::Below => ((pos.0 - 1, pos.1), FromDirection::Right),
},
'-' => match dir {
FromDirection::Left => ((pos.0 + 1, pos.1), dir),
FromDirection::Right => ((pos.0 - 1, pos.1), dir),
FromDirection::Above | FromDirection::Below => {
new_rays.push(((pos.0 + 1, pos.1), FromDirection::Left));
((pos.0 - 1, pos.1), FromDirection::Right)
}
},
'|' => match dir {
FromDirection::Above => ((pos.0, pos.1 + 1), dir),
FromDirection::Below => ((pos.0, pos.1 - 1), dir),
FromDirection::Left | FromDirection::Right => {
new_rays.push(((pos.0, pos.1 + 1), FromDirection::Above));
((pos.0, pos.1 - 1), FromDirection::Below)
}
},
c => unimplemented!("invalid character {}", c),
}
}
new_rays
}
fn empty_state(&self) -> VisitState {
let mut energized = Vec::new();
for _ in 0..self.tiles.len() {
energized.push(Vec::from_iter(repeat(false).take(self.tiles[0].len())));
}
VisitState {
energized,
visited_rays: HashSet::new(),
}
}
}
impl<T: BufRead> From<Lines<T>> for Contraption {
fn from(lines: Lines<T>) -> Self {
let mut tiles = Vec::new();
for line in lines {
tiles.push(line.unwrap().chars().map(|c| c.into()).collect());
}
Contraption { tiles }
}
}
// PROBLEM 1 solution
fn problem1<T: BufRead>(input: Lines<T>) -> u64 {
let mut contraption = Contraption::from(input);
let mut state = contraption.empty_state();
contraption.cast_ray(&mut state, (0,0), FromDirection::Left);
state.energized.iter().flatten().filter(|c| **c).count() as u64
}
// PROBLEM 2 solution
fn problem2<T: BufRead>(input: Lines<T>) -> u64 {
let mut contraption = Contraption::from(input);
let mut max_tiles = 0u64;
for y in 0..contraption.tiles.len() as i64 {
let mut left_state = contraption.empty_state();
contraption.cast_ray(&mut left_state, (0, y), FromDirection::Left);
let mut right_state = contraption.empty_state();
contraption.cast_ray(
&mut right_state,
(contraption.tiles[0].len() as i64 - 1, y),
FromDirection::Right,
);
max_tiles = std::cmp::max(
max_tiles,
std::cmp::max(left_state.score(), right_state.score()),
);
}
for x in 0..contraption.tiles[0].len() as i64 {
let mut top_state = contraption.empty_state();
contraption.cast_ray(&mut top_state, (x, 0), FromDirection::Above);
let mut bottom_state = contraption.empty_state();
contraption.cast_ray(
&mut bottom_state,
(x, contraption.tiles.len() as i64 - 1),
FromDirection::Below,
);
max_tiles = std::cmp::max(
max_tiles,
std::cmp::max(top_state.score(), bottom_state.score()),
);
}
max_tiles
}
#[cfg(test)]
mod tests {
use crate::*;
use std::io::Cursor;
const EXAMPLE: &str = &r".|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|....";
#[test]
fn problem1_example() {
let c = Cursor::new(EXAMPLE);
assert_eq!(problem1(c.lines()), 46);
}
#[test]
fn problem2_example() {
let c = Cursor::new(EXAMPLE);
assert_eq!(problem2(c.lines()), 51);
}
}

View File

@ -1,6 +1,6 @@
use std::fs::File;
use std::io::{BufRead, BufReader, Lines};
use std::time::{Duration, Instant};
use std::time::Instant;
// BOILERPLATE
type InputIter = Lines<BufReader<File>>;