#!/usr/bin/env python3 from intcode import defaultlist from operator import mul def str_of_signal(signal): return ''.join(map(str, signal)) def apply_pattern(signal, offset=0): sums = [None] * (len(signal)-1) + [signal[-1]] for i in range(len(signal)-2, -1, -1): sums[i] = sums[i+1] + signal[i] sums = defaultlist(sums, lambda : 0) new = [] for i in range(len(signal)): step = i + offset + 1 n = 0 for block in range(i, len(signal), 4*step): n += sums[block] - sums[block + step] n -= sums[block + 2*step] - sums[block + 3*step] new.append(abs(n)%10) return new def phase(signal, n, offset=0): signal = signal[offset:] for i in range(n): signal = apply_pattern(signal, offset) return signal def preproc(puzzle_input): return list(map(int, puzzle_input)) def partI(signal): return str_of_signal(phase(signal, 100)[:8]) def partII(signal): signal = signal * 10**4 offset = int(str_of_signal(signal[:7])) return str_of_signal(phase(signal, 100, offset)[:8])