#! /usr/bin/python3# Advent of Code 2022, day 9from__future__importannotationsfromenumimportEnumfromtypingimportIterable,Iterator,Set,TupleCoords=Tuple[int,int]classDirection(Enum):O=(0,0)U=(0,1)D=(0,-1)L=(-1,0)R=(1,0)UL=(-1,1)UR=(1,1)DL=(-1,-1)DR=(1,-1)def__init__(self,dx,dy):self.dx=dxself.dy=dyclassKnot:def__init__(self,x:int,y:int):self.x=xself.y=y@propertydefcoords(self)->Coords:return(self.x,self.y)defmove(self,direction:Direction)->None:self.x+=direction.dxself.y+=direction.dydefdist(self,other:Knot)->int:""""Chebyshev distance! (Not really used in my code, actually)"""returnmax(abs(self.x-other.x),abs(self.y-other.y))defdirection_to(self,other:Knot)->Direction:dx=other.x-self.xdy=other.y-self.yifdx<-1:ifdy<0:returnDirection.DLifdy==0:returnDirection.Lifdy>0:returnDirection.ULifdx==-1:ifdy<-1:returnDirection.DLif-1<=dy<=1:returnDirection.Oifdy>1:returnDirection.ULifdx==0:ifdy<-1:returnDirection.Dif-1<=dy<=1:returnDirection.Oifdy>1:returnDirection.Uifdx==1:ifdy<-1:returnDirection.DRif-1<=dy<=1:returnDirection.Oifdy>1:returnDirection.URifdx>1:ifdy<0:returnDirection.DRifdy==0:returnDirection.Rifdy>0:returnDirection.URassertFalse# cannot happen, all cases were covereddeffollow(self,other:Knot)->None:self.move(self.direction_to(other))classRope:def__init__(self,n_knots:int)->None:self.knots=[Knot(0,0)for_inrange(n_knots)]@propertydefhead(self)->Knot:returnself.knots[0]@propertydeftail(self)->Knot:returnself.knots[-1]defmove(self,direction:Direction)->None:self.head.move(direction)foriinrange(1,len(self.knots)):leader=self.knots[i-1]follower=self.knots[i]follower.follow(leader)defimport_lines(lines:Iterable[str])->Iterator[Direction]:forlineinlines:word1,word2=line.split()direction=Direction[word1]repeat=int(word2)for_inrange(repeat):yielddirectiondefsolve_both(lines:Iterable[str])->Tuple[int,int]:"""Solve both parts of today's puzzle"""rope=Rope(10)visited1=set()# type: Set[Coords]visited2=set()# type: Set[Coords]fordirectioninimport_lines(lines):rope.move(direction)visited1.add(rope.knots[1].coords)visited2.add(rope.tail.coords)returnlen(visited1),len(visited2)
J'aurais bien aimé éviter d'énumérer tous les cas de mouvement de suivi, mais je n'ai rien trouvé d'astucieux pour éviter cela.
J'espère que dans vos solutions perso, vous aurez pensé à utiliser, en arrivant à la deuxième partie, à utiliser une seule corde pour simuler les deux...
# En Python, modélisé
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 9. Évalué à 4.
J'aurais bien aimé éviter d'énumérer tous les cas de mouvement de suivi, mais je n'ai rien trouvé d'astucieux pour éviter cela.
J'espère que dans vos solutions perso, vous aurez pensé à utiliser, en arrivant à la deuxième partie, à utiliser une seule corde pour simuler les deux...