aoc/year2015/
day14.rs

1//! # Reindeer Olympics
2//!
3//! In order to make things easier we create a function to calculate the distance travelled by a
4//! reindeer at any arbitrary time.
5use 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 score = vec![0; input.len()];
28    let mut distances = vec![0; input.len()];
29
30    for minute in 1..time {
31        let mut lead = 0;
32
33        for (index, &reindeer) in input.iter().enumerate() {
34            let next = distance(reindeer, minute);
35            distances[index] = next;
36            lead = lead.max(next);
37        }
38
39        for (index, &distance) in distances.iter().enumerate() {
40            if distance == lead {
41                score[index] += 1;
42            }
43        }
44    }
45
46    *score.iter().max().unwrap()
47}
48
49fn distance([speed, fly, rest]: Reindeer, time: u32) -> u32 {
50    let total = fly + rest;
51    let complete = time / total;
52    let partial = (time % total).min(fly);
53
54    speed * (fly * complete + partial)
55}