Voici ma solution en Haskell.
La partie 1 utilise un BFS mais c'est un peu overkill.
La partie 2 repose sur des idées similaires à ce qu'a proposé Pierre.
Une partie non négligeable du code (la fonction getNiceInput) chercher à determiner quelle est la tuile adéquate pour remplacer la tuile Start.
importAOC.Preludehiding(head)importData.List(head,maximum)importqualifiedData.HashMap.StrictasMapimportqualifiedData.HashSetasSetimportAOC(aoc)importAOC.Parser(Parser,choice,eol,sepEndBy1,some)importAOC.Search(bfs)importAOC.Util(adjacentPoints,listTo2dMap)importAOC.Tuple(thd3)dataTile=NS|EW|NE|NW|SW|SE|Empty|Startderiving(Eq)typeCoord=(Int,Int)typeInput=[[Tile]]typeMatrix=HashMapCoordTileparser::ParserInputparser=sometile`sepEndBy1`eolwheretile=choice[NS<$"|",EW<$"-",NE<$"L",NW<$"J",SW<$"7",SE<$"F",Empty<$".",Start<$"S"]-- returns the start coordinate and the input where the start tile is replaced with the adequate tile getNiceInput::Input->(Input,Matrix,Coord)getNiceInputtiles=(cleanedTiles,cleanedMat,start)wherestart=head[pos|(pos,Start)<-Map.toListmat]mat=listTo2dMaptilesadequateTile=case[start`elem`neighborsmatnbor|nbor<-neighborsmatstart]of-- (x-1, y), (x+1, y), (x, y-1), (x, y+1)[True,True,False,False]->NS[False,False,True,True]->EW[True,False,False,True]->NE[True,False,True,False]->NW[False,True,False,True]->SE[False,True,True,False]->SW_->Empty-- cannot happen if the input is nicecleanedMat=Map.insertstartadequateTilematcleanedTiles=[[iftile==StartthenadequateTileelsetile|tile<-row]|row<-tiles]neighbors::Matrix->Coord->[Coord]neighborsmat(i,j)=casematMap.!?(i,j)ofJustNS->[(i-1,j),(i+1,j)]JustEW->[(i,j-1),(i,j+1)]JustNE->[(i-1,j),(i,j+1)]JustNW->[(i,j-1),(i-1,j)]JustSW->[(i+1,j),(i,j-1)]JustSE->[(i,j+1),(i+1,j)]JustStart->adjacentPoints(i,j)_->[]part1::Input->Intpart1tiles=maximum.mapfst$bfs(neighborsmat)startwhere(_,mat,start)=getNiceInputtilespart2::Input->Intpart2tiles=sum.mapcountRow$cleanedTileswhere(tiles',mat,start)=getNiceInputtilesloopSet=Set.fromList.mapsnd$bfs(neighborsmat)start-- replace each tile not in the loop with an empty tilecleanedTiles=[[if(i,j)`Set.member`loopSetthentileelseEmpty|(j,tile)<-zip[0..]row]|(i,row)<-zip[0..]tiles']countRow=thd3.foldl'go(False,False,0)go(isInside,fromNorth,counter)=\caseNS->(notisInside,fromNorth,counter)NE->(isInside,True,counter)SE->(isInside,False,counter)NW->(isInside==fromNorth,fromNorth,counter)SW->(isInside/=fromNorth,fromNorth,counter)Empty->(isInside,fromNorth,ifisInsidethencounter+1elsecounter)_->(isInside,fromNorth,counter)solve::Text->IO()solve=aocparserpart1part2
# Solution en Haskell
Posté par Guillaume.B . En réponse au message Advent of Code 2023 : Jour 10. Évalué à 1. Dernière modification le 11 décembre 2023 à 17:29.
Voici ma solution en Haskell.
La partie 1 utilise un BFS mais c'est un peu overkill.
La partie 2 repose sur des idées similaires à ce qu'a proposé Pierre.
Une partie non négligeable du code (la fonction getNiceInput) chercher à determiner quelle est la tuile adéquate pour remplacer la tuile Start.