1use crate::util::iter::*;
6use crate::util::parse::*;
7
8type Reindeer = [u32; 3];
9
10pub fn parse(input: &str) -> Vec<Reindeer> {
11 input.iter_unsigned().chunk::<3>().collect()
12}
13
14pub fn part1(input: &[Reindeer]) -> u32 {
15 part1_testable(input, 2503)
16}
17
18pub fn part2(input: &[Reindeer]) -> u32 {
19 part2_testable(input, 2503)
20}
21
22pub fn part1_testable(input: &[Reindeer], time: u32) -> u32 {
23 input.iter().map(|&r| distance(r, time)).max().unwrap()
24}
25
26pub fn part2_testable(input: &[Reindeer], time: u32) -> u32 {
27 let mut scores = vec![0; input.len()];
28 let mut distances = vec![0; input.len()];
29
30 for minute in 1..=time {
31 let mut furthest = 0;
32
33 for (index, &reindeer) in input.iter().enumerate() {
34 let next = distance(reindeer, minute);
35 distances[index] = next;
36 furthest = furthest.max(next);
37 }
38
39 for (score, &distance) in scores.iter_mut().zip(distances.iter()) {
40 *score += (distance == furthest) as u32;
41 }
42 }
43
44 *scores.iter().max().unwrap()
45}
46
47fn distance([speed, fly, rest]: Reindeer, time: u32) -> u32 {
48 let cycle_time = fly + rest;
49 let complete = time / cycle_time;
50 let partial = (time % cycle_time).min(fly);
51
52 speed * (fly * complete + partial)
53}