diff --git a/day 20/day_20_felix.cpp b/day 20/day_20_felix.cpp
index 56cfdfadc4cc1ef6c4cbd3074b987a7f66739fa0..02b8c1b8501c4fe4dbf804f870651658c8aef9c4 100644
--- a/day 20/day_20_felix.cpp	
+++ b/day 20/day_20_felix.cpp	
@@ -21,8 +21,7 @@ coord START;
 coord END;
 int N, M = 0;
 array<array<bool, 145>, 145> IS_WALL = {true};
-map<coord, ll> TO_COME;
-map<coord, ll> TO_GO;
+vector <coord> FORWARD_PATH;
 
 void parse_input() {
     string line;
@@ -55,70 +54,60 @@ void parse_input() {
 }
 
 bool in_bounds(coord u) {
-    return u.first >= 0 && u.first < M && u.second >= 0 && u.second < N;
+    bool in = u.first >= 0 && u.first < M && u.second >= 0 && u.second < N;
+    return in && !IS_WALL[u.first][u.second];
 }
 
-vector<coord> neighbors(coord u) {
-    vector<coord> n = {
-        {u.first - 1, u.second},
-        {u.first + 1, u.second},
-        {u.first, u.second - 1},
-        {u.first, u.second + 1}
-    };
-    return n;
+coord move(coord u, char d) {
+    if (d == 'N') return {u.first - 1, u.second};
+    if (d == 'S') return {u.first + 1, u.second};
+    if (d == 'W') return {u.first, u.second - 1};
+    if (d == 'E') return {u.first, u.second + 1};
+    return {-1, -1};
 }
 
-vector<pair<coord,int>> cheat_neighbors(coord u, int cheat_length) {
-    vector<pair<coord,int>> nlist;
-
-    // grab all squares within distance cheat_length that are not in a wall
-    for (int i = -cheat_length; i <= cheat_length; i++) {
-        for (int j = -cheat_length + abs(i); j <= cheat_length - abs(i); j++) {
-            coord n = {u.first + i, u.second + j};
-            if (!in_bounds(n) || IS_WALL[n.first][n.second]) continue;
-            int cost = abs(i) + abs(j);
-            
-            if (cost <= cheat_length) nlist.push_back({n, cost});
-                
-        }
-    }
+coord next(coord u, array<array<bool, 145>, 145> &visited) {
+    coord n = move(u, 'N');
+    if (in_bounds(n) && !visited[n.first][n.second]) return n;
+    n = move(u, 'S');
+    if (in_bounds(n) && !visited[n.first][n.second]) return n;
+    n = move(u, 'W');
+    if (in_bounds(n) && !visited[n.first][n.second]) return n;
+    n = move(u, 'E');
+    if (in_bounds(n) && !visited[n.first][n.second]) return n;
+    return {-1, -1};
+}
 
-    return nlist;
+int dist(coord u, coord v) {
+    return abs(u.first - v.first) + abs(u.second - v.second);
 }
 
 
+vector<coord> bfs(coord start) {
 
-map<coord, ll> bfs(coord start) {
-    queue<tuple<ll, coord>> q;
-    q.push({0, start});
     array<array<bool, 145>, 145> visited = {false};
 
-    ll n_cheats = 0;
-
-    map<coord, ll> costs;
-    costs[start] = 0;
     visited[start.first][start.second] = true;
+    vector<coord> path = {start};
+    coord curr = next(start, visited);
 
-    while (!q.empty()) {
-        auto [c, pos] = q.front(); q.pop();
-
-        for (coord n : neighbors(pos)) if (in_bounds(n) && !IS_WALL[n.first][n.second] && !visited[n.first][n.second]) {
-             q.push({c + 1, n});
-             costs[n] = c + 1;
-             visited[n.first][n.second] = true;
-        }
+    while (curr != END) {
+        visited[curr.first][curr.second] = true;
+        path.push_back(curr);
+        curr = next(curr, visited);
     }
+    path.push_back(END);
 
-    return costs;
+    return path;
 }
 
-ll n_cheats(int cheat_distance, ll baseline) {
+ll n_cheats(int cheat_distance, int improvement_goal) {
     ll n_cheats = 0;
-    for (auto [pos, cost] : TO_COME) if (cost < baseline) {
-        for (auto [cheat_pos, cheat_cost] : cheat_neighbors(pos, cheat_distance)) {
-            if (TO_GO[cheat_pos] + cost + cheat_cost <= baseline) {
-                n_cheats++;
-            }
+    for (int i = 0; i < FORWARD_PATH.size() - improvement_goal; i++) {
+        for (int j = i + improvement_goal; j < FORWARD_PATH.size(); j++) {
+            int d = dist(FORWARD_PATH[i], FORWARD_PATH[j]);
+            if (d > cheat_distance) j += max(d - cheat_distance-1, 0);
+            else if (j - i - d >= improvement_goal) n_cheats++; 
         }
     }
     return n_cheats;
@@ -127,20 +116,19 @@ ll n_cheats(int cheat_distance, ll baseline) {
 int main (int argc, char* argv[]) {
     for (int i = 0; i < argc; i++) if (string(argv[i]) == "-d") DEBUG = true;
     
+    if (DEBUG) cout << "Reading data..." << endl;
     parse_input();
-
-    TO_COME = bfs(START);
-    TO_GO = bfs(END);
-    ll baseline = TO_COME[END];
+    FORWARD_PATH = bfs(START);
+    if (DEBUG) cout << "Data read." << endl;
 
     if (DEBUG) {
-        cout << "Baseline: " << baseline << endl;
+        cout << "Baseline: " << FORWARD_PATH.size() << endl;
     }
 
-    ll part1 = n_cheats(2, baseline - 100);
+    ll part1 = n_cheats(2, 100);
     cout << "Part 1: " << part1 << endl;
 
-    ll part2 = n_cheats(20, baseline - 100);
+    ll part2 = n_cheats(20, 100);
     cout << "Part 2: " << part2 << endl;
 
     return 0;