Solved 2015/14 P1+P2
This commit is contained in:
parent
4c9a134bd4
commit
4e67cca173
73
2015/14/14.md
Normal file
73
2015/14/14.md
Normal file
@ -0,0 +1,73 @@
|
||||
## \-\-- 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*?
|
||||
|
||||
Your puzzle answer was `2660`.
|
||||
|
||||
## \-\-- Part Two \-\-- {#part2}
|
||||
|
||||
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]{title="It also risks choosing a duration that isn't coprime with the cycle times of each reindeer."}.
|
||||
|
||||
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*?
|
||||
|
||||
Your puzzle answer was `1256`.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars:
|
||||
\*\*
|
||||
|
||||
At this point, you should [return to your Advent calendar](/2015) and
|
||||
try another puzzle.
|
||||
|
||||
If you still want to see it, you can [get your puzzle
|
||||
input](14/input).
|
||||
|
92
2015/14/solution.py
Normal file
92
2015/14/solution.py
Normal file
@ -0,0 +1,92 @@
|
||||
#!/bin/python3
|
||||
import sys,time,re
|
||||
from pprint import pprint
|
||||
sys.path.insert(0, '../../')
|
||||
from fred import list2int,get_re,nprint,lprint,loadFile
|
||||
start_time = time.time()
|
||||
|
||||
input_f = 'input'
|
||||
|
||||
def loadRaindeers(input_f):
|
||||
"""Load raindeer info from file into a dict
|
||||
|
||||
Args:
|
||||
input_f (str): filename
|
||||
|
||||
Returns:
|
||||
dict: Returns a dict of raindeer into
|
||||
"""
|
||||
raindeers = {}
|
||||
with open(input_f) as file:
|
||||
for line in file:
|
||||
match = get_re(r"^(\w+).*fly (\d+).*for (\d+).* for (\d+) seconds.$",line.rstrip())
|
||||
raindeers[match.group(1)] = {
|
||||
'speed': int(match.group(2)),
|
||||
'time': int(match.group(3)),
|
||||
'rest': int(match.group(4)),
|
||||
'distance' : 0,
|
||||
'score': 0
|
||||
}
|
||||
return raindeers
|
||||
|
||||
#########################################
|
||||
# #
|
||||
# Part 1 #
|
||||
# #
|
||||
#########################################
|
||||
def part1():
|
||||
raindeers = loadRaindeers(input_f)
|
||||
print(raindeers)
|
||||
seconds = 2503
|
||||
max_dist = 0
|
||||
for r in raindeers:
|
||||
speed = raindeers[r]['speed']
|
||||
time = raindeers[r]['time']
|
||||
rest = raindeers[r]['rest']
|
||||
|
||||
cycle = (time+rest)
|
||||
number_cycles = seconds//cycle
|
||||
remainder = seconds%cycle
|
||||
distance = speed * (number_cycles*time+min(remainder,time))
|
||||
if distance > max_dist:
|
||||
max_dist = distance
|
||||
return max_dist
|
||||
|
||||
start_time = time.time()
|
||||
print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
||||
|
||||
|
||||
#########################################
|
||||
# #
|
||||
# Part 2 #
|
||||
# #
|
||||
#########################################
|
||||
def part2():
|
||||
raindeers = loadRaindeers(input_f)
|
||||
|
||||
seconds = 2503
|
||||
for i in range(1,seconds+1):
|
||||
|
||||
for r in raindeers:
|
||||
speed = raindeers[r]['speed']
|
||||
time = raindeers[r]['time']
|
||||
rest = raindeers[r]['rest']
|
||||
|
||||
cycle = (time+rest)
|
||||
|
||||
# Cycle 0 to time+rest, but distance is only updated while
|
||||
# the cycle is less than time.
|
||||
if i % cycle <= time and i % cycle != 0:
|
||||
raindeers[r]['distance'] += speed
|
||||
|
||||
current_winner = max(raindeers[r]['distance'] for r in raindeers)
|
||||
ties = [k for k, r in raindeers.items() if r['distance'] == current_winner]
|
||||
|
||||
for t in ties:
|
||||
|
||||
raindeers[t]['score'] += 1
|
||||
|
||||
return max(raindeers[r]['score'] for r in raindeers)
|
||||
|
||||
start_time = time.time()
|
||||
print('Part 2:',part2(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
Loading…
Reference in New Issue
Block a user