#!/usr/bin/env python3 import sys def mix_and_prune(secret, result): return (secret ^ result) % 16777216 def prg(secret): nsec = mix_and_prune(secret, secret * 64) nsec = mix_and_prune(nsec, nsec // 32) return mix_and_prune(nsec, nsec * 2048) if __name__ == '__main__': nums = [int(line.strip('\n')) for line in open(sys.argv[1])] # challenge 1 res1 = 0 changes, values = {}, {} change_set = set([]) for n in nums: secret = n changes[n] = [[] for i in range(2000)] values[n] = [0] * 2000 ob = int(str(secret)[-1]) for i in range(2000): secret = prg(secret) bananas = int(str(secret)[-1]) for j in range(i,min(2000,i+4)): changes[n][j].append(bananas - ob) values[n][i] = bananas ob = bananas res1 += secret print(f"challenge 1:\n{res1}\n") # challenge 2 (could be more efficient i guess) res2 = 0 for n in nums: change_set = change_set.union(set([tuple(c) if c[-1] > 1 else () for c in changes[n]])) for c in list(change_set): if c != () and c[-1] > 1 and sum([list(c) in changes[num] for num in nums]) > 100: res2 = max(sum([values[num][changes[num].index(list(c))] if list(c) in changes[num] else 0 for num in nums]), res2) print(f"challenge 2:\n{res2}")