92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
|
#!/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')
|