From 5dca2c96f907741fa79017513ef1744268f5aeb3 Mon Sep 17 00:00:00 2001 From: Parnic Date: Sun, 22 Dec 2024 00:06:53 -0600 Subject: [PATCH] Day 22 Fun with properly executing instructions. --- src/22.cs | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/22.cs diff --git a/src/22.cs b/src/22.cs new file mode 100644 index 0000000..186b1fb --- /dev/null +++ b/src/22.cs @@ -0,0 +1,113 @@ +namespace aoc2024; + +internal class Day22 : Day +{ + private List secretNumbers = []; + internal override void Parse() + { + secretNumbers = [..Util.Parsing.ReadAllLinesAsInts($"{GetDay()}")]; + } + + private long Mix(long num, long secret) + { + var result = num ^ secret; + return result; + } + + private long Prune(long num) + { + var result = aoc2024.Util.Math.Modulo(num, 16777216); + return result; + } + + private long GenerateNext(long initial) + { + var step1 = initial * 64; + var secret = Mix(step1, initial); + secret = Prune(secret); + + var step2 = (long)System.Math.Truncate(secret / 32.0); + secret = Mix(step2, secret); + secret = Prune(secret); + + var step3 = secret * 2048; + secret = Mix(step3, secret); + secret = Prune(secret); + + return secret; + } + + internal override string Part1() + { + long total = 0; + foreach (var num in secretNumbers) + { + var next = num; + for (int i = 0; i < 2000; i++) + { + next = GenerateNext(next); + } + + total += next; + } + + return $"Sum of 2000th numbers: <+white>{total}"; + } + + internal override string Part2() + { + var sequences = new List>(secretNumbers.Count); + var prices = new List>(secretNumbers.Count); + var changes = new List>(secretNumbers.Count); + for (int idx = 0; idx < secretNumbers.Count; idx++) + { + sequences.Add(new List(2000)); + prices.Add(new List(2001)); + changes.Add(new List(2000)); + + var num = secretNumbers[idx]; + var next = num; + var lastPrice = next % 10; + prices[idx].Add(lastPrice); + for (int i = 0; i < 2000; i++) + { + next = GenerateNext(next); + var price = next % 10; + var change = price - lastPrice; + + sequences[idx].Add(next); + prices[idx].Add(price); + changes[idx].Add(change); + + lastPrice = price; + } + } + + var tuplePrices = new List>(secretNumbers.Count); + + for (int i = 0; i < secretNumbers.Count; i++) + { + tuplePrices.Add([]); + for (int j = 0; j < 2000 - 4; j++) + { + var tuple = (changes[i][j], changes[i][j + 1], changes[i][j + 2], changes[i][j + 3]); + var price = prices[i][j + 4]; + tuplePrices[i].TryAdd(tuple, price); + } + } + + var highestPrice = 0L; + // assume the highest sequence exists in the first buyer. works for my input. + foreach (var tuplePrice in tuplePrices[0]) + { + var totalPrice = tuplePrices.Select(p => p.GetValueOrDefault(tuplePrice.Key, 0)).Sum(); + + if (totalPrice > highestPrice) + { + highestPrice = totalPrice; + } + } + + return $"Most bananas I can get: <+white>{highestPrice}"; + } +}