|
1 | 1 | # -------------------------------- Input data ---------------------------------------- #
|
2 | 2 | importos,pathfinding
|
3 | 3 |
|
| 4 | +fromcomplex_utilsimport* |
| 5 | + |
| 6 | + |
| 7 | +j=SuperComplex(1j) |
| 8 | + |
| 9 | + |
4 | 10 | test_data= {}
|
5 | 11 |
|
6 | 12 | test=1
|
|
18 | 24 | )
|
19 | 25 | test_data[test]= {
|
20 | 26 | "input":open(input_file,"r+").read().strip(),
|
21 |
| -"expected": ["6256","Unknown"], |
| 27 | +"expected": ["6256","973"], |
22 | 28 | }
|
23 | 29 |
|
24 | 30 | # -------------------------------- Control program execution ------------------------- #
|
|
40 | 46 |
|
41 | 47 | depth=int(depth)
|
42 | 48 | max_x,max_y=map(int,target.split(","))
|
43 |
| -target=max_x-1j*max_y |
| 49 | +target=max_x-j*max_y |
44 | 50 |
|
45 | 51 | geological= {0:0}
|
46 | 52 | erosion= {0:0}
|
47 | 53 | forxinrange(max_x+1):
|
48 | 54 | geological[x]=x*16807
|
49 | 55 | erosion[x]= (geological[x]+depth)%20183
|
50 | 56 | foryinrange(max_y+1):
|
51 |
| -geological[-1j*y]=y*48271 |
52 |
| -erosion[-1j*y]= (geological[-1j*y]+depth)%20183 |
| 57 | +geological[-j*y]=y*48271 |
| 58 | +erosion[-j*y]= (geological[-j*y]+depth)%20183 |
53 | 59 |
|
54 | 60 | forxinrange(1,max_x+1):
|
55 | 61 | foryinrange(1,max_y+1):
|
56 |
| -geological[x-1j*y]= ( |
57 |
| -erosion[x-1-1j*y]*erosion[x-1j* (y-1)] |
| 62 | +geological[x-j*y]= ( |
| 63 | +erosion[x-1-j*y]*erosion[x-j* (y-1)] |
58 | 64 | )%20183
|
59 |
| -erosion[x-1j*y]= (geological[x-1j*y]+depth)%20183 |
| 65 | +erosion[x-j*y]= (geological[x-j*y]+depth)%20183 |
60 | 66 |
|
61 | 67 | geological[target]=0
|
62 | 68 | erosion[target]=0
|
|
70 | 76 | neither,climbing,torch=0,1,2
|
71 | 77 | rocky,wet,narrow=0,1,2
|
72 | 78 |
|
73 |
| -# Override the neighbors function |
74 |
| -defneighbors(self,vertex): |
75 |
| -north= (0,1) |
76 |
| -south= (0,-1) |
77 |
| -west= (-1,0) |
78 |
| -east= (1,0) |
79 |
| -directions_straight= [north,south,west,east] |
80 |
| - |
81 |
| -neighbors= {} |
82 |
| -fordirindirections_straight: |
83 |
| -target= (vertex[0]+dir[0],vertex[1]+dir[1],vertex[2]) |
84 |
| -iftargetinself.vertices: |
85 |
| -neighbors[target]=1 |
86 |
| -fortoolin (neither,climbing,torch): |
87 |
| -target= (vertex[0],vertex[1],tool) |
88 |
| -iftargetinself.verticesandtool!=vertex[1]: |
89 |
| -neighbors[target]=7 |
90 |
| - |
91 |
| -returnneighbors |
| 79 | +allowed= { |
| 80 | +rocky: [torch,climbing], |
| 81 | +wet: [neither,climbing], |
| 82 | +narrow: [torch,neither], |
| 83 | + } |
92 | 84 |
|
93 | 85 | # Add some coordinates around the target
|
94 | 86 | padding=10ifcase_to_test==1else50
|
95 | 87 | forxinrange(max_x,max_x+padding):
|
96 | 88 | geological[x]=x*16807
|
97 | 89 | erosion[x]= (geological[x]+depth)%20183
|
98 | 90 | foryinrange(max_y,max_y+padding):
|
99 |
| -geological[-1j*y]=y*48271 |
100 |
| -erosion[-1j*y]= (geological[-1j*y]+depth)%20183 |
| 91 | +geological[-j*y]=y*48271 |
| 92 | +erosion[-j*y]= (geological[-j*y]+depth)%20183 |
101 | 93 | forxinrange(1,max_x+padding):
|
102 | 94 | foryinrange(1,max_y+padding):
|
103 |
| -ifx-1j*yingeological: |
| 95 | +ifx-j*yingeological: |
104 | 96 | continue
|
105 |
| -geological[x-1j*y]= ( |
106 |
| -erosion[x-1-1j*y]*erosion[x-1j* (y-1)] |
| 97 | +geological[x-j*y]= ( |
| 98 | +erosion[x-1-j*y]*erosion[x-j* (y-1)] |
107 | 99 | )%20183
|
108 |
| -erosion[x-1j*y]= (geological[x-1j*y]+depth)%20183 |
| 100 | +erosion[x-j*y]= (geological[x-j*y]+depth)%20183 |
109 | 101 |
|
110 | 102 | terrain= {x:erosion[x]%3forxinerosion}
|
| 103 | + |
111 | 104 | delerosion
|
112 | 105 | delgeological
|
113 | 106 |
|
114 |
| -# Then run pathfinding algo |
| 107 | +# Prepare pathfinding algorithm |
| 108 | + |
| 109 | +# Override the neighbors function |
| 110 | +defneighbors(self,vertex): |
| 111 | +north=j |
| 112 | +south=-j |
| 113 | +west=-1 |
| 114 | +east=1 |
| 115 | +directions_straight= [north,south,west,east] |
| 116 | + |
| 117 | +neighbors= {} |
| 118 | +fordirindirections_straight: |
| 119 | +target= (vertex[0]+dir,vertex[1]) |
| 120 | +ifself.is_valid(target): |
| 121 | +neighbors[target]=1 |
| 122 | +fortoolin (neither,climbing,torch): |
| 123 | +target= (vertex[0],tool) |
| 124 | +ifself.is_valid(target): |
| 125 | +neighbors[target]=7 |
| 126 | + |
| 127 | +returnneighbors |
| 128 | + |
| 129 | +# Define what is a valid spot |
| 130 | +defis_valid(self,vertex): |
| 131 | +ifvertex[0].real<0orvertex[0].imag>0: |
| 132 | +returnFalse |
| 133 | +ifvertex[0].real>=max_x+paddingorvertex[0].imag<=-(max_y+padding): |
| 134 | +returnFalse |
| 135 | +ifvertex[1]inallowed[terrain[vertex[0]]]: |
| 136 | +returnTrue |
| 137 | +returnFalse |
| 138 | + |
| 139 | +# Heuristics function for A* search |
| 140 | +defestimate_to_complete(self,start,target): |
| 141 | +distance=0 |
| 142 | +foriinrange(len(start)-1): |
| 143 | +distance+=abs(start[i]-target[i]) |
| 144 | +distance+=7ifstart[-1]!=target[-1]else0 |
| 145 | +returndistance |
| 146 | + |
| 147 | +# Run pathfinding algorithm |
115 | 148 | pathfinding.WeightedGraph.neighbors=neighbors
|
116 |
| -vertices= [ |
117 |
| - (x.real,x.imag,neither)forxinterrainifterrain[x]in (wet,narrow) |
118 |
| - ] |
119 |
| -vertices+= [ |
120 |
| - (x.real,x.imag,climbing)forxinterrainifterrain[x]in (rocky,wet) |
121 |
| - ] |
122 |
| -vertices+= [ |
123 |
| - (x.real,x.imag,torch)forxinterrainifterrain[x]in (rocky,narrow) |
124 |
| - ] |
125 |
| -graph=pathfinding.WeightedGraph(vertices) |
126 |
| - |
127 |
| -graph.dijkstra((0,0,torch), (max_x,-max_y,torch)) |
128 |
| - |
129 |
| -puzzle_actual_result=graph.distance_from_start[(max_x,-max_y,torch)] |
130 |
| - |
131 |
| -# 979 is too high |
| 149 | +pathfinding.WeightedGraph.is_valid=is_valid |
| 150 | +pathfinding.Graph.estimate_to_complete=estimate_to_complete |
| 151 | + |
| 152 | +graph=pathfinding.WeightedGraph() |
| 153 | + |
| 154 | +graph.a_star_search( |
| 155 | + (SuperComplex(0),torch), (SuperComplex(max_x-j*max_y),torch) |
| 156 | + ) |
| 157 | + |
| 158 | +puzzle_actual_result=graph.distance_from_start[(max_x-j*max_y,torch)] |
132 | 159 |
|
133 | 160 |
|
134 | 161 | # -------------------------------- Outputs / results --------------------------------- #
|
|