advent_of_code/year2020/
day15.rs1use crate::input::Input;
2
3pub fn solve(input: &Input) -> Result<u32, String> {
4 const NEVER_SEEN: u32 = 0;
5
6 let target_turn: u32 = input.part_values(2020, 30_000_000);
7 let mut value_to_turn: Vec<u32> = vec![0; target_turn as usize];
8 let mut next_number = 0;
9 let mut turn = 0;
10
11 for (idx, parsed_starting_number) in input
12 .text
13 .split(',')
14 .map(|s| {
15 s.parse::<u32>()
16 .map_err(|error| format!("Invalid input: {error}"))
17 })
18 .enumerate()
19 {
20 let starting_number = parsed_starting_number?;
21 if starting_number > target_turn {
22 return Err(format!("Too high starting number: {starting_number}"));
23 }
24 next_number = starting_number;
25 value_to_turn[next_number as usize] = (idx + 1) as u32;
26 turn += 1;
27 }
28
29 while turn != target_turn {
30 if next_number >= target_turn {
31 return Err(format!("Too big number: {next_number}"));
32 }
33
34 let last_spoken_turn = std::mem::replace(&mut value_to_turn[next_number as usize], turn);
35
36 next_number = if last_spoken_turn == NEVER_SEEN {
37 0
39 } else {
40 turn - last_spoken_turn
43 };
44
45 turn += 1;
46 }
47
48 Ok(next_number)
49}
50
51#[test]
52pub fn tests() {
53 let example = "0,3,6";
54 test_part_one!(example => 436);
55 test_part_two!(example => 175_594);
56
57 let real_input = include_str!("day15_input.txt");
58 test_part_one!(real_input => 1194);
59 test_part_two!(real_input => 48710);
60}