#!/usr/bin/env python3 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] i = 0 step = offset + 1 while i + step < len(signal): n = sum(sums[i::4*step]) n -= sum(sums[i+step::4*step]) n -= sum(sums[i+2*step::4*step]) n += sum(sums[i+3*step::4*step]) signal[i] = abs(n)%10 i += 1 step += 1 signal[i:] = [s % 10 for s in sums[i:]] def phase(signal, n, offset=0): for i in range(n): apply_pattern(signal, offset) def preproc(puzzle_input): return list(map(int, puzzle_input)) def partI(signal): signal = signal.copy() phase(signal, 100) return str_of_signal(signal[:8]) def partII(signal): signal = signal * 10**4 offset = int(str_of_signal(signal[:7])) signal = signal[offset:] phase(signal, 100, offset) return str_of_signal(signal[:8])