1-
2-
31# This v1 works for part 1, not part 2
42# Since it's also quite slow, I've done a v2 that should be better
53
64
7-
8-
9-
10-
115# -------------------------------- Input data -------------------------------- #
126import os ,pathfinding ,re
137
148test_data = {}
159
1610test = 1
17- test_data [test ]= {"input" :"""/->-\\
11+ test_data [test ]= {
12+ "input" :"""/->-\\
1813| | /----\\
1914| /-+--+-\ |
2015| | | | v |
2116\-+-/ \-+--/
2217 \------/ """ ,
23- "expected" : [' Unknown' , ' Unknown' ],
24- }
18+ "expected" : [" Unknown" , " Unknown" ],
19+ }
2520
2621test += 1
27- test_data [test ]= {"input" :r"""/>-<\
22+ test_data [test ]= {
23+ "input" :r"""/>-<\
2824| |
2925| /<+-\
3026| | | v
3127\>+</ |
3228 | ^
3329 \<->/""" ,
34- "expected" : ['Unknown' ,'Unknown' ],
35- }
36-
37- test = 'real'
38- input_file = os .path .join (os .path .dirname (__file__ ),'Inputs' ,os .path .basename (__file__ ).replace ('.py' ,'.txt' ))
39- test_data [test ]= {"input" :open (input_file ,"r+" ).read (),
40- "expected" : ['124,130' ,'99, 96' ],
41- }
30+ "expected" : ["Unknown" ,"Unknown" ],
31+ }
32+
33+ test = "real"
34+ input_file = os .path .join (
35+ os .path .dirname (__file__ ),
36+ "Inputs" ,
37+ os .path .basename (__file__ ).replace (".py" ,".txt" ),
38+ )
39+ test_data [test ]= {
40+ "input" :open (input_file ,"r+" ).read (),
41+ "expected" : ["124,130" ,"99, 96" ],
42+ }
4243
4344# -------------------------------- Control program execution -------------------------------- #
4445
45- case_to_test = ' real'
46+ case_to_test = " real"
4647part_to_test = 2
4748
4849# -------------------------------- Initialize some variables -------------------------------- #
4950
50- puzzle_input = test_data [case_to_test ][' input' ]
51- puzzle_expected_result = test_data [case_to_test ][' expected' ][part_to_test - 1 ]
52- puzzle_actual_result = ' Unknown'
51+ puzzle_input = test_data [case_to_test ][" input" ]
52+ puzzle_expected_result = test_data [case_to_test ][" expected" ][part_to_test - 1 ]
53+ puzzle_actual_result = " Unknown"
5354
5455
5556# -------------------------------- Actual code execution -------------------------------- #
5657
5758
58- def grid_to_vertices (self ,grid ,wall = '#' ):
59+ def grid_to_vertices (self ,grid ,wall = "#" ):
5960self .vertices = []
6061track = {}
6162y = 0
6263
6364for line in grid .splitlines ():
64- line = line .replace ('^' ,'|' ).replace ('v' ,'|' ).replace ('>' ,'-' ).replace ('<' ,'-' )
65+ line = (
66+ line .replace ("^" ,"|" ).replace ("v" ,"|" ).replace (">" ,"-" ).replace ("<" ,"-" )
67+ )
6568for x in range (len (line )):
6669if line [x ]!= wall :
6770self .vertices .append ((x ,y ))
6871track [(x ,y )]= line [x ]
6972
7073y += 1
7174
72- directions = [(1 ,0 ), (- 1 ,0 ), (0 ,1 ), (0 ,- 1 )]
73- right ,left ,down ,up = directions
75+ north = 1j
76+ south = - 1j
77+ west = - 1
78+ east = 1
79+
80+ directions = [north ,south ,west ,east ]
7481
75- for coords in self .vertices :
82+ for source in self .vertices :
7683for direction in directions :
77- x , y = coords [ 0 ] + direction [ 0 ], coords [ 1 ] + direction [ 1 ]
84+ target = source + direction
7885
79- if track [coords ]== '-' and direction in [up , down ]:
86+ if track [source ]== "-" and direction in [north , south ]:
8087continue
81- if track [coords ]== '|' and direction in [left , right ]:
88+ if track [source ]== "|" and direction in [west , east ]:
8289continue
8390
84- if ( x , y ) in self .vertices :
85- if track [coords ]in (' \\ ' , '/' ):
86- if track [( x , y ) ]in (' \\ ' , '/' ):
91+ if target in self .vertices :
92+ if track [source ]in (" \\ " , "/" ):
93+ if track [target ]in (" \\ " , "/" ):
8794continue
88- if track [( x , y ) ]== '-' and direction in [up , down ]:
95+ if track [target ]== "-" and direction in [north , south ]:
8996continue
90- elif track [( x , y ) ]== '|' and direction in [left , right ]:
97+ elif track [target ]== "|" and direction in [west , east ]:
9198continue
92- if coords in self .edges :
93- self .edges [(coords )].append (( x , y ) )
99+ if source in self .edges :
100+ self .edges [(source )].append (target )
94101else :
95- self .edges [(coords )]= [( x , y ) ]
102+ self .edges [(source )]= [target ]
96103
97104return True
98105
99- pathfinding .Graph .grid_to_vertices = grid_to_vertices
100106
101- def turn_left (direction ):
102- return (direction [1 ],- direction [0 ])
107+ pathfinding .Graph .grid_to_vertices = grid_to_vertices
103108
104- def turn_right (direction ):
105- return (- direction [1 ],direction [0 ])
106109
110+ def turn_left (direction ):
111+ return (direction [1 ],- direction [0 ])
107112
108113
114+ def turn_right (direction ):
115+ return (- direction [1 ],direction [0 ])
109116
110117
111118# Analyze grid
112119grid = puzzle_input
113120graph = pathfinding .Graph ()
114- graph .grid_to_vertices (puzzle_input ,' ' )
121+ graph .grid_to_vertices (puzzle_input ," " )
115122
116- intersections = graph .grid_search (grid ,'+' )[ '+' ]
123+ intersections = graph .grid_search (grid ,"+" )[ "+" ]
117124
118- directions = {'^' : (0 ,- 1 ),'>' : (1 ,0 ),'<' : (- 1 ,0 ),'v' : (0 ,1 )}
119- dirs = {(0 ,- 1 ):'^' , (1 ,0 ):'>' , (- 1 ,0 ):'<' , (0 ,1 ):'v' }
125+ directions = {"^" : (0 ,- 1 ),">" : (1 ,0 ),"<" : (- 1 ,0 ),"v" : (0 ,1 )}
126+ dirs = {(0 ,- 1 ):"^" , (1 ,0 ):">" , (- 1 ,0 ):"<" , (0 ,1 ):"v" }
120127
121128
122129# Find carts
123- list_carts = graph .grid_search (grid , ('^' , '<' , '>' , 'v' ))
130+ list_carts = graph .grid_search (grid , ("^" , "<" , ">" , "v" ))
124131carts = []
125132cart_positions = []
126133for direction in list_carts :
@@ -143,15 +150,16 @@ def turn_right (direction):
143150pos ,dir ,choice = cart
144151new_pos = (pos [0 ]+ dir [0 ],pos [1 ]+ dir [1 ])
145152
146- print (pos ,choice ,dirs [dir ])
147-
153+ print (pos ,choice ,dirs [dir ])
148154
149155# We need to turn
150156if new_pos not in graph .edges [pos ]:
151- options = [((pos [0 ]+ x [0 ],pos [1 ]+ x [1 ]),x )
152- for x in directions .values ()
153- if x != (- dir [0 ],- dir [1 ])
154- and (pos [0 ]+ x [0 ],pos [1 ]+ x [1 ])in graph .edges [pos ]]
157+ options = [
158+ ((pos [0 ]+ x [0 ],pos [1 ]+ x [1 ]),x )
159+ for x in directions .values ()
160+ if x != (- dir [0 ],- dir [1 ])
161+ and (pos [0 ]+ x [0 ],pos [1 ]+ x [1 ])in graph .edges [pos ]
162+ ]
155163new_pos ,dir = options [0 ]
156164
157165# Intersection
@@ -165,25 +173,20 @@ def turn_right (direction):
165173
166174new_cart = (new_pos ,dir ,choice )
167175
168-
169-
170-
171-
172176# Check collisions
173177if new_cart [0 ]in cart_positions :
174178if part_to_test == 1 :
175179puzzle_actual_result = new_cart [0 ]
176180break
177181else :
178- print ( ' collision' ,new_cart [0 ])
182+ print ( " collision" ,new_cart [0 ])
179183collision += 1
180184carts = [c for c in carts if c [0 ]!= new_cart [0 ]]
181185cart_positions = [c [0 ]for c in carts ]
182186else :
183187carts .append (new_cart )
184188cart_positions .append (new_cart [0 ])
185189
186-
187190# Count ticks + sort carts
188191subtick += 1
189192if subtick == nb_carts - collision :
@@ -194,18 +197,14 @@ def turn_right (direction):
194197carts = sorted (carts ,key = lambda x : (x [0 ][1 ],x [0 ][0 ]))
195198cart_positions = [c [0 ]for c in carts ]
196199
197- print ( ' End of tick' ,tick ,' - Remaining' ,len (carts ))
200+ print ( " End of tick" ,tick ," - Remaining" ,len (carts ))
198201if len (carts )== 1 :
199202break
200203
201204if part_to_test == 2 :
202205puzzle_actual_result = carts
203- #99, 96
206+ # 99, 96
204207# -------------------------------- Outputs / results -------------------------------- #
205208
206- print ('Expected result : ' + str (puzzle_expected_result ))
207- print ('Actual result : ' + str (puzzle_actual_result ))
208-
209-
210-
211-
209+ print ("Expected result : " + str (puzzle_expected_result ))
210+ print ("Actual result : " + str (puzzle_actual_result ))