Part1 was easy: translate the definitions into python code and let the memoization decoration do catching for efficiency.
Part2 is an application of the A* algorithm, which I ended consulting in Wikipedia because my recall was wrong and, although I solved the given example, I fail at the problem.
importcollectionsimportfunctoolsROCKY,WET,NARROW=range(3)@functools.lru_cache(maxsize=None)defgeologic_index(region,depth,target):x,y=regionifregion==(0,0)orregion==target:return0elify==0:returnx*16807elifx==0:returny*48271else:returnerosion_level((x-1,y),depth,target)*erosion_level((x,y-1),depth,target)@functools.lru_cache(maxsize=None)deferosion_level(region,depth,target):return(geologic_index(region,depth,target)+depth)%20183deftype_(region,depth,target):returnerosion_level(region,depth,target)%3defrisk_level(depth,target):width,height=targetreturnsum(type_((x,y),depth,target)forxinrange(width+1)foryinrange(height+1))deftest_geologic_index():assertgeologic_index((0,0),510,(10,10))==0assertgeologic_index((1,0),510,(10,10))==16807assertgeologic_index((0,1),510,(10,10))==48271assertgeologic_index((1,1),510,(10,10))==145722555assertgeologic_index((10,10),510,(10,10))==0deftest_erosion_level():asserterosion_level((0,0),510,(10,10))==510asserterosion_level((1,0),510,(10,10))==17317asserterosion_level((0,1),510,(10,10))==8415asserterosion_level((1,1),510,(10,10))==1805asserterosion_level((10,10),510,(10,10))==510deftest_type():asserttype_((0,0),510,(10,10))==ROCKYasserttype_((1,0),510,(10,10))==WETasserttype_((0,1),510,(10,10))==ROCKYasserttype_((1,1),510,(10,10))==NARROWasserttype_((10,10),510,(10,10))==ROCKYdeftest_risk_level():assertrisk_level(510,(10,10))==114# Part 2
CLIMBING_GEAR,TORCH,NEITHER=range(3)COMPATIBILITY={ROCKY:{CLIMBING_GEAR,TORCH},WET:{CLIMBING_GEAR,NEITHER},NARROW:{TORCH,NEITHER}}State=collections.namedtuple('State','region equipment')classCave:def__init__(self,depth,target):self.depth=depthself.target=targetdeftype_(self,region):returntype_(region,self.depth,self.target)defexplore(self):fscore=collections.defaultdict(lambda:float('inf'))gscore={}start=State(region=(0,0),equipment=TORCH)gscore[start]=0fscore[start]=self.heuristic(start)open_states={start}closed_states=set()whileTrue:current_state=min(open_states,key=lambdas:fscore[s])open_states.remove(current_state)ifcurrent_state.region==self.targetandcurrent_state.equipment==TORCH:returngscore[current_state]closed_states.add(current_state)fornext_state,distanceinself.neighborhood(current_state):ifnext_stateinclosed_states:continuetentative_gscore=gscore[current_state]+distanceifnext_statenotinopen_states:open_states.add(next_state)eliftentative_gscore>gscore[next_state]:continuegscore[next_state]=tentative_gscorefscore[next_state]=tentative_gscore+self.heuristic(next_state)defheuristic(self,state):returnabs(self.target[0]-state.region[0]) \
+abs(self.target[1]-state.region[1])defneighborhood(self,current):next_states_and_distances=[]fornext_regioninadjacent(current.region):ifcurrent.equipmentinCOMPATIBILITY[self.type_(next_region)]:next_states_and_distances.append((State(region=next_region,equipment=current.equipment),1))forequipmentin[CLIMBING_GEAR,TORCH,NEITHER]:ifequipment!=current.equipmentandequipmentinCOMPATIBILITY[self.type_(current.region)]:next_states_and_distances.append((State(region=current.region,equipment=equipment),7))returnnext_states_and_distancesdefadjacent(region):x,y=regionmoves=[]ifx>0:moves.append((x-1,y))ify>0:moves.append((x,y-1))returnmoves+[(x+1,y),(x,y+1)]defexplore(depth,target):returnCave(depth,target).explore()deftest_cave():cave=Cave(510,(10,10))assertcave.type_((0,0))==ROCKYassertcave.type_((1,0))==WETassertcave.type_((0,1))==ROCKYassertcave.type_((1,1))==NARROWassertcave.type_((10,10))==ROCKYdeftest_explore():cave=Cave(510,(10,10))assertcave.explore()==45def_test_part2():cave=Cave(8112,(13,743))assertcave.explore()==1010if__name__=='__main__':print("Part1: ",risk_level(8112,(13,743)))print("Part2: ",explore(8112,(13,743)))
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Part1 was easy: translate the definitions into python code and let the memoization decoration do catching for efficiency.
Part2 is an application of the A* algorithm, which I ended consulting in Wikipedia because my recall was wrong and, although I solved the given example, I fail at the problem.