From f8101a5155e65c39d3f1702bce280cfa96e9968f Mon Sep 17 00:00:00 2001 From: daviddoji Date: Wed, 17 May 2023 07:52:37 +0200 Subject: [PATCH] Solution to Problem 14 in Python --- src/Year_2015/P14.py | 91 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/Year_2015/P14.py diff --git a/src/Year_2015/P14.py b/src/Year_2015/P14.py new file mode 100644 index 0000000..e8b0899 --- /dev/null +++ b/src/Year_2015/P14.py @@ -0,0 +1,91 @@ +# --- Day 14: Reindeer Olympics --- + +# This year is the Reindeer Olympics! Reindeer can fly at high speeds, but must +# rest occasionally to recover their energy. Santa would like to know which of +# his reindeer is fastest, and so he has them race. + +# Reindeer can only either be flying (always at their top speed) or resting +# (not moving at all), and always spend whole seconds in either state. + +# For example, suppose you have the following Reindeer: + +# Comet can fly 14 km/s for 10 seconds, but then must rest for 127 seconds. +# Dancer can fly 16 km/s for 11 seconds, but then must rest for 162 seconds. + +# After one second, Comet has gone 14 km, while Dancer has gone 16 km. After ten +# seconds, Comet has gone 140 km, while Dancer has gone 160 km. On the eleventh +# second, Comet begins resting (staying at 140 km), and Dancer continues on for +# a total distance of 176 km. On the 12th second, both reindeer are resting. +# They continue to rest until the 138th second, when Comet flies for another ten +# seconds. On the 174th second, Dancer flies for another 11 seconds. + +# In this example, after the 1000th second, both reindeer are resting, and Comet +# is in the lead at 1120 km (poor Dancer has only gotten 1056 km by that point). +# So, in this situation, Comet would win (if the race ended at 1000 seconds). + +# Given the descriptions of each reindeer (in your puzzle input), after exactly +# 2503 seconds, what distance has the winning reindeer traveled? + +import re + +with open("files/P14.txt") as f: + reindeers = [line for line in f.read().strip().split("\n")] + +reindeers_dict = {} +for reindeer in reindeers: + reindeers_dict[reindeer.split()[0]] = list( + map(int, re.findall(r"\d+", reindeer)) + ) + + +def part_1(): + dist = {} + for reindeer, (kms, s1, s2) in reindeers_dict.items(): + dist[reindeer] = ( + 2503 // (s1 + s2) * (kms * s1) + min(s1, 2503 % (s1 + s2)) * kms + ) + print(f"The winning reindeer traveled {max(dist.values())} kms") + + +# --- Part Two --- + +# Seeing how reindeer move in bursts, Santa decides he's not pleased with the +# old scoring system. + +# Instead, at the end of each second, he awards one point to the reindeer +# currently in the lead. (If there are multiple reindeer tied for the lead, they +# each get one point.) He keeps the traditional 2503 second time limit, of +# course, as doing otherwise would be entirely ridiculous. + +# Given the example reindeer from above, after the first second, Dancer is in +# the lead and gets one point. He stays in the lead until several seconds into +# Comet's second burst: after the 140th second, Comet pulls into the lead and +# gets his first point. Of course, since Dancer had been in the lead for the 139 +# seconds before that, he has accumulated 139 points by the 140th second. + +# After the 1000th second, Dancer has accumulated 689 points, while poor Comet, +# our old champion, only has 312. So, with the new scoring system, Dancer would +# win (if the race ended at 1000 seconds). + +# Again given the descriptions of each reindeer (in your puzzle input), after +# exactly 2503 seconds, how many points does the winning reindeer have? + + +def part_2(): + dist = {} + points = {reindeer: 0 for reindeer in reindeers_dict} + for sec in range(1, 2504): + for reindeer, (kms, s1, s2) in reindeers_dict.items(): + dist[reindeer] = ( + sec // (s1 + s2) * (kms * s1) + min(s1, sec % (s1 + s2)) * kms + ) + maximum = max(dist.values()) + for reindeer, value in dist.items(): + if value == maximum: + points[reindeer] += 1 + print(f"The winning reindeer has {max(points.values())} points") + + +if __name__ == "__main__": + part_1() + part_2()