Solve 2024:20 p1-2 "Race Condition"

BFS to get the path from start to end.

pt 1 took some time to wrap around, and initial
versions of the code used defaultdict() to keep
counts of all cheats to check if the example
puzzle input gace the right counts for the cheats.

But since only 100 or more was requested, a counter
do the job in the final version of the code.

For pt 2, a permutation is used.
This commit is contained in:
Anders Englöf Ytterström 2024-12-27 19:40:14 +01:00
parent 14520a4625
commit 0500ac41ab
2 changed files with 74 additions and 0 deletions

View file

@ -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

View file

@ -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)