Problème intéressant, il me rappelle le jour 17 de 2022.
J'ai écrit une fonction tilt qui fait tomber les briques vers l'ouest.
Pour cela, pour chaque ligne, je split la ligne selon # et pour chaque morceau du split, je sépare les O et les "." et je reconcatène tout en mettant les O d'abord et les "." ensuite.
Ensuite j'ai une fonction tiltInDirection qui se ramène à tilt en faisant des rotate et des reverse selon le cas de figure.
Pour la partie 2, je génère une suite infinie cyclique de North, West, South, East
et à partir de celle ci, je génère une liste infinie des différentes configurations après avoir effectué les tilts dans la direction donnée.
Dans cette liste, je cherche les indices x et y de la même configuration (fonction findRepetition) et la configuration qui nous intéresse est celle à l'indice x + (1000000000 - x) mod (y - x).
La partie 2 tourne en 600ms. Pas très satisfait mais ça reste raisonnable.
Voici le code
importAOC.Preludehiding(empty)importData.List((!!))importAOC(aoc)importqualifiedData.HashMap.StrictasMapimportAOC.Parser(Parser,sepEndBy1,eol,some)importAOC.Util(flattenWithIndex,splitWhen)dataRock=Empty|Round|Cubederiving(Eq,Enum)dataDirection=West|East|North|SouthtypeGrid=[[Rock]]instanceHashableRockwherehashWithSaltsrock=s`hashWithSalt`fromEnumrockparser::ParserGridparser=somerock`sepEndBy1`eolwhererock=Empty<$"."<|>Round<$"O"<|>Cube<$"#"-- tilt to Westtilt::Grid->Gridtilt=mapperRowwhereperRow=intercalate[Cube].mapgo.splitWhen(==Cube)goxs=rounded++emptywhere(rounded,empty)=partition(==Round)xstiltInDirection::Direction->Grid->GridtiltInDirection=\caseWest->tiltEast->mapreverse.tilt.mapreverseNorth->transpose.tilt.transposeSouth->reverse.transpose.tilt.transpose.reverse-- return the first two indices of the same element in a infinite list of elementsfindRepetition::Hashablea=>[a]->(Int,Int)findRepetition=goMap.empty.zip[0..]wheregom((i,x):xs)=casemMap.!?xofJustj->(j,i)Nothing->go(Map.insertxim)xsgo_[]=error"findRepetition: not an infinite list"-- compute the laod of a gridload::Grid->Intloadgrid=sum.mapscore$flattenWithIndexgridwherescore(i,_,Round)=len-iscore_=0len=lengthgridpart1::Grid->Intpart1=load.tiltInDirectionNorthpart2::Grid->Intpart2grid=load(grids!!y')where(x,y)=findRepetitiongridsy'=x+(1000000000-x)`mod`(y-x)grids=scanl'(fliptiltInDirection)griddirectionsdirections=cycle[North,West,South,East]solve::Text->IO()solve=aocparserpart1part2
# Solution en Haskell
Posté par Guillaume.B . En réponse au message Advent of Code, jour 14. Évalué à 1. Dernière modification le 14 décembre 2023 à 13:20.
Problème intéressant, il me rappelle le jour 17 de 2022.
J'ai écrit une fonction
tiltqui fait tomber les briques vers l'ouest.Pour cela, pour chaque ligne, je split la ligne selon # et pour chaque morceau du split, je sépare les O et les "." et je reconcatène tout en mettant les O d'abord et les "." ensuite.
Ensuite j'ai une fonction
tiltInDirectionqui se ramène àtilten faisant des rotate et des reverse selon le cas de figure.Pour la partie 2, je génère une suite infinie cyclique de North, West, South, East
et à partir de celle ci, je génère une liste infinie des différentes configurations après avoir effectué les tilts dans la direction donnée.
Dans cette liste, je cherche les indices x et y de la même configuration (fonction
findRepetition) et la configuration qui nous intéresse est celle à l'indicex + (1000000000 - x) mod (y - x).La partie 2 tourne en 600ms. Pas très satisfait mais ça reste raisonnable.
Voici le code