Skip to content

Commit e866789

Browse files
2016: Day 24
1 parent d204d42 commit e866789

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed

2016/day24/.vscode/settings.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"[rust]": {
3+
"editor.defaultFormatter": "rust-lang.rust-analyzer",
4+
"editor.formatOnSave": true
5+
},
6+
"rust-analyzer.check.command": "clippy"
7+
}

2016/day24/Cargo.lock

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

2016/day24/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[package]
2+
name = "day24"
3+
version = "0.1.0"
4+
edition = "2021"

2016/day24/src/main.rs

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
use std::{
2+
cmp::Reverse,
3+
collections::{hash_map::DefaultHasher, BTreeSet, BinaryHeap, HashSet},
4+
fs,
5+
hash::{Hash, Hasher},
6+
};
7+
8+
#[derive(PartialEq, Eq)]
9+
struct State {
10+
steps: usize,
11+
x: i32,
12+
y: i32,
13+
digits_found: BTreeSet<char>,
14+
}
15+
16+
impl Ord for State {
17+
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
18+
self.steps.cmp(&other.steps)
19+
}
20+
}
21+
22+
impl PartialOrd for State {
23+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
24+
Some(self.cmp(other))
25+
}
26+
}
27+
28+
fn key(s: &State) -> u64 {
29+
let mut h = DefaultHasher::new();
30+
s.x.hash(&mut h);
31+
s.y.hash(&mut h);
32+
s.digits_found.hash(&mut h);
33+
h.finish()
34+
}
35+
36+
fn main() {
37+
for part1 in [true, false] {
38+
let input = fs::read_to_string("input.txt").expect("Could not read file");
39+
40+
let grid = input
41+
.lines()
42+
.map(|l| l.chars().collect::<Vec<_>>())
43+
.collect::<Vec<_>>();
44+
45+
let mut digits = Vec::new();
46+
let mut start_x = 0;
47+
let mut start_y = 0;
48+
for y in 0..grid.len() {
49+
for x in 0..grid[0].len() {
50+
if grid[y][x].is_ascii_digit() {
51+
if grid[y][x] == '0' {
52+
start_x = x;
53+
start_y = y;
54+
}
55+
digits.push(grid[y][x]);
56+
}
57+
}
58+
}
59+
60+
let mut seen = HashSet::new();
61+
let mut queue = BinaryHeap::new();
62+
let initial = State {
63+
steps: 0,
64+
x: start_x as i32,
65+
y: start_y as i32,
66+
digits_found: BTreeSet::from(['0']),
67+
};
68+
let initial_key = key(&initial);
69+
seen.insert(initial_key);
70+
queue.push(Reverse(initial));
71+
72+
while !queue.is_empty() {
73+
let s = queue.pop().unwrap().0;
74+
75+
if s.digits_found.len() == digits.len()
76+
&& (part1 || (s.x as usize == start_x && s.y as usize == start_y))
77+
{
78+
println!("{}", s.steps);
79+
break;
80+
}
81+
82+
for dir in [(-1, 0), (1, 0), (0, -1), (0, 1)] {
83+
let nx = s.x + dir.0;
84+
let ny = s.y + dir.1;
85+
let c = grid[ny as usize][nx as usize];
86+
if c != '#' {
87+
let mut ndf = s.digits_found.clone();
88+
if c.is_ascii_digit() && !ndf.contains(&c) {
89+
ndf.insert(c);
90+
}
91+
let ns = State {
92+
steps: s.steps + 1,
93+
x: nx,
94+
y: ny,
95+
digits_found: ndf,
96+
};
97+
let k = key(&ns);
98+
if !seen.contains(&k) {
99+
seen.insert(k);
100+
queue.push(Reverse(ns));
101+
}
102+
}
103+
}
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)