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