summaryrefslogtreecommitdiff
path: root/2024/aoc2024-d22.py
diff options
context:
space:
mode:
Diffstat (limited to '2024/aoc2024-d22.py')
-rw-r--r--2024/aoc2024-d22.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/2024/aoc2024-d22.py b/2024/aoc2024-d22.py
new file mode 100644
index 0000000..5c4c809
--- /dev/null
+++ b/2024/aoc2024-d22.py
@@ -0,0 +1,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);