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