diff options
| author | Reiner Herrmann <reiner@reiner-h.de> | 2022-09-24 21:29:54 +0200 |
|---|---|---|
| committer | Reiner Herrmann <reiner@reiner-h.de> | 2022-09-24 21:29:54 +0200 |
| commit | 900be14bba5f0b653756b7d9b1317f45c4204c63 (patch) | |
| tree | 7c2039c02fb6cb6819605879efaeed686ee8b67c | |
| parent | 0b15e3afbe4b9cde581efbfb48c666dbb79c049f (diff) | |
day14
| -rw-r--r-- | inputs/day14 | 9 | ||||
| -rw-r--r-- | src/bin/day14.rs | 79 |
2 files changed, 88 insertions, 0 deletions
diff --git a/inputs/day14 b/inputs/day14 new file mode 100644 index 0000000..2af1170 --- /dev/null +++ b/inputs/day14 @@ -0,0 +1,9 @@ +Vixen can fly 19 km/s for 7 seconds, but then must rest for 124 seconds. +Rudolph can fly 3 km/s for 15 seconds, but then must rest for 28 seconds. +Donner can fly 19 km/s for 9 seconds, but then must rest for 164 seconds. +Blitzen can fly 19 km/s for 9 seconds, but then must rest for 158 seconds. +Comet can fly 13 km/s for 7 seconds, but then must rest for 82 seconds. +Cupid can fly 25 km/s for 6 seconds, but then must rest for 145 seconds. +Dasher can fly 14 km/s for 3 seconds, but then must rest for 38 seconds. +Dancer can fly 3 km/s for 16 seconds, but then must rest for 37 seconds. +Prancer can fly 25 km/s for 6 seconds, but then must rest for 143 seconds. diff --git a/src/bin/day14.rs b/src/bin/day14.rs new file mode 100644 index 0000000..8df62e4 --- /dev/null +++ b/src/bin/day14.rs @@ -0,0 +1,79 @@ +use std::collections::HashMap; +use regex::Regex; + +fn main() { + let input = advent::read_lines(14); + println!("14a: {}", winning_distance(&input, 2503)); + println!("14b: {}", winning_points(&input, 2503)); +} + +struct Reindeer { + name: String, + speed: u32, + duration: u32, + rest: u32, +} + +impl Reindeer { + fn new(input: &str) -> Reindeer { + let re = Regex::new(r"^([A-Za-z]+) can fly ([0-9]+) km/s for ([0-9]+) seconds, but then must rest for ([0-9]+) seconds.$").unwrap(); + let cap = re.captures(input).unwrap(); + let name = cap[1].to_string(); + let speed = cap[2].parse::<u32>().unwrap(); + let duration = cap[3].parse::<u32>().unwrap(); + let rest = cap[4].parse::<u32>().unwrap(); + + Reindeer { name, speed, duration, rest } + } + + fn distance(&self, time: u32) -> u32 { + let cycle_time = self.duration + self.rest; + + let time_flown = (time / cycle_time) * self.duration + + std::cmp::min(self.duration, time % cycle_time); + + time_flown * self.speed + } +} + +fn winning_distance(input: &[String], time: u32) -> u32 { + input.iter() + .map(|line| Reindeer::new(line)) + .map(|reindeer| reindeer.distance(time)) + .max() + .unwrap() +} + +fn winning_points(input: &[String], time: u32) -> u32 { + let reindeers = input.iter() + .map(|line| Reindeer::new(line)) + .collect::<Vec<Reindeer>>(); + let mut scores = HashMap::new(); + + for t in 1..=time { + let mut winner = ("", 0); + for reindeer in &reindeers { + let distance = reindeer.distance(t); + if distance >= winner.1 { + winner = (&reindeer.name, distance); + } + } + *scores.entry(winner.0).or_insert(0) += 1; + } + *scores.values().max().unwrap() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + let input = [ + "Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds.".to_string(), + "Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds.".to_string(), + ]; + assert_eq!(winning_distance(&input, 1000), 1120); + assert_eq!(winning_points(&input, 1000), 689); + } +} |
