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