In [120]:
import csv
from collections import defaultdict
def parse_scanners(input_file):
scanners = defaultdict(int)
with open(input_file, 'rt') as f_input:
csv_reader = csv.reader(f_input, delimiter=' ')
for l in csv_reader:
scanners[int(l[0].rstrip(':'))] = int(l[1].rstrip())
return scanners
In [175]:
def tick(lrank, time):
r = time % (2 * (lrank - 1))
return (r <= lrank - 1) * r + (r > lrank - 1) * (2 * (lrank - 1) - r)
def get_state(time, scanners):
state = dict(zip(list(scanners.keys()), [0] * len(scanners)))
if time == 0:
return state
elif time > 0:
for t in range(time + 1):
for scanner in scanners:
state[scanner] = tick(scanners[scanner], t)
return state
Some nice time-lapse plotting :)
In [221]:
from time import sleep
def print_state(time, scanners):
stt = get_state(time + 1, scanners)
depths = range(max(list(scanners.keys())) + 1)
depths_printable = '\t'.join(map(str, depths))
print(depths_printable)
max_range = max(list(scanners.values()))
printable = '\t'.join(['(S)' if ((scanners[j] >= 1) and (stt[j] == 0) and (time == j)) \
else '[S]' if ((scanners[j] >= 1) and (stt[j] == 0) and (time != j)) \
else '( )' if ((scanners[j] >= 1) and (stt[j] != 0) and (time == j)) \
else '[ ]' if ((scanners[j] >= 1) and (stt[j] != 0) and (time != j)) \
else '(.)' if (time == j) \
else '...' for j in depths])
print(printable)
for i in range(2, max_range + 1):
printable = '\t'.join(['[S]' if ((scanners[j] >= i) and (stt[j] == i-1)) \
else '[ ]' if ((scanners[j] >= i) and (stt[j] != i-1)) \
else ' ' for j in depths])
print(printable)
def timelapse(input_path):
scanners = parse_scanners(input_path)
for t in range(max(list(scanners.keys())) + 10):
if t > 0: sleep(1)
print('After Picosecond {}:'.format(t))
print_state(t, scanners)
In [222]:
timelapse('input.test1.txt')
Trip severity calculator:
In [187]:
def trip_severity(input_path):
severity = 0
scanners = parse_scanners(input_path)
layers = max(list(scanners.keys()))
for t in range(layers + 1):
if scanners[t] != 0:
tick_before = tick(scanners[t], t)
tick_now = tick(scanners[t], t + 1)
if (tick_before == 0):
severity += scanners[t] * t
return severity
In [188]:
assert(trip_severity('input.test1.txt') == 24)
In [189]:
trip_severity('input.txt')
Out[189]:
In [303]:
def trip_caught_delayed(delay):
severity = 0
caught = False
layers = max(list(scanners.keys()))
for t in range(0, layers + 1):
if scanners[t] != 0:
tick_before = tick(scanners[t], t + delay)
if (tick_before == 0):
caught = True
severity += scanners[t] * t
return caught
In [304]:
def minimum_delay():
delay = 0
while trip_caught_delayed(delay):
delay += 1
return delay
In [308]:
%%time
scanners = parse_scanners('input.test1.txt')
trip_caught_delayed(10)
In [309]:
%%time
minimum_delay()
Out[309]:
In [311]:
%%time
scanners = parse_scanners('input.txt')
print(minimum_delay())
In [349]:
def alt_minimum_delay():
delay = 0
caught = True
layers = list(scanners.keys())
while (delay >= 0) and caught:
caught = False
for j in layers:
if (delay + 1 + j) % (2 * scanners[j] - 2) == 0:
caught = True
delay += 1
return delay
In [352]:
%%time
scanners = parse_scanners('input.test1.txt')
print(alt_minimum_delay())
In [354]:
%%time
scanners = parse_scanners('input.txt')
print(alt_minimum_delay())