1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
#advent of code day 22
#day 22
#first puzzle I did after getting filtered by day 19
#easy enough, just needed to calculate the prices per sequences
#before calculating the sums to speed things up
#for part 1 jsut calculate the new secret number after 2000 iterations
#for part 2: make 2 dictionaries with secret number indexes as keys
#each value in both dictionaries are lists
#1 dictionary is for how prices are changing, the other one is current prices
#make a set of all possible sequences from all secret keys based on price change dictionary
#make a 3rd dictionary which has secret number as key and another dictionary as value
#the nested dictionary contains prices based on a sequence
#after that just iterate over the set of possible sequences make a sum
#of the prices for that sequence, choose the highest
#one thing that lead to a wrong answer was that I was constantly updating
#the price in 3rd dictionary, but according to problem descriptions
#monkeys sell the first time the sequence occurs, which means I needed to
#only register the price once, then skip the sequence next time it occurs in
#given secret number
SecretNumbers = [int(l) for l in open("22.in","r").read().strip().split("\n")];
def CalcSecret(previous_number):
next_number = (previous_number<<6)^previous_number;
next_number = next_number%16777216;
next_number = (next_number>>5)^next_number;
next_number = next_number%16777216;
next_number = (next_number<<11)^next_number;
next_number = next_number%16777216;
return next_number;
print("please wait 1/3");
part1 = 0;
step = 2000;
changes = {};
prices = {};
#calculate the 2000 iterations of each secret number
#sum up all values of 2000th iteration for part 1
#store the prices of each number for each iteration
#store the change in price of each number for each iteration
for num_i,num in enumerate(SecretNumbers):
num_old = 0 + num;
changes[num_i] = [];
prices[num_i] = [];
prices[num_i].append(num%10);
for s in range(step):
num_new = CalcSecret(num_old);
changes[num_i].append(num_new%10-num_old%10);
prices[num_i].append(num_new%10);
num_old = 0 + num_new;
part1 += num_old;
print("please wait 2/3");
#create a set of all possible sequences
#store the price of a secret number when given sequence occurs
prices_per_seq = {};
sequences = set();
for num_i in changes:
prices_per_seq[num_i] = {};
for j in range(3,len(changes[num_i])):
subseq = tuple(changes[num_i][j-3:j+1]);
sequences.add(subseq);
price_sub = prices[num_i][j+1];
if subseq in prices_per_seq[num_i]: continue;
prices_per_seq[num_i][subseq] = price_sub + 0;
print("please wait 3/3");
#for each sequence calculate the sum of prices for each secret number
#when given sequence occurs. Store the highest sum for part 2
part2 = 0;
for s_i,sequence in enumerate(sequences):
print(s_i+1,"/",len(sequences)); #to make sure the code still runs
score = 0;
for num_i in prices_per_seq:
score += prices_per_seq[num_i].get(sequence,0);
part2 = max(score,part2);
print("part 1 =", part1);
print("part 2 =", part2);
|