Skip to content

Commit

Permalink
feat: day 16
Browse files Browse the repository at this point in the history
  • Loading branch information
JosefKuchar committed Dec 16, 2024
1 parent 9dcebca commit 1cea6d2
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 23 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 13](./src/bin/13.rs) | `363.7µs` | `344.0µs` |
| [Day 14](./src/bin/14.rs) | `245.3µs` | `127.9ms` |
| [Day 15](./src/bin/15.rs) | `236.3µs` | `984.1µs` |
| [Day 16](./src/bin/16.rs) | `2.3ms` | `5.9ms` |

**Total: 594.95ms**
**Total: 603.15ms**
<!--- benchmarking table --->

---
Expand Down
15 changes: 15 additions & 0 deletions data/examples/16.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
###############
#.......#....E#
#.#.###.#.###.#
#.....#.#...#.#
#.###.#####.#.#
#.#.#.......#.#
#.#.#####.###.#
#...........#.#
###.#.#####.#.#
#...#.....#.#.#
#.#.#.###.#.#.#
#.....#...#.#.#
#.###.#.#.#.#.#
#S..#.....#...#
###############
51 changes: 29 additions & 22 deletions src/bin/14.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{
collections::{HashMap, HashSet},
};

use pathfinding::matrix::directions::S;
use regex::Regex;

advent_of_code::solution!(14);
Expand Down Expand Up @@ -76,30 +77,36 @@ pub fn part_two(input: &str) -> Option<u32> {
robot.position.1 = robot.position.1.rem_euclid(height);
}

let robot_positions: HashSet<(i32, i32)> = robots.iter().map(|r| r.position).collect();
let symetric = robot_positions
.iter()
.filter(|(x, y)| robot_positions.contains(&(width - 1 - x, *y)))
.count();
if symetric > symetric_max_count {
symetric_max_count = symetric;
seconds = i + 1;
// for y in 0..height {
// for x in 0..width {
// let mut found = false;
// for robot in robots.iter() {
// if robot.position == (x, y) {
// found = true;
// break;
// }
// }
// print!("{}", if found { '#' } else { '.' });
// }
// println!();
// }
// println!("Seconds: {}", i + 1);
let mut found = false;
let mut robot_positions: HashSet<(i32, i32)> = HashSet::new();
for robot in robots.iter() {
if robot_positions.contains(&robot.position) {
found = true;
break;
}
robot_positions.insert(robot.position);
}
if found {
continue;
}
seconds = i;

for y in 0..height {
for x in 0..width {
let mut found = false;
for robot in robots.iter() {
if robot.position == (x, y) {
found = true;
break;
}
}
print!("{}", if found { '#' } else { '.' });
}
println!();
}
println!("Seconds: {}", i + 1);
}

Some(seconds)
}

Expand Down
104 changes: 104 additions & 0 deletions src/bin/16.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
advent_of_code::solution!(16);

use itertools::Itertools;
use pathfinding::prelude::{astar, astar_bag};

const DIRS: [(i32, i32); 4] = [(-1, 0), (0, 1), (1, 0), (0, -1)];

fn in_bounds(map: &[Vec<char>], pos: (i32, i32)) -> bool {
pos.0 >= 0
&& pos.1 >= 0
&& pos.0 < map.len() as i32
&& pos.1 < map[0].len() as i32
&& map[pos.0 as usize][pos.1 as usize] != '#'
}

fn successors(map: &[Vec<char>], node: &(i32, i32, i32)) -> Vec<((i32, i32, i32), u32)> {
let mut result = Vec::new();
let dir = node.2 as usize;
let straight = (node.0 + DIRS[dir].0, node.1 + DIRS[dir].1);
if in_bounds(&map, straight) {
result.push(((straight.0, straight.1, node.2), 1));
}
let left = (
node.0 + DIRS[(dir + 3) % 4].0,
node.1 + DIRS[(dir + 3) % 4].1,
);
if in_bounds(&map, left) {
result.push(((left.0, left.1, (node.2 + 3) % 4), 1001));
}
let right = (
node.0 + DIRS[(dir + 1) % 4].0,
node.1 + DIRS[(dir + 1) % 4].1,
);
if in_bounds(&map, right) {
result.push(((right.0, right.1, (node.2 + 1) % 4), 1001));
}
result
}

fn parse_input(input: &str) -> (Vec<Vec<char>>, (i32, i32, i32)) {
let map = input
.lines()
.map(|line| line.chars().collect::<Vec<_>>())
.collect::<Vec<_>>();
let mut start: (i32, i32, i32) = (0, 0, 0);
for (y, row) in map.iter().enumerate() {
for (x, cell) in row.iter().enumerate() {
if *cell == 'S' {
start = (y as i32, x as i32, 1);
}
}
}
(map, start)
}

pub fn part_one(input: &str) -> Option<u32> {
let (map, start) = parse_input(input);
let res = astar(
&start,
|node| successors(&map, node),
|_| 0,
|node| map[node.0 as usize][node.1 as usize] == 'E',
);
Some(res.unwrap().1 as u32)
}

pub fn part_two(input: &str) -> Option<u32> {
let (map, start) = parse_input(input);
let res = astar_bag(
&start,
|node| successors(&map, node),
|_| 0,
|node| map[node.0 as usize][node.1 as usize] == 'E',
);
Some(
res.unwrap()
.0
.flat_map(|nodes| {
nodes
.iter()
.map(|node| (node.0, node.1))
.collect::<Vec<_>>()
})
.unique()
.count() as u32,
)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(7036));
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(45));
}
}

0 comments on commit 1cea6d2

Please sign in to comment.