Day 22: Monkey Market
Today's puzzle was quite enjoyable as it was fairly straight forward. A lot of what needed doing was in the instructions, i.e some integer manipulation and then a simple sum (at least for Part 1).
Part 1
The code is pretty straight forward, we carry out a loop 2,000 times, each time storing the new secret number, so we can sum them up at the end.
Part 2
Ok so this one took a bit more brain power, but again a lot of the logic was in the instructions.
One of the biggest differences is the calc_price_changes()
function. This function processes a sequence of numbers and just calculates “price changes” to identify patterns.
Let’s dive in closer:
The calc_price_changes
function:
Processes a list of “generated secrets”.
Calculates changes in “prices” (the last digit of each secret).
Identifies unique patterns of 4 consecutive changes.
4.Aggregates a score based on these patterns.
It takes two arguments:
A list of numbers (representing generated secrets) as well as a dictionary-like object (defaultdictcr) to store and aggregate scores for unique patterns.
A defaultdict
is a very useful tool. It works like a normal dictionary but with a key advantage. If it doesn’t find the key within the dictionary it will handle creating the key and assigning it default value of the type passed in.
finding sequence changes of 4
for p in range(len(price_change_sequence) - 4 + 1):
changes = price_change_sequence[p: p + 4]
key = tuple((changes[0][0], changes[1][0], changes[2][0], changes[3][0]))
if key not in sequences:
sequence_sum[key] += changes[3][1]
sequences.add(key)
The above code uses a sliding window 4 to extract groups of 4 consecutive (change, price) tuples.
Example: If price_change_sequence
is [(1, 5), (2, 7), (-1, 6), (3, 9)]
, one “chunk” is [(1, 5), (2, 7), (-1, 6), (3, 9)]
.
We then extract only the change values from the 4-tuple, eg -2,-1,1 etc. If the pattern isn’t already in sequences, it’s a new pattern, so can add the last price (changes[3][1]) to sequence_sum[pattern]. Mark the key as processed by adding it to the sequences set.
At the end of the function:
sequence_sum
contains a mapping of unique (as we used the Set) 4-change patterns to their aggregated scores (based on the final price in each sequence).
Example: {(1, 2, -1, 3): 9, (-2, 0, 1, -1): 6}.
Walkthrough
Let’s say we have an input of
generated_secrets = [45, 46, 50, 53, 58, 61]
sequence_sum = defaultdict(int)
calc_price_changes(generated_secrets, sequence_sum)
Steps:
1.Calculate Price Changes:
Prices: [5, 6, 0, 3, 8, 1]
(last digits).
Changes: [(1, 6), (-6, 0), (3, 3), (5, 8), (-7, 1)]
- Extract 4-Change Patterns: (1, -6, 3, 5) → Add 8 (last price in the pattern) to sequence_sum. (-6, 3, 5, -7) → Add 1 to sequence_sum.
Output:
{(1, -6, 3, 5): 8, (-6, 3, 5, -7): 1}
Wrapping Up
Here’s how it all came together:
Input Processing: We read and converted the input into a list of secret numbers.
Sequence Generation: For each secret, we iteratively evolved it over 2000 generations to produce a sequence of derived values.
Price Change Analysis: We calculated differences between successive prices (last digits) in the sequences, identified unique 4-change patterns, and aggregated scores for those patterns.
Result Extraction: Finally, we determined the most impactful pattern by finding the one with the highest aggregated score.
By breaking the problem into clear, modular steps, we efficiently processed data, tracked patterns, and solved the puzzle.
As always I hope this has helped, and you've learnt something from my solution. Feel free to drop a follow, or reach out on Twitter
Top comments (0)