J'ai enfin ma solution pour le jour 20.
1) J'ai exploré plusieurs solutions comme laisser mon PC calculé à l'aveugle pendant 1j de travail. Je chauffe en partie à l'électrique. Donc, cela ne me coutait pas de laisser mon PC cramer des Watt :).
2) J’ai tenté de simplifier les cycles des flip-flop sans grand succès. Car je pensais que les conjuctions serait beaucoup plus complexe avec leurs multiples false, true qu’elles crachent
3) Via récursivité de trouver une méthode pour factoriser les circuits. Je n’ai pas vu la solution suivante toute suite, car ma fonction recursive allé jusqu’au flip / flop. Mais au final,c’était trop complexe pour trouver une simplification évidente.
4) Finalement, j’ai tenté juste de regarder les cycles des trues sur les 4 conjonctions qui sont avant RX { "hz", "pv", "qh", "xm" }
Et là, c’était évident. J’avais des cycles réguliers pour ces 4 conjonctions. Il ne me reste plus qu’à trouver quand elles sont à true toutes les 4 en même temps. Ce qui revient à trouver le PPCM des 4 cycles.
J’ai demandé à chatgpt de me fournir le calcul d’un PPCM (çà se reconnait au style).
En prenant, le problème dans le bon sens, j’aurai pu le résoudre en 1h partie 1 et partie 2.... J’ai mis encore bien 5h cumulé.
publicclassAoc2023s20v3{publicrecordMessage(StringsourceName,booleanhight,Componentcomponent){}// Hard coded main conjunctionprotectedstaticfinalString[]CHECK_MAIN_RX_CONJUNCTION=newString[]{"hz","pv","qh","xm"};// Function to find the GCD (Greatest Common Divisor) of two numbersprivatestaticlongfindGCD(longa,longb){while(b!=0){longtemp=b;b=a%b;a=temp;}returna;}// Function to find the LCM (Lowest Common Multiple) of two numbersprivatestaticlongfindLCM(longa,longb){return(a*b)/findGCD(a,b);}// Function to find the LCM of an array of numberspublicstaticlongfindLCMOfArray(Long[]numbers){if(numbers.length==0){thrownewIllegalArgumentException("Array should not be empty");}longlcm=numbers[0];for(inti=1;i<numbers.length;i++){lcm=findLCM(lcm,numbers[i]);}returnlcm;}publicstaticabstractclassComponent{Stringname;String[]targetNames=newString[0];publicMap<String,Message>getMessageHight=newHashMap<>();publicMap<String,Message>getMessageLow=newHashMap<>();privateMessage[]sendTrue;privateMessage[]sendFalse;publicHashMap<Long,List<Boolean>>signalHistory=newLinkedHashMap<>();publicComponent(Stringname){this.name=name;}publicvoidregisterInput(Stringname){}publicvoidclear(){}publicvoidprocess(Circuitcircuit,Messagemessage){}publicfinalvoidsend(Circuitcircuit,booleansendSignalHight){Message[]toSend;if(sendSignalHight){if(sendTrue==null){sendTrue=Arrays.stream(targetNames).map(target->newMessage(this.name,sendSignalHight,circuit.elementsByName.get(target))).toArray(k->newMessage[k]);}toSend=sendTrue;}else{if(sendFalse==null){sendFalse=Arrays.stream(targetNames).map(target->newMessage(this.name,sendSignalHight,circuit.elementsByName.get(target))).toArray(k->newMessage[k]);}toSend=sendFalse;}if(thisinstanceofConjuction&&sendSignalHight)signalHistory.computeIfAbsent((long)circuit.circuitIndex,(k)->newArrayList<Boolean>()).add(sendSignalHight);ArrayDeque<Message>messages=circuit.messages;for(Messagetarget:toSend){messages.add(target);}}publicStringexpr(Circuitcircuit){returnthis.name;}}publicstaticclassFlipFlopextendsComponent{booleanstate;publicFlipFlop(Stringname){super(name);}@Overridepublicvoidclear(){state=false;}@Overridepublicvoidprocess(Circuitcircuit,Messagemessage){if(message.hight){// do nothingreturn;}this.state=!state;send(circuit,this.state);}@OverridepublicStringtoString(){return"FlipFlop [state="+state+", name="+name+", targetNames="+targetNames+"]";}publicStringexpr(Circuitcircuit){return"%"+this.name;}}publicstaticclassConjuctionextendsComponent{privatelongstate=0;privatelongallUp=0;privateMap<String,Long>inputMask=newHashMap<>();privateMap<String,Long>notInputMask=newHashMap<>();publicConjuction(Stringname){super(name);}@OverridepublicvoidregisterInput(Stringname){intnextId=inputMask.size();longmask=1L<<nextId;inputMask.put(name,mask);notInputMask.put(name,~mask);allUp=(1L<<(nextId+1))-1;}@Overridepublicvoidprocess(Circuitcircuit,Messagemessage){if(message.hight){longmask=inputMask.get(message.sourceName);state=state|mask;}else{longnotMask=notInputMask.get(message.sourceName);state=state¬Mask;}varnotAllTrue=state!=allUp;send(circuit,notAllTrue);}@OverridepublicStringtoString(){return"Conjuction [name="+name+", targetNames="+targetNames+"]";}publicStringexpr(Circuitcircuit){return"/*"+this.name+"*/("+this.inputMask.keySet().stream().map(n->circuit.elementsByName.get(n).expr(circuit)).collect(Collectors.joining(" & "))+") \n";}}publicstaticclassOutputextendsComponent{privatelongcountHight;privatelongcountSmall;publicOutput(Stringname){super(name);}@Overridepublicvoidclear(){this.countHight=0;this.countSmall=0;}@Overridepublicvoidprocess(Circuitcircuit,Messagemessage){if(message.hight)countHight++;elsecountSmall++;}@OverridepublicStringtoString(){return"Output [countHight="+countHight+", countSmall="+countSmall+", name="+name+", targetNames="+targetNames+"]";}}publicstaticclassCircuit{Map<String,Component>elementsByName=newHashMap<>();String[]broadcastList=newString[0];ArrayDeque<Message>messages=newArrayDeque<>();longcountHight;longcountLow;longcircuitIndex=0;voidparse(Scannerin){while(in.hasNext()){Stringrow=in.nextLine();String[]part=row.split("->");StringtypeName=part[0].trim();String[]targetNames=Arrays.stream(part[1].trim().split(",")).map(String::trim).toArray(k->newString[k]);if("broadcaster".equals(typeName)){broadcastList=targetNames;}elseif(typeName.startsWith("%")){FlipFlopflipFlop=newFlipFlop(typeName.substring(1));flipFlop.targetNames=targetNames;elementsByName.put(flipFlop.name,flipFlop);}elseif(typeName.startsWith("&")){Conjuctionc=newConjuction(typeName.substring(1));c.targetNames=targetNames;elementsByName.put(c.name,c);}}elementsByName.put("output",newOutput("output"));elementsByName.put("rx",newOutput("rx"));for(Componentsource:elementsByName.values()){for(Stringtarget:source.targetNames){Componentrx=elementsByName.get(target);if(rx!=null){rx.registerInput(source.name);}}}for(Stringtarget:broadcastList){elementsByName.get(target).registerInput("broadcast");}}publiclongexperienceToFindWhereRxIsUp(longcount){messages.clear();elementsByName.values().forEach(Component::clear);countHight=0;countLow=0;longs=System.currentTimeMillis();intx=0;while(true){circuitIndex=x;countLow++;for(Stringinitial:broadcastList){messages.add(newMessage("broadcast",false,elementsByName.get(initial)));}processMessages();if(x>count){System.out.println("seek "+x+" "+(System.currentTimeMillis()-s)+"ms");s=System.currentTimeMillis();returntryToFindLcmInMainConjuction();}x++;}}privatelongtryToFindLcmInMainConjuction(){List<Long>toComputeLcm=newArrayList<>();for(Stringname:CHECK_MAIN_RX_CONJUNCTION){Componentc=elementsByName.get(name);System.out.println(c.name+" => "+c.signalHistory.keySet());Longprevious=null;LongpreviousDiff=null;for(Longl:c.signalHistory.keySet()){if(previous!=null){longdiff=l-previous;System.out.print((l-previous)+",");if(previousDiff!=null){if(diff==previousDiff){toComputeLcm.add(diff);}else{System.out.println("Can't compute LCM");}}previousDiff=diff;}previous=l;}System.out.println();}returnfindLCMOfArray(toComputeLcm.toArray(newLong[toComputeLcm.size()]));}privatevoidprocessMessages(){while(!messages.isEmpty()){Messagemessage=messages.pollFirst();if(message.hight){countHight++;}else{countLow++;}message.component.process(this,message);}}}publicstaticvoidmain(String[]args){try(Scannerin=newScanner(Aoc2023s18v2.class.getResourceAsStream("res/t20.txt"))){Circuitcircuit=newCircuit();circuit.parse(in);longresult=circuit.experienceToFindWhereRxIsUp(20000);System.out.println(result);}}}
# Enfin...
Posté par syj . En réponse au message Advent of Code 2023, jour 20. Évalué à 1.
J'ai enfin ma solution pour le jour 20.
1) J'ai exploré plusieurs solutions comme laisser mon PC calculé à l'aveugle pendant 1j de travail. Je chauffe en partie à l'électrique. Donc, cela ne me coutait pas de laisser mon PC cramer des Watt :).
2) J’ai tenté de simplifier les cycles des flip-flop sans grand succès. Car je pensais que les conjuctions serait beaucoup plus complexe avec leurs multiples false, true qu’elles crachent
3) Via récursivité de trouver une méthode pour factoriser les circuits. Je n’ai pas vu la solution suivante toute suite, car ma fonction recursive allé jusqu’au flip / flop. Mais au final,c’était trop complexe pour trouver une simplification évidente.
4) Finalement, j’ai tenté juste de regarder les cycles des trues sur les 4 conjonctions qui sont avant RX { "hz", "pv", "qh", "xm" }
Et là, c’était évident. J’avais des cycles réguliers pour ces 4 conjonctions. Il ne me reste plus qu’à trouver quand elles sont à true toutes les 4 en même temps. Ce qui revient à trouver le PPCM des 4 cycles.
J’ai demandé à chatgpt de me fournir le calcul d’un PPCM (çà se reconnait au style).
En prenant, le problème dans le bon sens, j’aurai pu le résoudre en 1h partie 1 et partie 2.... J’ai mis encore bien 5h cumulé.