summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2022-09-24 21:29:54 +0200
committerReiner Herrmann <reiner@reiner-h.de>2022-09-24 21:29:54 +0200
commit900be14bba5f0b653756b7d9b1317f45c4204c63 (patch)
tree7c2039c02fb6cb6819605879efaeed686ee8b67c
parent0b15e3afbe4b9cde581efbfb48c666dbb79c049f (diff)
day14
-rw-r--r--inputs/day149
-rw-r--r--src/bin/day14.rs79
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);
+ }
+}