aoc/2018/01/01.py

45 lines
1.2 KiB
Python
Raw Normal View History

2021-05-14 08:53:06 +00:00
with open("input.txt") as f:
lines = f.read().splitlines()
freqs = [int(line) for line in lines]
print("Part 1:", sum(freqs))
## what follows is a O(n log n) solution using modulos to avoid cycling manually.
## personally i just did it in elixir with Stream.cycle()...
from itertools import accumulate
sums = [0] + list(accumulate(freqs))
seen = set()
# check first cycle
for s in sums:
if s in seen:
ans2 = s
seen.add(s)
# check if last element is 0 (can't do mod 0)
tail = sums[-1]
if tail == 0:
ans2 = 0
# calculate mapping of all mods and indexes
sums = sums[:-1] # the last sum is part of the next iteration -- we start at 0
from collections import defaultdict
mods = defaultdict(list)
for i, s in enumerate(sums):
mods[s % tail].append((i,s))
mini, mind, minf = None, None, None
for m in mods.values():
ss = list(sorted(m, key = lambda t: t[1])) # sort by second element of tuple
for i in range(1,len(ss)):
diff = ss[i][1] - ss[i-1][1]
index = ss[i-1][0] if tail > 0 else ss[i][0]
freq = ss[i][1] if tail > 0 else ss[i-1][1]
if mind is None or diff < mind or (diff == mind and index < mini):
mini = index
mind = diff
minf = freq
ans2 = minf
print("Part 2:", ans2)