diff --git a/day 22/day_22_felix.cpp b/day 22/day_22_felix.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1c503dfe59fe1b37ab60ed870ce3f8fb2206c5b4 --- /dev/null +++ b/day 22/day_22_felix.cpp @@ -0,0 +1,136 @@ +/* +Usage: + g++ -o main day_X_felix.cpp (or compile however you like) + ./main < input.txt (pipe the input) + + Options: + -d : debug mode +*/ + +#include <bits/stdc++.h> +using namespace std; +bool DEBUG = false; + +// Standard definitions for many problems +#define coord pair <int, int> +#define ll long long + +vector<ll> STARTING_VALUES; + +ll mix(ll val, ll secret) { + return (val ^ secret); +} + +ll prune(ll secret) { + return secret % 16777216; +} + +ll step(ll val) { + ll secret = val; + secret = prune( mix(secret * 64, secret)); + secret = prune( mix(floor(secret / 32), secret)); + secret = prune( mix(secret * 2048, secret)); + + return secret; +} + +void read_input() { + string line; + while (getline(cin, line)) { + STARTING_VALUES.push_back(stoll(line)); + } +} + +ll part1() { + ll total = 0; + for (ll val : STARTING_VALUES) { + ll secret = val; + for (int i = 0; i < 2000; i++) secret = step(secret); + total += secret; + } + return total; +} + +vector<ll> generate_price_sequence(ll start, int num_steps = 2000) { + vector<ll> prices; + ll secret = start; + prices.push_back(secret % 10); + for (int i = 0; i < num_steps; i++) { + secret = step(secret); + prices.push_back(secret % 10); + } + return prices; +} + +vector<ll> generate_price_changes(vector<ll> prices) { + vector<ll> changes; + for (int i = 0; i < prices.size() - 1; i++) { + changes.push_back(prices[i+1] - prices[i]); + } + return changes; +} + +void print_sequence(array<ll,4> sequence) { + for (ll val : sequence) cout << val << " "; + cout << endl; +} + +ll part2() { + map<array<ll,4>, ll> total_sequence_values; + + // Loop over each monkey + for (ll val : STARTING_VALUES) { + map<array<ll,4>, ll> best_values; + vector<ll> prices = generate_price_sequence(val); + vector<ll> changes = generate_price_changes(prices); + + // Check the best value that each sequence can get for this monkey + // Note to past Felix: Don't find the BEST value, find the FIRST value. + for (int i = 3; i < changes.size(); i++) { + array<ll,4> sequence = {changes[i-3], changes[i-2], changes[i-1], changes[i]}; + + if (best_values.find(sequence) == best_values.end()) { + best_values[sequence] = prices[i+1]; + // } else { // SHIT the monkey takes the first price, not the best... Read before you code, kids. + // best_values[sequence] = max(best_values[sequence], prices[i+1]); + } + } + + // For each sequence, add this up to the total that would be generated + for (auto [sequence, value] : best_values) { + if (total_sequence_values.find(sequence) == total_sequence_values.end()) { + total_sequence_values[sequence] = value; + } else { + total_sequence_values[sequence] += value; + } + } + } + + // Find the best sequence to use + ll total = 0; + for (auto [sequence, value] : total_sequence_values) { + if (value > total) { + total = value; + if (DEBUG) { + cout << "New best sequence: "; + print_sequence(sequence); + cout << " Value: " << value << endl; + } + } + } + return total; +} + +int main (int argc, char* argv[]) { + for (int i = 0; i < argc; i++) if (string(argv[i]) == "-d") DEBUG = true; + + read_input(); + + ll p1 = part1(); + cout << "Part 1: " << p1 << endl; + + ll p2 = part2(); + cout << "Part 2: " << p2 << endl; + + return 0; +} \ No newline at end of file