Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 912ecf7

Browse files
committed
Day 16 part 2
1 parent 6d8e758 commit 912ecf7

File tree

1 file changed

+50
-14
lines changed

1 file changed

+50
-14
lines changed

src/bin/day16.rs

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use adventofcode2024::ascii::{Dir, Map, Pos};
22
use adventofcode2024::input::AocInput;
33
use std::cmp::Ordering;
4-
use std::collections::{BinaryHeap, HashSet};
4+
use std::collections::{BinaryHeap, HashMap, HashSet};
55
use std::time::Instant;
66

7-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8-
struct State(Pos, Dir, i64);
7+
#[derive(Debug, Clone, PartialEq, Eq)]
8+
struct State(Vec<Pos>, Dir, i64);
99

1010
impl Ord for State {
1111
fn cmp(&self, other: &Self) -> Ordering {
@@ -22,30 +22,66 @@ impl PartialOrd for State {
2222
fn part1(map: &Map, start: Pos, end: Pos) {
2323
let mut work: BinaryHeap<State> = BinaryHeap::new();
2424
let mut done: HashSet<(Pos, Dir)> = HashSet::new();
25-
work.push(State(start, Dir::E, 0));
25+
work.push(State(vec![start], Dir::E, 0));
2626
while let Some(s) = work.pop() {
27-
if done.contains(&(s.0, s.1)) {
27+
let pos = *s.0.last().unwrap();
28+
let dir = s.1;
29+
if done.contains(&(pos, dir)) {
2830
continue;
2931
}
30-
if s.0 == end {
32+
done.insert((pos, dir));
33+
if pos == end {
3134
println!("Part 1: {:?}", s.2);
3235
return;
3336
}
34-
work.push(State(s.0, s.1.right90(), s.2 + 1000));
35-
work.push(State(s.0, s.1.left90(), s.2 + 1000));
36-
let t = s.0.step(s.1);
37-
if map.get(t) == '.' {
38-
work.push(State(t, s.1, s.2 + 1));
37+
work.push(State(s.0.clone(), dir.right90(), s.2 + 1000));
38+
work.push(State(s.0.clone(), dir.left90(), s.2 + 1000));
39+
let target = pos.step(dir);
40+
if map.get(target) == '.' {
41+
let mut extended_path = s.0.clone();
42+
extended_path.push(target);
43+
work.push(State(extended_path, dir, s.2 + 1));
3944
}
40-
done.insert((s.0, s.1));
4145
}
4246
panic!("No path found!");
4347
}
4448

45-
fn part2(_map: &Map, start: Pos, end: Pos) {
46-
println!("Part 2: {}", 2);
49+
50+
fn part2(map: &Map, start: Pos, end: Pos) {
51+
let mut work: BinaryHeap<State> = BinaryHeap::new();
52+
let mut done: HashMap<(Pos, Dir), i64> = HashMap::new();
53+
let mut best: Vec<State> = Vec::new();
54+
work.push(State(vec![start], Dir::E, 0));
55+
while let Some(s) = work.pop() {
56+
let pos = *s.0.last().unwrap();
57+
let dir = s.1;
58+
if let Some(cc) = done.get(&(pos, dir)) {
59+
if *cc < s.2 {
60+
continue;
61+
}
62+
}
63+
done.insert((pos, dir), s.2);
64+
if pos == end {
65+
if !best.is_empty() && best.first().unwrap().2 < s.2 {
66+
break;
67+
}
68+
best.push(s.clone());
69+
}
70+
work.push(State(s.0.clone(), dir.right90(), s.2 + 1000));
71+
work.push(State(s.0.clone(), dir.left90(), s.2 + 1000));
72+
let target = pos.step(dir);
73+
if map.get(target) == '.' {
74+
let mut extended_path = s.0.clone();
75+
extended_path.push(target);
76+
work.push(State(extended_path, dir, s.2 + 1));
77+
}
78+
}
79+
80+
let cnt: HashSet<Pos> = best.iter().map(|s| s.0.clone()).flatten().collect();
81+
println!("Part 2: {:?}", cnt.len());
4782
}
4883

84+
4985
fn main() {
5086
let start = Instant::now();
5187
let mut input = AocInput::new("inputs/day16.txt");

0 commit comments

Comments
 (0)