1use crate::util::parse::*;
10use std::fmt::Write as _;
11
12pub fn parse(input: &str) -> &str {
13 input
14}
15
16pub fn part1(input: &str) -> u32 {
17 let lengths: Vec<_> = input.iter_unsigned().collect();
18 let knot = hash(&lengths, 1);
19 knot.iter().take(2).map(|&b| b as u32).product()
20}
21
22pub fn part2(input: &str) -> String {
23 let mut lengths: Vec<_> = input.trim().bytes().map(|b| b as usize).collect();
24 lengths.extend([17, 31, 73, 47, 23]);
25
26 let knot = hash(&lengths, 64);
27 let mut result = String::new();
28
29 for chunk in knot.chunks_exact(16) {
30 let reduced = chunk.iter().fold(0, |acc, n| acc ^ n);
31 let _ = write!(&mut result, "{reduced:02x}");
32 }
33
34 result
35}
36
37fn hash(lengths: &[usize], rounds: usize) -> Vec<u8> {
38 let mut knot: Vec<_> = (0..=255).collect();
39 let mut position = 0;
40 let mut skip = 0;
41
42 for _ in 0..rounds {
43 for &length in lengths {
44 let next = length + skip;
45 knot[0..length].reverse();
46 knot.rotate_left(next % 256);
47 position += next;
48 skip += 1;
49 }
50 }
51
52 knot.rotate_right(position % 256);
54 knot
55}