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 }