Pour la définition de aoc.group_lines(lines: str), cf. hier
from__future__importannotationsimportitertoolsfromtypingimportIterable,Iterator,List,Optional,Tuple,UnionimportaocclassElement:def__init__(self,value:Union[List[Element],int]):self.value=valuedef__lt__(self,other:Element)->bool:ifisinstance(self.value,int)andisinstance(other.value,int):returnself.value<other.valueifisinstance(self.value,list)andisinstance(other.value,list):forself_elt,other_eltinzip(self.value,other.value):ifself_elt<other_elt:returnTrueifother_elt<self_elt:returnFalse# Ran out of elements on one of the listsreturnlen(self.value)<len(other.value)ifisinstance(self.value,int):returnElement([self])<otherifisinstance(other.value,int):returnself<Element([other])assertFalse# should not happen: we covered all casesdef__eq__(self,other:object)->bool:ifnotisinstance(other,Element):returnNotImplementedifisinstance(self.value,int)andisinstance(other.value,int):returnself.value==other.valueifisinstance(self.value,list)andisinstance(other.value,list):return(len(self.value)==len(other.value)andall(self_elt==other_eltforself_elt,other_eltinzip(self.value,other.value)))ifisinstance(self.value,int):returnElement([self])==otherifisinstance(other.value,int):returnself==Element([other])assertFalse# should not happen: we covered all casesdef__str__(self)->str:ifisinstance(self.value,int):returnstr(self.value)elifisinstance(self.value,list):return'[{}]'.format(','.join(str(element)forelementinself.value))assertFalse# should not happen: we covered all casesdefimport_element(chars:Iterable[str])->Element:element:Optional[Element]=Nonelists:List[List[Element]]=[]# List[List[Element]]current_list:Optional[List[Element]]=Nonecurrent_int:Optional[int]=Noneforcharinchars:ifchar=='[':ifcurrent_intisnotNone:raiseValueError("unexpected beginning of list")ifcurrent_listisnotNone:lists.append(current_list)current_list=[]elifchar==']':ifcurrent_listisNone:raiseValueError("unexpected end of list")# If we were parsing an int, add it before closing current listifcurrent_intisnotNone:current_list.append(Element(current_int))current_int=Noneiflists:# We are closing a sub-listprev_list=lists.pop()prev_list.append(Element(current_list))current_list=prev_listelse:# We are closing the top-level listelement=Element(current_list)current_list=Noneelifchar.isdecimal():value=int(char)ifcurrent_intisNone:current_int=valueelse:current_int=10*current_int+valuecontinueelifchar==',':ifcurrent_listisNone:raiseValueError("unexpected separator")ifcurrent_intisnotNone:current_list.append(Element(current_int))current_int=Noneelifchar=='\n':passelse:raiseValueError("unexpected character")ifelementisNone:raiseValueError("nothing to parse")returnelementdefimport_pairs(lines:Iterable[str])->Iterator[Tuple[Element,Element]]:forgroupinaoc.group_lines(lines):elements=[import_element(line)forlineingroup]iflen(elements)!=2:raiseValueError("unexpected group length")yield(elements[0],elements[1])defimport_elements(lines:Iterable[str])->Iterator[Element]:forlineinlines:iflineandline!='\n':yieldimport_element(line)defsolve1(lines:Iterable[str])->int:"""Solve part 1 of today's puzzle"""pairs=import_pairs(lines)returnsum(i+1fori,(elt1,elt2)inenumerate(pairs)ifelt1<elt2)defsolve2(lines:Iterable[str])->int:"""Solve part 2 of today's puzzle"""elements:Iterable[Element]=import_elements(lines)div1=import_element("[[2]]")div2=import_element("[[6]]")elements=sorted(itertools.chain(elements,(div1,div2)))key=1fori,elementinenumerate(elements):ifelement==div1orelement==div2:key*=i+1returnkey
# En Pypthon
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 13. Évalué à 5.
Pour la définition de
aoc.group_lines(lines: str), cf. hier