diff --git a/2024-python/output/__init__.py b/2024-python/output/__init__.py index 0f69f41..22da24f 100644 --- a/2024-python/output/__init__.py +++ b/2024-python/output/__init__.py @@ -118,6 +118,22 @@ def bfs(S, E=None): # return insights +def mhd_search(r, c, R=20): + """returns all coords that are within R manhattan distance from (r,c)""" + p = set() + for d in range(1, R + 1): + p.add((r, c + d)) + p.add((r, c - d)) + p.add((r + d, c)) + p.add((r - d, c)) + for dd in range(d): + p.add((r - dd, c - d + dd)) + p.add((r + dd, c - d + dd)) + p.add((r - dd, c - dd + d)) + p.add((r + dd, c - dd + d)) + return p + + def dijkstras(grid, start, target): """ 1. Create an array that holds the distance of each vertex from the starting diff --git a/2024-python/output/day_20.py b/2024-python/output/day_20.py new file mode 100644 index 0000000..98ab96b --- /dev/null +++ b/2024-python/output/day_20.py @@ -0,0 +1,58 @@ +from collections import deque + +from output import matrix, D, mhd + + +def solve(data): + grid, H, W = matrix(data) + S = next((r, c) for r in range(H) for c in range(W) if grid[r][c] == "S") + E = next((r, c) for r in range(H) for c in range(W) if grid[r][c] == "E") + seen = set() + Q = deque([(S, 0, [])]) + while Q: + pos, w, path = Q.pop() + r, c = pos + if grid[r][c] == "#" or pos in seen: + continue + seen.add(pos) + if pos == E: + og = path + [(r, c)] + break + for dr, dc in D: + Q.append(((r + dr, c + dc), w + 1, path + [(r, c)])) + + track = {rc: i for i, rc in enumerate(og)} + T = 100 + p1 = 0 + p2 = 0 + + cheats = set() + for r, c in track.keys(): + for dr, dc in D: + rr, cc = r + dr * 2, c + dc * 2 + if ( + (rr, cc) not in cheats + and (rr, cc) in track + and T + 2 <= abs(track[(rr, cc)] - track[(r, c)]) + ): + p1 += 1 + cheats.add((r, c)) + + tk = [k for k in track.keys()] + for b in range(T, len(tk)): + for a in range(b - T): + distance = mhd(tk[a], tk[b]) + if distance <= 20 and b - a - distance >= T: + p2 += 1 + + return p1, p2 + + +if __name__ == "__main__": + with open("./input/20.txt", "r") as f: + inp = f.read().strip() + + p1, p2 = solve(inp) + + print(p1) + print(p2)