Skip to content

Commit 1b10902

Browse files
committed
Day 22 Part 2
1 parent c3eece8 commit 1b10902

File tree

4 files changed

+162
-3
lines changed

4 files changed

+162
-3
lines changed

Day_22/README.md

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ The part about secrets is literal, the Historian explains. Each buyer produces a
1414

1515
In particular, each buyer's _secret_ number evolves into the next secret number in the sequence via the following process:
1616

17-
- Calculate the result of _multiplying the secret number by `64`_. Then, _mix_ this result into the secret number. Finally, _prune_ the secret number.
18-
- Calculate the result of _dividing the secret number by `32`_. Round the result down to the nearest integer. Then, _mix_ this result into the secret number. Finally, _prune_ the secret number.
19-
- Calculate the result of _multiplying the secret number by `2048`_. Then, _mix_ this result into the secret number. Finally, _prune_ the secret number.
17+
- Calculate the result of _multiplying the secret number by `64`. Then, _mix_ this result into the secret number. Finally, _prune_ the secret number.
18+
- Calculate the result of _dividing the secret number by `32`. Round the result down to the nearest integer. Then, _mix_ this result into the secret number. Finally, _prune_ the secret number.
19+
- Calculate the result of _multiplying the secret number by `2048`. Then, _mix_ this result into the secret number. Finally, _prune_ the secret number.
2020

2121
Each step of the above process involves _mixing_ and _pruning_:
2222

@@ -67,3 +67,78 @@ For each buyer, simulate the creation of 2000 new secret numbers. _What is the s
6767
Your puzzle answer was `[REDACTED]`.
6868

6969
The first half of this puzzle is complete! It provides one gold star: ⭐
70+
71+
72+
## \--- Part Two ---
73+
74+
Of course, the secret numbers aren't the prices each buyer is offering! That would be ridiculous. Instead, the _prices_ the buyer offers are just the _ones digit_ of each of their secret numbers.
75+
76+
So, if a buyer starts with a secret number of `123`, that buyer's first ten _prices_ would be:
77+
78+
```
79+
3 (from 123)
80+
0 (from 15887950)
81+
6 (from 16495136)
82+
5 (etc.)
83+
4
84+
4
85+
6
86+
4
87+
4
88+
2
89+
```
90+
91+
This price is the number of _bananas_ that buyer is offering in exchange for your information about a new hiding spot. However, you still don't speak [monkey](https://adventofcode.com/2022/day/21), so you can't negotiate with the buyers directly. The Historian speaks a little, but not enough to negotiate; instead, he can ask another monkey to negotiate on your behalf.
92+
93+
Unfortunately, the monkey only knows how to decide when to sell by looking at the _changes_ in price. Specifically, the monkey will only look for a specific sequence of _four consecutive changes_ in price, then immediately sell when it sees that sequence.
94+
95+
So, if a buyer starts with a secret number of `123`, that buyer's first ten secret numbers, prices, and the associated changes would be:
96+
97+
```
98+
123: 3
99+
15887950: 0 (-3)
100+
16495136: 6 (6)
101+
527345: 5 (-1)
102+
704524: 4 (-1)
103+
1553684: 4 (0)
104+
12683156: 6 (2)
105+
11100544: 4 (-2)
106+
12249484: 4 (0)
107+
7753432: 2 (-2)
108+
```
109+
110+
Note that the first price has no associated change because there was no previous price to compare it with.
111+
112+
In this short example, within just these first few prices, the highest price will be `6`, so it would be nice to give the monkey instructions that would make it sell at that time. The first `6` occurs after only two changes, so there's no way to instruct the monkey to sell then, but the second `6` occurs after the changes `-1,-1,0,2`. So, if you gave the monkey that sequence of changes, it would wait until the first time it sees that sequence and then immediately sell your hiding spot information at the current price, winning you `6` bananas.
113+
114+
Each buyer only wants to buy one hiding spot, so after the hiding spot is sold, the monkey will move on to the next buyer. If the monkey _never_ hears that sequence of price changes from a buyer, the monkey will never sell, and will instead just move on to the next buyer.
115+
116+
Worse, you can only give the monkey _a single sequence_ of four price changes to look for. You can't change the sequence between buyers.
117+
118+
You're going to need as many bananas as possible, so you'll need to _determine which sequence_ of four price changes will cause the monkey to get you the _most bananas overall_. Each buyer is going to generate `2000` secret numbers after their initial secret number, so, for each buyer, you'll have `2000` price changes_ in which your sequence can occur.
119+
120+
Suppose the initial secret number of each buyer is:
121+
122+
```
123+
1
124+
2
125+
3
126+
2024
127+
```
128+
129+
There are many sequences of four price changes you could tell the monkey, but for these four buyers, the sequence that will get you the most bananas is `-2,1,-1,3`. Using that sequence, the monkey will make the following sales:
130+
131+
- For the buyer with an initial secret number of `1`, changes `-2,1,-1,3` first occur when the price is `7`.
132+
- For the buyer with initial secret `2`, changes `-2,1,-1,3` first occur when the price is `7`.
133+
- For the buyer with initial secret `3`, the change sequence `-2,1,-1,3` _does not occur_ in the first 2000 changes.
134+
- For the buyer starting with `2024`, changes `-2,1,-1,3` first occur when the price is `9`.
135+
136+
So, by asking the monkey to sell the first time each buyer's prices go down `2`, then up `1`, then down `1`, then up `3`, you would get `23` (`7 + 7 + 9`) bananas!
137+
138+
Figure out the best sequence to tell the monkey so that by looking for that same sequence of changes in every buyer's future prices, you get the most bananas in total. _What is the most bananas you can get?_
139+
140+
Your puzzle answer was `1490`.
141+
142+
Your puzzle answer was `[REDACTED]`.
143+
144+
Both parts of this puzzle are complete! They provide two gold stars: ⭐⭐

