Joli, du coup j'ai honte de montrer ma solution avec liste chaînée maison. Mais je la montre quand même, allez :
from__future__importannotationsimportiofromtypingimportIterable,Iterator,OptionalclassChain:def__init__(self,*elts:Element)->None:self._len=len(elts)self.first=elts[0]last=elts[-1]prev:Optional[Element]=Noneforeltinelts:ifprevisnotNone:prev.attach(elt)prev=eltlast.attach(self.first)def__len__(self):returnself._lendef__getitem__(self,index:int)->Element:index=index%len(self)current=self.firstfor_inrange(index):current=current.nextreturncurrentdefget_elt(self,base_elt:Element,index:int)->Element:index=index%len(self)current=base_eltfor_inrange(index):current=current.nextreturncurrentdef__iter__(self)->Iterator[Element]:current=self.firstfor_inrange(self._len):yieldcurrentcurrent=current.nextdefextract(self,index:int)->Element:elt=self[index]elt.detach()self._len-=1returneltdefextract_elt(self,elt:Element)->None:# WARNING: not checking that elt is part of selfelt.detach()self._len-=1definsert(self,index:int,elt:Element)->None:prev=self[index]next_=prev.next# Attach (prev and elt) and (elt and next_)prev.attach(elt)elt.attach(next_)self._len+=1definsert_elt(self,base:Element,shift:int,elt:Element)->None:# WARNING: not checking that elt is part of selfshift%=self._lenprev=basefor_inrange(shift):prev=prev.nextnext_=prev.next# Attach (prev and elt) and (elt and next_)prev.attach(elt)elt.attach(next_)self._len+=1def__str__(self):result=io.StringIO()result.write('(')foreltinself:result.write('{}, '.format(elt.value))result.write(')')returnresult.getvalue()classElement:def__init__(self,value:int)->None:self.value=valueself.prev=selfself.next=selfdefattach(self,other:Element)->None:self.next=otherother.prev=selfdefdetach(self)->None:prev=self.prevnext_=self.next# Detach selfself.prev=selfself.next_=self# Attach prev and next_prev.attach(next_)defsolve1(lines:Iterable[str])->int:"""Solve part 1 of today's puzzle"""elts=[Element(int(line))forlineinlines]seq=Chain(*elts)zero:Optional[elt]=Noneforeltinelts:ifzeroisNoneandelt.value==0:zero=eltprev=elt.prevseq.extract_elt(elt)seq.insert_elt(prev,elt.value,elt)ifzeroisNone:raiseValueError("invalid input without a zero value")return(seq.get_elt(zero,1000).value+seq.get_elt(zero,2000).value+seq.get_elt(zero,3000).value)defsolve2(lines:Iterable[str])->int:"""Solve part 2 of today's puzzle"""key=811589153elts=[Element(key*int(line))forlineinlines]seq=Chain(*elts)zero:Optional[elt]=Nonefor_inrange(10):foreltinelts:ifzeroisNoneandelt.value==0:zero=eltprev=elt.prevseq.extract_elt(elt)seq.insert_elt(prev,elt.value,elt)ifzeroisNone:raiseValueError("invalid input without a zero value")return(seq.get_elt(zero,1000).value+seq.get_elt(zero,2000).value+seq.get_elt(zero,3000).value)
À noter que c'est pas mal plus lent qu'avec des listes Python en fait... :-(
[^] # Re: Un bug que j'ai résolu sans jamais le trouver.
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 20. Évalué à 4.
Joli, du coup j'ai honte de montrer ma solution avec liste chaînée maison. Mais je la montre quand même, allez :
À noter que c'est pas mal plus lent qu'avec des listes Python en fait... :-(