aoc2016/src/days/d17.rs

95 lines
2.3 KiB
Rust
Raw Normal View History

2024-11-26 22:51:13 +00:00
#![allow(non_upper_case_globals)]
#![allow(unused_imports)]
use md5::Digest;
use crate::prelude::*;
pub type I = &'static str;
pub type O = String;
pub type O2 = usize;
const _cand: [(isize, isize, char); 4] = [(-1, 0, 'U'), (1, 0, 'D'), (0, -1, 'L'), (0, 1, 'R')];
fn _open_doors ((y, x): (usize, usize), digest: Digest) -> Vec<(usize, usize, char)> {
let repr = format!("{:x}", digest);
let access: [char; 4] = repr.chars().take(4).collect_vec().try_into().unwrap();
_cand.iter()
.enumerate()
.filter_map(|(i, &(dy, dx, n))| match (y.checked_add_signed(dy), x.checked_add_signed(dx)) {
(Some(y), Some(x)) => if y <= 3 && x <= 3 { Some((y, x, n, i)) } else { None },
_ => None
})
.filter(|(_, _, _, idx)| ('b'..='f').contains(&access[*idx]))
.map(|(a, b, c, _)| (a, b, c))
.collect()
}
fn _digest (pass: &'static str, i: &str) -> Digest {
let full = format!("{pass}{i}");
md5::compute(full)
}
fn _dfs (cur: (usize, usize), path: &mut String, pass: &'static str) -> bool {
if cur == (3, 3) { return true; } else {
let digest = _digest(pass, &path);
let doors = _open_doors(cur, digest);
for (ny, nx, p) in doors {
path.push(p);
if _dfs((ny, nx), path, pass) {
return true;
} else {
path.pop();
}
}
return false;
}
}
fn _dfs_max (cur: (usize, usize), path: &mut String, pass: &'static str, max: &mut usize) {
if cur == (3, 3) {
*max = (*max).max(path.len());
} else {
let digest = _digest(pass, &path);
let doors = _open_doors(cur, digest);
for (ny, nx, p) in doors {
path.push(p);
_dfs_max((ny, nx), path, pass, max);
path.pop();
}
}
}
fn _silver (data: I) -> O {
let mut path = String::new();
_dfs((0, 0), &mut path, data);
path
}
fn _gold (data: I) -> O2 {
let mut path = String::new();
let mut max = 0;
_dfs_max((0, 0), &mut path, data, &mut max);
max
}
#[cfg(test)]
mod test {
use super::*;
const pass: &'static str = "edjrjqaa";
#[test]
fn silver () {
let ans = _silver(pass);
assert_eq!(ans, s!("DUDRDLRRRD"))
}
#[test]
fn gold () {
let ans = _gold(pass);
assert_eq!(ans, 502)
}
}