Skip to content

Commit 60b3091

Browse files
committed
Completed day 18 of year 2024
1 parent af9ed83 commit 60b3091

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

2024/18.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
from heapq import heappop, heappush
5+
6+
def parse(data):
7+
points = []
8+
for point in data.split('\n'):
9+
x, y = point.split(',')
10+
points.append((int(x), int(y)))
11+
12+
return points
13+
14+
split_data = parse
15+
completed = True
16+
raw_data = None # Not To be touched
17+
18+
def part1(data):
19+
movements = [(0, -1), (0, 1), (1, 0), (-1, 0)]
20+
mapSize = 71
21+
goal = (70,70)
22+
corrupted = data[:1024]
23+
24+
25+
seen = set()
26+
queue = [(0,0,0, [(0,0)])]
27+
while len(queue) > 0:
28+
x, y, steps, path = queue.pop(0)
29+
30+
for dx, dy in movements:
31+
nx, ny = x + dx, y + dy
32+
if not (0 <= nx < mapSize and 0 <= ny < mapSize): continue
33+
if (nx, ny) in seen: continue
34+
if (nx, ny) in corrupted: continue
35+
if (nx, ny) == goal:
36+
# plot(path+[goal], corrupted, mapSize)
37+
return steps+1
38+
39+
seen.add((nx, ny))
40+
queue.append((nx, ny, steps+1, path+[(nx, ny)]))
41+
42+
print(seen)
43+
print(f"WTF? We saw {len(seen)} locations and still haven't seen the goal!")
44+
45+
def plot(path, walls, size):
46+
for y in range(size):
47+
for x in range(size):
48+
if (x, y) in walls:
49+
print('#', end='')
50+
elif (x, y) in path:
51+
print('O', end='')
52+
else:
53+
print('.', end='')
54+
print()
55+
56+
def hasPath(start, end, blocked, bounds):
57+
# Since we don't care much about optimality, this we will implement the A* algorithm
58+
movements = [(0, -1), (0, 1), (1, 0), (-1, 0)]
59+
(sx, sy), (ex, ey) = start, end
60+
61+
seen = set()
62+
queue = [(abs(ex-sx)+abs(ey-sy), sx, sy, id(0), [sx, sy])] # Heuristic, x, y, unique, path
63+
while len(queue) > 0:
64+
_, x, y, _, path = heappop(queue)
65+
66+
for dx, dy in movements:
67+
nx, ny = x + dx, y + dy
68+
if not (0 <= nx < bounds[0] and 0 <= ny < bounds[1]): continue
69+
if (nx, ny) in seen: continue
70+
if (nx, ny) in blocked: continue
71+
if (nx, ny) == end: return path+[end]
72+
73+
seen.add((nx, ny))
74+
heappush(queue, (abs(ex-nx)+abs(ey-ny), nx, ny, id(0), path+[(nx, ny)]))
75+
76+
return False
77+
78+
def part2(data):
79+
checking = 1024
80+
path = hasPath((0, 0), (70, 70), data[:checking], (71, 71))
81+
while True:
82+
checking += 1
83+
if data[checking-1] in path: # Only update if the current byte disturbs the precalculated path (optimization)
84+
path = hasPath((0, 0), (70, 70), data[:checking], (71, 71))
85+
if path == False:
86+
# plot(hasPath((0, 0), (70, 70), data[:checking-1], (71, 71)), data[:checking], 71)
87+
break
88+
# plot(path, data[:checking], 71)
89+
# print('---')
90+
91+
# if checking % 100 == 0: print(f'{checking/len(data):,.2%}')
92+
93+
return f'{data[checking-1][0]},{data[checking-1][1]}'

0 commit comments

Comments
 (0)