Day_22/example_22b.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
2
3+
3
4+
2024

Day_22/task_22b.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
def load_data(filename):
2+
with open(filename, "r") as file:
3+
return [int(row) for row in file.read().splitlines()]
4+
5+
6+
def mix(secret, num):
7+
return secret ^ num
8+
9+
10+
def prune(secret):
11+
return secret % 16777216
12+
13+
14+
def generate_new_secret(old_secret, repeat=1):
15+
changes = dict()
16+
diff = []
17+
for _ in range(repeat):
18+
19+
old_price = int(str(old_secret)[-1])
20+
new_secret = prune(mix(old_secret, old_secret * 64))
21+
new_secret = prune(mix(new_secret, int(new_secret / 32)))
22+
new_secret = prune(mix(new_secret, new_secret * 2048))
23+
24+
old_secret = new_secret
25+
26+
new_price = int(str(new_secret)[-1])
27+
28+
if len(diff) == 4:
29+
diff.pop(0)
30+
31+
diff.append(new_price - old_price)
32+
33+
if len(diff) == 4:
34+
seq = tuple(diff)
35+
if seq in changes:
36+
continue # monkey will only buy on the *first* sequence
37+
changes[seq] = new_price
38+
return new_secret, changes
39+
40+
41+
def merge_dicts(merged, dict2):
42+
for key, value in dict2.items():
43+
if key in merged:
44+
merged[key] += value
45+
else:
46+
merged[key] = value
47+
48+
49+
if __name__ == "__main__":
50+
data = load_data("Day_22/puzzle_input.txt")
51+
repeat = 2000
52+
53+
merged_changes = dict()
54+
for secret in data:
55+
new_secret, changes = generate_new_secret(secret, repeat)
56+
merge_dicts(merged_changes, changes)
57+
58+
print(max(merged_changes, key=merged_changes.get))
59+
print(max(merged_changes.values()))

Day_22/test_task_22b.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from task_22b import mix, prune, generate_new_secret, merge_dicts, load_data
2+
3+
4+
def test_mix():
5+
assert mix(42, 15) == 37
6+
7+
8+
def test_prune():
9+
assert prune(100000000) == 16113920
10+
11+
12+
def test_generate_new_secret():
13+
repeat = 2000
14+
data = load_data("Day_22/example_22b.txt")
15+
merged_changes = dict()
16+
for secret in data:
17+
_, changes = generate_new_secret(secret, repeat)
18+
merge_dicts(merged_changes, changes)
19+
20+
assert max(merged_changes, key=merged_changes.get) == (-2, 1, -1, 3)
21+
assert max(merged_changes.values()) == 23

0 commit comments

Comments
 (0)