C'est le dernier jour où je vais avoir le temps de la faire, la suite ça sera peut-être dans une semaine...
J'ai inventé un algo un peu tordu, assez efficace, rude à piger, donc à débugger.
Déjà les coordonnées sont en 1 dimension : x+y*10+z*100, on va simplifier, surtout qu'on ne fait que des mouvements vers le bas, aucun test aux bornes à faire.
J'ajoute un bloc de 10x10 en 0 pour poser le bazar.
Une structure de Blocs assez modélisée, une autre pour l'Univers bien plus simple et à la fin un algo tordu.
fromsysimportstdinfromfunctoolsimporttotal_orderingfromcollectionsimportdequefromitertoolsimportchaindata=deque(stdin.read().strip().splitlines())@total_orderingclassBloc:def__init__(self,blocdef=None,blocname=None,cubes=None):self.name=blocnameifcubes:self.cubes=cubesself.alt=min(cubes)//100returnx,y,z=zip(*((int(__)for__in_.split(","))for_inblocdef.split("~")))self.cubes={a+b*10+c*100forainrange(min(x),max(x)+1)forbinrange(min(y),max(y)+1)forcinrange(min(z),max(z)+1)}self.alt=min(z)def__iter__(self):forpinself.cubes:yieldpdef__eq__(self,o):returnself.alt==o.altdef__lt__(self,o):returnself.alt<o.altdef__contains__(self,_):return_inself.cubesdef__repr__(self):returnf"Bloc#{self.name}({self.cubes})"def__neg__(self):alt=min(_//100for_inself.cubes)*100-100returnBloc(blocname=self.name,cubes={alt+_%100for_inself.cubes})def__pos__(self):alt=max(_//100for_inself.cubes)*100+100returnBloc(blocname=self.name,cubes={alt+_%100for_inself.cubes})def__sub__(self,x):self.cubes={_-100*xfor_inself.cubes}classUniverse:def__init__(self):self.zone=set(range(100))self.blocs={}def__contains__(self,_):# True if bloc can be placed in universereturnnotself.zone.intersection(_.cubes)defadd(self,_):self.zone.update(_)forpin_:self.blocs[p]=_.namedata.extendleft(["0,0,0~9,9,0"])blocs=sorted(Bloc(line,i)fori,lineinenumerate(data))ground=blocs.pop(0)universe=Universe()universe.add(ground)forblocinblocs:while-blocinuniverse:bloc-1universe.add(bloc)# Blocs under each blocdown={bloc.name:{universe.blocs[p]forpin-blocifpinuniverse.blocs}forblocinblocs}cannot={blocfor_indown.values()iflen(_)==1forblocin_}.difference({0})ex1=len(blocs)-len(cannot)
Et l'exercice 2, prenez peur !
topof={}partial={}forblocinsorted(blocs,reverse=True):name=bloc.nameifnamenotintopof:topof[name]=set()# Handling partially supported blocksmypartial=partial.pop(name,set())ifmypartial:replay=Truewhilereplay:replay=Falsenewpart=set()# All blocs partially supported elsewhereotherpart=set(chain.from_iterable(vfork,vinpartial.items()ifknotintopof[name]))for_inmypartial:if_notinotherpart:# That bloc isn't supported by someone else elsewhere, it is mine!topof[name].add(_)topof[name].update(topof.get(_,[]))replay=True# We'll have to restart the search here, because the world changed.else:newpart.add(_)mypartial=newpartifmypartial:partial[name]=mypartial# Sending down my informationsup=topof.get(name,set()).union({name})downward=list(down.get(name,[]))iflen(downward)==1:# Supported by only one other bloc, sending what I'm actively supportingtopof[downward[0]]=topof.get(downward[0],set()).union(up)# Sending known partial information downforblocindownward:partial[bloc]=partial.get(bloc,set()).union({name}).union(partial.get(name,{}))partial.pop(name,None)ex2=sum(len(topof[bloc])forblocincannot)
J'ai pas vraiment le temps de remettre au propre, en gros je pars du haut, et je « pose » les blocs les uns sur les autres, en notant ceux qui sont partiellement posés, et où.
Et puis à chaque bloc, j'essaie de simplifier par ceux qui ne sont partiellement posés plus que sur lui.
Et... bah ça marche, en tapant bien sur le code.
# On fait tomber des trucs, mais on fait pas de Tetris.
Posté par Yth (Mastodon) . En réponse au message Advent of Code 2023, jour 22. Évalué à 2.
C'est le dernier jour où je vais avoir le temps de la faire, la suite ça sera peut-être dans une semaine...
J'ai inventé un algo un peu tordu, assez efficace, rude à piger, donc à débugger.
Déjà les coordonnées sont en 1 dimension :
x+y*10+z*100, on va simplifier, surtout qu'on ne fait que des mouvements vers le bas, aucun test aux bornes à faire.J'ajoute un bloc de 10x10 en 0 pour poser le bazar.
Une structure de Blocs assez modélisée, une autre pour l'Univers bien plus simple et à la fin un algo tordu.
Et l'exercice 2, prenez peur !
J'ai pas vraiment le temps de remettre au propre, en gros je pars du haut, et je « pose » les blocs les uns sur les autres, en notant ceux qui sont partiellement posés, et où.
Et puis à chaque bloc, j'essaie de simplifier par ceux qui ne sont partiellement posés plus que sur lui.
Et... bah ça marche, en tapant bien sur le code.