AdventOfCode/2015/14/solution.py

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')