fromcollectionsimportdefaultdict,namedtupleLeg=namedtuple('Leg','start begin end cont_start cont_end')defmkleg(start,begin,end,cont_start=None,cont_end=None):returnLeg(start,begin,end,cont_start,cont_end)classExpedition:def__init__(self,regexp):self.regexp=regexpself.distances=defaultdict(lambda:float('inf'))self.doors=set()self.legs={mkleg((1,1),0,len(self.regexp))}defexplore(self):assertself.regexp[0]=='^'andself.regexp[-1]=='$'counter=0whilelen(self.legs)>0:next_leg=self.legs.pop()self.explore_leg(next_leg)counter+=1defexplore_leg(self,current_leg):(x,y)=current_leg.startidx=current_leg.beginfinish=Falsewhileidx<current_leg.endandnotfinish:old_pos=(x,y)current=self.regexp[idx]ifcurrent=='^':self.distances[(x,y)]=0elifcurrent=='N':y-=2elifcurrent=='E':x+=2elifcurrent=='S':y+=2elifcurrent=='W':x-=2elifcurrent=='$':passelifcurrent=='(':matching=self.find_matching(idx)options=self.find_options(idx,matching)for(option_begin,option_end)inoptions:assertoption_begin<=option_endifoption_begin<option_end:leg=mkleg((x,y),option_begin,option_end,matching,current_leg.end)else:leg=mkleg((x,y),matching,current_leg.end)self.legs.add(leg)finish=Trueelifcurrent==')':passelse:raiseException('unexpected character ',current)self.distances[(x,y)]=min(1+self.distances[old_pos],self.distances[(x,y)])idx+=1ifcurrent_leg.cont_startandcurrent_leg.cont_start<current_leg.cont_end:leg=mkleg((x,y),current_leg.cont_start,current_leg.cont_end)self.legs.add(leg)deffind_matching(self,idx):assertself.regexp[idx]=='('opened=0whileTrue:idx+=1current=self.regexp[idx]ifcurrent=='(':opened+=1elifcurrent==')'andopened==0:returnidx+1elifcurrent==')':opened-=1elifcurrent=='^':raiseException("regexp should be well constructed")deffind_options(self,begin,end):assertself.regexp[begin]=='('andself.regexp[end-1]==')'options=[]opened=0option_start=begin+1foridxinrange(begin+1,end):current=self.regexp[idx]ifcurrent=='(':opened+=1elifcurrent==')':opened-=1elifcurrent=='|'andopened==0:options.append((option_start,idx))option_start=idx+1idx+=1options.append((option_start,end))returnoptionsdefpart1(regexp):expedition=Expedition(regexp)expedition.explore()returnmax(expedition.distances.values())defpart2(regexp):expedition=Expedition(regexp)expedition.explore()returnsum(1forvinexpedition.distances.values()ifv>=1000)deftest_part1():assertpart1('^WNE$')==3assertpart1('^ENWWW(NEEE|SSE(EE|N))$')==10assertpart1('^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$')==18assertpart1('^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$')==23assertpart1('^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$')==31if__name__=='__main__':withopen('input.txt','r')asfile:contents=file.read().strip()print("Part1: ",part1(contents))print("Part2: ",part2(contents))
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.
One day after but now it works !!