solution: day 17

This commit is contained in:
YK 2024-11-27 01:51:13 +03:00
parent 728a14855a
commit 350f6ef6eb
2 changed files with 95 additions and 1 deletions

View File

@ -14,7 +14,7 @@ pub mod d13;
pub mod d14;
pub mod d15;
pub mod d16;
// pub mod d17;
pub mod d17;
// pub mod d18;
// pub mod d19;
// pub mod d20;

94
src/days/d17.rs Normal file
View File

@ -0,0 +1,94 @@
#![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)
}
}