Posté par steph1978 .
En réponse au message Avent du Code, jour 11.
Évalué à 3.
Dernière modification le 11 décembre 2022 à 13:39.
Je suis tombé dans le piège de la solution qui ne scale pas en deuxième partie. Pas grave, on s'adapte.
Pour les deux parties, pour éviter un parsing laborieux, j'ai transformé l'input en code. Car à bien y regarder, c'est du code :)
La solution naïve ne scale pas car passé une certaine taille (32bit je crois) l'arithmétique des grands entiers sort du processeur, doit repasser par la mémoire et devient très très lente.
Chez moi c'était très net : les 500 premiers rounds sont fulgurants, moins de 1s, puis chaque round prends presque une seconde. Pour faire les 100000, en admettant avoir assez de RAM, il faudrait donc une grosse heure à 100% de CPU. Je n'ai pas cette patience.
L'astuce pour passer à l'échelle est de limiter la taille des nombres manipulés en appliquant l'arithmétique modulaire. Chaque singe à son diviseur (un nombre premier mais je crois pas que ça joue). Donc au lieu d'avoir l'item sous forme de nombre, on le transforme en une liste de restes de division, un pour chaque singe.
part 1
Je vous épargne le code complet de la première partie qui est en gros celui de la deuxième partie en un peu plus simple.
input
fromcollectionsimportdequeM=[(deque([84,72,58,51]),lambdaold:old*3,lambdax:7ifdivmod(x,13)[1]else1)# ...# same for all monkeys# ...]
part 2
input
fromcollectionsimportdequePRIMES=(13,2,7,17,5,11,3,19)defmods(x):return[x%iforiinPRIMES]M=[[deque(mods(x)forxin[84,72,58,51]),lambdaold:[((o%i)*(3%i))%ifor(o,i)inzip(old,PRIMES)],lambdax:7ifx[0]else1,0],[deque(mods(x)forxin[88,58,58]),lambdaold:[((o%i)+(8%i))%ifor(o,i)inzip(old,PRIMES)],lambdax:5ifx[1]else7,0]# ...# same for all monkeys# ...]
# python, on oublie toute dignité
Posté par steph1978 . En réponse au message Avent du Code, jour 11. Évalué à 3. Dernière modification le 11 décembre 2022 à 13:39.
Je suis tombé dans le piège de la solution qui ne scale pas en deuxième partie. Pas grave, on s'adapte.
Pour les deux parties, pour éviter un parsing laborieux, j'ai transformé l'input en code. Car à bien y regarder, c'est du code :)
La solution naïve ne scale pas car passé une certaine taille (32bit je crois) l'arithmétique des grands entiers sort du processeur, doit repasser par la mémoire et devient très très lente.
Chez moi c'était très net : les 500 premiers rounds sont fulgurants, moins de 1s, puis chaque round prends presque une seconde. Pour faire les 100000, en admettant avoir assez de RAM, il faudrait donc une grosse heure à 100% de CPU. Je n'ai pas cette patience.
L'astuce pour passer à l'échelle est de limiter la taille des nombres manipulés en appliquant l'arithmétique modulaire. Chaque singe à son diviseur (un nombre premier mais je crois pas que ça joue). Donc au lieu d'avoir l'item sous forme de nombre, on le transforme en une liste de restes de division, un pour chaque singe.
part 1
Je vous épargne le code complet de la première partie qui est en gros celui de la deuxième partie en un peu plus simple.
input
part 2
input
main loop