day-16.rs (1547B)
1 fn main() {
2 let input = std::fs::read_to_string("input.txt")
3 .unwrap()
4 .trim()
5 .chars()
6 .map(|ch| ch.to_digit(10).unwrap() as i32)
7 .collect::<Vec<i32>>();
8 println!("Rust:");
9 println!("Part 1: {}", part_1(&input));
10 println!("Part 2: {}", part_2(&input));
11 }
12
13 fn fft(signal: &mut Vec<i32>) {
14 let pattern = [0, 1, 0, -1];
15 for i in 0..signal.len() {
16 let mut curr_signal = 0;
17 for j in i..signal.len() {
18 curr_signal += pattern[(j + 1) / (i + 1) % pattern.len()] * signal[j];
19 }
20 signal[i] = curr_signal.abs() % 10;
21 }
22 }
23
24 fn digits_to_num(digits: &[i32]) -> i32 {
25 digits.iter().fold(0, |acc, digit| acc * 10 + digit)
26 }
27
28 fn part_1(input: &Vec<i32>) -> i32 {
29 let mut signal = input.clone();
30 for _ in 0..100 {
31 fft(&mut signal);
32 }
33 digits_to_num(&signal[..8])
34 }
35
36 fn part_2(input: &Vec<i32>) -> i32 {
37 let offset = digits_to_num(&input[..7]) as usize;
38 // We only care about signal beyond the offset.
39 let mut signal = (offset..(10000 * input.len()))
40 .map(|i| input[i % input.len()])
41 .collect::<Vec<_>>();
42 // Since this will be in latter half of the signal, the only pattern we see
43 // is i 0s and (n - i) 1s.
44 for _ in 0..100 {
45 signal = signal
46 .iter()
47 .rev()
48 .scan(0, |acc, &x| {
49 *acc += x;
50 Some(*acc % 10)
51 })
52 .collect();
53 signal.reverse();
54 }
55 digits_to_num(&signal[..8])
56 }