Je peux dire que j'ai galéré sur celui là. Tout ça parce que j'ai mal lu l'énoncé.
Je n'avais pas vu qu'il fallait traiter les gestions de pulsations sous forme de file.
Je les traitais sous forme de pile et bizarrement ça m'a quand même donné la bonne réponse pour la première partie.
Pour la deuxième partie, c'est comme pour le jour 8, c'est très compliqué dans le cas général mais facile parce que l'instance a de bonnes propriétés (je n'aime pas trop ce genre de journée).
Tout d'abord, on remarque que rx a un seul prédécesseur qui est de type Conjonction et que celui a 4 prédécesseurs (que je vais appeler a, b, d) chacun de type Conjonction.
Ensuite, si on enlève broadcaster, rx et son prédécesseur, on se retrouve avec 4 composantes connexes et donc les pulsations de chacune vont vivre leur vie indépendamment des autres.
Si, on regarde quand a, b, c ou d envoie une pulsation forte, on remarque que ça forme un cycle sans prépériode et qu'une pulsation forte n'apparait qu'une seule fois durant un cycle.
Il suffit donc de repérer pour a, b, c et d la première fois qu'il y a une pulsation forte et faire le PPCM entre les différentes valeurs trouvées.
Pour le code en Haskell, j'utilise une monade State et des Lens, ce qui me permet de simplifier l'écriture.
dataType=FlipFlop|Conjunction|BroadcasterdataModule=Module!Type[String]typeNetwork=HashMapStringModuledataNState=NState{_ffState::!(HashMapStringBool)-- the state of flip flap mdoules,_from::!(HashMapString(HashMapStringBool))-- last signal sent by predecessor,_nbLow::!Int,_nbHigh::!Int,_seen::!(HashMapStringBool)}makeLenses''NStateparser::ParserNetworkparser=insertRx.Map.fromList<$>module_`sepEndBy1`eolwheremodule_=dot<-type_n<-name<*" -> "ns<-name`sepBy1`", "pure(n,Moduletns)name=somelowerChartype_=FlipFlop<$"%"<|>Conjunction<$"&"<|>pureBroadcasterinsertRx=Map.insert"rx"(ModuleBroadcaster[])sendSignal::Network->Seq(String,String,Bool)->StateNState()sendSignalnetwork=\caseSeq.Empty->pure()((name,srcName,pulse):<|queue')->doifpulsethennbHigh+=1elsedonbLow+=1seen.ixname.=TrueletModuletype_dests=networkMap.!namecasetype_ofBroadcaster->sendSignalnetwork$queue'><Seq.fromList(map(,name,False)dests)FlipFlop->ifpulsethensendSignalnetworkqueue'elsedonstate<-getletstate=_ffStatenstateMap.!nameffState.ixname.=notstatesendSignalnetwork$queue'><Seq.fromList(map(,name,notstate)dests)Conjunction->dofrom.ixname.ixsrcName.=pulsenstate<-getletsignal'=anynot$Map.elems(_fromnstateMap.!name)sendSignalnetwork$queue'><Seq.fromList(map(,name,signal')dests)round::Network->StateNState()roundnetwork=doseen.=Map.map(constFalse)networksendSignalnetwork$Seq.singleton("broadcaster","$dummy",False)initNState::Network->NStateinitNStatenetwork=NStateinitFfStateinitFrom00initSeenwhereinitFfState=Map.map(constFalse)networkemptyFrom=Map.map(constMap.empty)networkedgeList=concat.Map.elems$Map.mapWithKeygonetworkgou(Module_vs)=map(u,)vsinitFrom=foldl'go'emptyFromedgeListgo'from_(u,v)=Map.adjust(Map.insertuFalse)vfrom_initSeen=Map.map(constFalse)networkpart1::Network->Intpart1network=_nbLowfinalState*_nbHighfinalStatewherenstate=initNStatenetworkfinalState=flipexecStatenstatedoforM_[(1::Int)..1000]\_->roundnetworkpart2::Network->Integerpart2network=foldl'lcm1cycleswherenstate=initNStatenetworkpredRx=head.Map.keys$_fromnstateMap.!"rx"predPredRx=Map.keys$_fromnstateMap.!predRxnstates=iterate'(execState(roundnetwork))nstatecycles=mapextractCyclepredPredRxextractCyclename=head[idx|(idx,True)<-zip[0..].map((Map.!name)._seen)$nstates]solve::Text->IO()solve=aocparserpart1part2
# Solution en Haskell
Posté par Guillaume.B . En réponse au message Advent of Code 2023, jour 20. Évalué à 2.
Je peux dire que j'ai galéré sur celui là. Tout ça parce que j'ai mal lu l'énoncé.
Je n'avais pas vu qu'il fallait traiter les gestions de pulsations sous forme de file.
Je les traitais sous forme de pile et bizarrement ça m'a quand même donné la bonne réponse pour la première partie.
Pour la deuxième partie, c'est comme pour le jour 8, c'est très compliqué dans le cas général mais facile parce que l'instance a de bonnes propriétés (je n'aime pas trop ce genre de journée).
Tout d'abord, on remarque que rx a un seul prédécesseur qui est de type Conjonction et que celui a 4 prédécesseurs (que je vais appeler a, b, d) chacun de type Conjonction.
Ensuite, si on enlève broadcaster, rx et son prédécesseur, on se retrouve avec 4 composantes connexes et donc les pulsations de chacune vont vivre leur vie indépendamment des autres.
Si, on regarde quand a, b, c ou d envoie une pulsation forte, on remarque que ça forme un cycle sans prépériode et qu'une pulsation forte n'apparait qu'une seule fois durant un cycle.
Il suffit donc de repérer pour a, b, c et d la première fois qu'il y a une pulsation forte et faire le PPCM entre les différentes valeurs trouvées.
Pour le code en Haskell, j'utilise une monade State et des Lens, ce qui me permet de simplifier l'écriture.