Skip to content

Commit

Permalink
further simplify and optimize day 16
Browse files Browse the repository at this point in the history
  • Loading branch information
kcaffrey committed Dec 16, 2023
1 parent f7a5436 commit 9187910
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 81 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 13](./src/bin/13.rs) | `12.3µs` | `15.9µs` |
| [Day 14](./src/bin/14.rs) | `25.0µs` | `4.5ms` |
| [Day 15](./src/bin/15.rs) | `20.4µs` | `85.9µs` |
| [Day 16](./src/bin/16.rs) | `178.8µs` | `8.1ms` |
| [Day 16](./src/bin/16.rs) | `134.7µs` | `5.8ms` |

**Total: 15.29ms**
**Total: 12.95ms**
<!--- benchmarking table --->

---
Expand Down
102 changes: 23 additions & 79 deletions src/bin/16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ fn energize_count(grid: &Grid, start: Coordinate, start_dir: Direction) -> u32 {
energized[start.row * grid.width + start.col] = true;
queue.push_back((start, start_dir, grid.get_tile(start)));
while let Some((cur, dir, tile)) = queue.pop_front() {
for (next, next_dir) in tile
.next(dir)
.filter_map(|dir| grid.move_in_dir(cur, dir).map(|c| (c, dir)))
{
let mut do_next = |next_dir| {
let Some(next) = grid.move_in_dir(cur, next_dir) else {
return;
};
let tile = grid.get_tile(next);
let i = next.row * grid.width + next.col;
let was_energized = energized[i];
Expand All @@ -47,6 +47,25 @@ fn energize_count(grid: &Grid, start: Coordinate, start_dir: Direction) -> u32 {
// Otherwise keep going
_ => queue.push_back((next, next_dir, tile)),
}
};
use Direction::{East, North, South, West};
use Tile::{Empty, HorizontalSplitter, LeftMirror, RightMirror, VerticalSplitter};
match (tile, dir) {
(Empty, _) => do_next(dir),
(HorizontalSplitter, East) | (HorizontalSplitter, West) => do_next(dir),
(VerticalSplitter, North) | (VerticalSplitter, South) => do_next(dir),
(LeftMirror, East) | (RightMirror, West) => do_next(South),
(LeftMirror, West) | (RightMirror, East) => do_next(North),
(LeftMirror, North) | (RightMirror, South) => do_next(West),
(LeftMirror, South) | (RightMirror, North) => do_next(East),
(HorizontalSplitter, _) => {
do_next(West);
do_next(East);
}
(VerticalSplitter, _) => {
do_next(North);
do_next(South);
}
}
}
energized.into_iter().filter(|&e| e).count() as u32
Expand Down Expand Up @@ -93,61 +112,6 @@ impl Grid {
}
}

impl Tile {
pub fn next(self, dir: Direction) -> impl Iterator<Item = Direction> {
let mut next = [None, None, None];
if self.can_go_straight(dir) {
next[0] = Some(dir);
}
if self.can_turn_left(dir) {
next[1] = Some(dir.rotate_left());
}
if self.can_turn_right(dir) {
next[2] = Some(dir.rotate_right());
}
next.into_iter().flatten()
}

const fn can_go_straight(self, dir: Direction) -> bool {
matches!(
(self, dir),
(Self::Empty, _)
| (Self::VerticalSplitter, Direction::South)
| (Self::VerticalSplitter, Direction::North)
| (Self::HorizontalSplitter, Direction::East)
| (Self::HorizontalSplitter, Direction::West)
)
}

const fn can_turn_left(self, dir: Direction) -> bool {
matches!(
(self, dir),
(Self::VerticalSplitter, Direction::East)
| (Self::VerticalSplitter, Direction::West)
| (Self::HorizontalSplitter, Direction::North)
| (Self::HorizontalSplitter, Direction::South)
| (Self::LeftMirror, Direction::North)
| (Self::LeftMirror, Direction::South)
| (Self::RightMirror, Direction::East)
| (Self::RightMirror, Direction::West)
)
}

const fn can_turn_right(self, dir: Direction) -> bool {
matches!(
(self, dir),
(Self::VerticalSplitter, Direction::East)
| (Self::VerticalSplitter, Direction::West)
| (Self::HorizontalSplitter, Direction::North)
| (Self::HorizontalSplitter, Direction::South)
| (Self::LeftMirror, Direction::East)
| (Self::LeftMirror, Direction::West)
| (Self::RightMirror, Direction::North)
| (Self::RightMirror, Direction::South)
)
}
}

impl Coordinate {
const fn new(row: usize, col: usize) -> Self {
Self { row, col }
Expand All @@ -173,26 +137,6 @@ impl Coordinate {
}
}

impl Direction {
const fn rotate_left(self) -> Self {
match self {
Direction::North => Direction::West,
Direction::South => Direction::East,
Direction::East => Direction::North,
Direction::West => Direction::South,
}
}

const fn rotate_right(self) -> Self {
match self {
Direction::North => Direction::East,
Direction::South => Direction::West,
Direction::East => Direction::South,
Direction::West => Direction::North,
}
}
}

#[derive(Error, Debug)]
enum ParseGridError {
#[error("invalid tile character: {0}")]
Expand Down

0 comments on commit 9187910

Please sign in to comment.