1use utils::md5;
2use utils::prelude::*;
3
4#[derive(Clone, Debug)]
6pub struct Day17 {
7 part1: String,
8 part2: u32,
9}
10
11impl Day17 {
12 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
13 let mut path = input.as_bytes().to_vec();
14 let mut shortest = Vec::new();
15 let mut longest = 0;
16 Self::find_paths(0, 0, &mut path, input.len(), &mut shortest, &mut longest);
17
18 Ok(Self {
19 part1: String::from_utf8(shortest).unwrap(),
20 part2: longest,
21 })
22 }
23
24 fn find_paths(
25 x: u32,
26 y: u32,
27 path: &mut Vec<u8>,
28 prefix_len: usize,
29 shortest_path: &mut Vec<u8>,
30 longest_path: &mut u32,
31 ) {
32 if x == 3 && y == 3 {
33 let path_len = path.len() - prefix_len;
34 if shortest_path.is_empty() || path_len < shortest_path.len() {
35 shortest_path.clear();
36 shortest_path.extend_from_slice(&path[prefix_len..]);
37 }
38 if path_len as u32 > *longest_path {
39 *longest_path = path_len as u32;
40 }
41 return;
42 }
43
44 let [first_u32, ..] = md5::hash(path);
45 if y > 0 && (first_u32 >> 28) & 0xF > 0xA {
46 path.push(b'U');
47 Self::find_paths(x, y - 1, path, prefix_len, shortest_path, longest_path);
48 path.pop();
49 }
50 if y < 3 && (first_u32 >> 24) & 0xF > 0xA {
51 path.push(b'D');
52 Self::find_paths(x, y + 1, path, prefix_len, shortest_path, longest_path);
53 path.pop();
54 }
55 if x > 0 && (first_u32 >> 20) & 0xF > 0xA {
56 path.push(b'L');
57 Self::find_paths(x - 1, y, path, prefix_len, shortest_path, longest_path);
58 path.pop();
59 }
60 if x < 3 && (first_u32 >> 16) & 0xF > 0xA {
61 path.push(b'R');
62 Self::find_paths(x + 1, y, path, prefix_len, shortest_path, longest_path);
63 path.pop();
64 }
65 }
66
67 #[must_use]
68 pub fn part1(&self) -> &str {
69 &self.part1
70 }
71
72 #[must_use]
73 pub fn part2(&self) -> u32 {
74 self.part2
75 }
76}
77
78examples!(Day17 -> (&'static str, u32) [
79 {
80 input: "ihgpwlah",
81 part1: "DDRRRD",
82 part2: 370,
83 },
84 {
85 input: "kglvqrro",
86 part1: "DDUDRLRRUDRD",
87 part2: 492,
88 },
89 {
90 input: "ulqzkmiv",
91 part1: "DRURDRUDDLLDLUURRDULRLDUUDDDRR",
92 part2: 830,
93 },
94]);