main.rs (2365B)
1 use std::collections::HashMap;
2
3 fn main() {
4 let input = std::fs::read_to_string("input.txt")
5 .unwrap()
6 .trim()
7 .split('\n')
8 .map(|s| s.parse::<i32>().unwrap())
9 .collect::<Vec<i32>>();
10 // 7228
11 println!("Part 1: {}", part_2(&input, 1, 1));
12 // 4526232706281
13 println!("Part 2: {}", part_2(&input, 811589153, 10));
14 }
15
16 fn mix(input: &Vec<i32>, prev_id: &mut Vec<usize>, next_id: &mut Vec<usize>) {
17 let max_step = input.len() as i32 - 1;
18 for id in 0..input.len() {
19 let fwd_steps = ((input[id] % max_step) + max_step) % max_step;
20 if fwd_steps == 0 {
21 continue;
22 }
23 let dest_prev_id = {
24 let mut tmp = id;
25 for _ in 0..fwd_steps {
26 tmp = next_id[tmp];
27 }
28 tmp
29 };
30 let dest_next_id = next_id[dest_prev_id];
31 let src_prev_id = prev_id[id];
32 let src_next_id = next_id[id];
33 next_id[src_prev_id] = src_next_id;
34 prev_id[src_next_id] = src_prev_id;
35 next_id[dest_prev_id] = id;
36 prev_id[id] = dest_prev_id;
37 next_id[id] = dest_next_id;
38 prev_id[dest_next_id] = id;
39 }
40 }
41
42 fn part_2(input: &Vec<i32>, key: i32, mix_count: usize) -> i128 {
43 let max_step = input.len() as i32 - 1;
44 let mut prev_id = Vec::new();
45 let mut next_id = Vec::new();
46 let mut input_scaled = Vec::new();
47 for i in 0..input.len() {
48 prev_id.push(if i == 0 { input.len() - 1 } else { i - 1 });
49 next_id.push((i + 1) % input.len());
50 input_scaled.push((input[i] * (key % max_step)) % max_step);
51 }
52
53 for _ in 0..mix_count {
54 mix(&input_scaled, &mut prev_id, &mut next_id);
55 }
56
57 let zero_id = input.iter().position(|&x| x == 0).unwrap();
58 let groove_id_1 = {
59 let mut tmp = zero_id;
60 for _ in 0..(1000 % input.len()) {
61 tmp = next_id[tmp];
62 }
63 tmp
64 };
65 let groove_id_2 = {
66 let mut tmp = groove_id_1;
67 for _ in 0..(1000 % input.len()) {
68 tmp = next_id[tmp];
69 }
70 tmp
71 };
72 let groove_id_3 = {
73 let mut tmp = groove_id_2;
74 for _ in 0..(1000 % input.len()) {
75 tmp = next_id[tmp];
76 }
77 tmp
78 };
79
80 (input[groove_id_1] + input[groove_id_2] + input[groove_id_3]) as i128 * key as i128
81 }