Suite de l'Avent du Code, jour 10.
Le PÚre Noël est tombé dans un torrent et n'a pas bien entendu ce que les lutins ont voulu lui dire avant de continuer leur chemin. Pour trouver un moyen de communiquer avec eux, il faut réimplémenter le processeur de son communicateur, qui a un peu souffert de l'humidité.
# En Python, modélisé
PostĂ© par đČ Tanguy Ortolo (site web personnel) . ĂvaluĂ© Ă 5. DerniĂšre modification le 10 dĂ©cembre 2022 Ă 13:03.
Sans surprise, j'ai implémenté un CPU selon les spécifications fournies. Mais pour ce qui est de faire quelque chose à partir des états qu'il atteint à des cycles donnés, je me suis amusé à y introduire ce que j'ai appelé un débogueur, je vous laisse découvrir ça.
# quick python
PostĂ© par steph1978 . ĂvaluĂ© Ă 3.
Rien Ă voir avec hier, les deux parties en une grosse demie heure.
part 1
part 2
[^] # Re: quick python
PostĂ© par Yth (Mastodon) . ĂvaluĂ© Ă 4. DerniĂšre modification le 10 dĂ©cembre 2022 Ă 15:14.
Tu peux simplifier un peu ta gestion des input en faisant ça :
Le premier point, d'utiliser
for l in sys.stdinpermet de ne pas lire tout l'input, mais simplement d'itérer sur les lignes, on reste plus bas en RAM, on traite un flux.Le second point, c'est d'utiliser *q pour prendre « ce qui reste ».
Dans le cas d'une ligne "noop" on a m="noop" et q=[].
Dans le cas de "addx XX" on a m="addx" et q=[XX], une list avec la valeur en premier (et unique) élément.
Mais en refilant *q à int, il « unpack » et int(*q) devient équivalent à int(XX).
Avec ça tu gÚres des instructions différentes, avec autant de paramÚtres que tu veux, tu t'en fous au niveau du parsing, tu veux juste connaßtre l'instruction et passer le reste à la gestion de l'instruction.
Ăa Ă©vite de rajouter un argument factice, et de splitter en ne prenant que les deux premiers.
PS: et aussi, chapeau pour la maĂźtrise d'awk, j'en suis pas lĂ !
[^] # Re: quick python
PostĂ© par steph1978 . ĂvaluĂ© Ă 3.
Ah ça c'est vu que j'ai bidouillé pour gérer un ou deux arguments par lignes :)
Merci pour l'astuce, ça me resservira.
# Entre deux.
PostĂ© par Yth (Mastodon) . ĂvaluĂ© Ă 3.
Moins modélisé que Tanguy, mais plus que steph.
Là je conserve tout l'historique des valeurs de X à chaque cycle, ça n'est évidemment pas viable sur un long programme.
Il faudrait optimiser pour la demande, c'est à dire écrire instruction aprÚs instruction l'état de l'écran pour le cycle qui passe, et faire un hook sur les valeurs de la premiÚre question, pour additionner/stocker par ailleurs.
Au début j'avais mis un compteur de cycle dans ma classe
cpumais à la fin je ne l'utilisais pas, alors je l'ai viré...C'est assez facile d' « optimiser » la classe cpu pour qu'elle dessine l'écran au fur et à mesure, on fait une méthode comme ça :
Et définir
self.col = 0; self.screen = []dans l'init.On remplace les appels Ă
self.history.append(self.X)parself.cycle().On réalise que
cpu.noopne fait plus qu'exécutercpu.cycle, donc on gardenoopetaddxdevient :On vire le
cpu.callpuisqu'on dessine l'écran à la volée dansmycpu.screenet on afficheprint("".join(mycpu.screen))à la fin. On n'a plus qu'à rajouter un history à 0 pour le cycle 0 inexistant, et on n'a plus besoin de fairereturn self.history[n-1]danscpu.__getitem__()Avec tout ça mis en place on a un code plus concis, plus clair, mais on conserve toujours l'historique pour la question 1, et s'en débarrasser oblige a faire un hook un peu crados dans
cpu.noop(), conserver le numĂ©ro du cycle courant, et sicycle%40==20ajouter Ăself.signal_strengthself.X * self.cycle.On se dĂ©barrasse de l'historique.
Plus propre ?
Moins propre ?
Difficile Ă dire...
Mais il s'agit de débuggage, donc on peut introduire un hook cpu.debug à chaque cycle, qui servirait à ça.
Bilan :
Bilan ?
8 octets de différence dans le fichier final, temps d'exécution rigoureusement similaire.
En pratique si on bourrine sur les entrées, le second code est plus lent puisqu'il maintient à jour un écran.
On peut utiliser un deque pour cpu.screen et avoir un scroll automatique, ça restreint la RAM utilisée, qui reste stable quelles que soient les données en entrées.
Alors que le premier fait juste un history.append(), ça pompe de la RAM (à l'infini d'ailleurs) mais pas du CPU.
# OĂč est la partie 2 ?
PostĂ© par gled . ĂvaluĂ© Ă 1.
Pour la somme des intensités, pas trop de difficultés, ma solution sans fioritures (en trichant un peu).
Mais que faut-il faire ensuite ? OĂč est la seconde partie de l'exercice sur la page d'adventofcode ? La derniĂšre phrase que je vois sur la page est :
Faut-il avoir un compte susnommé en bas de page pour le voir ?
[^] # Re: OĂč est la partie 2 ?
PostĂ© par Yth (Mastodon) . ĂvaluĂ© Ă 3.
Il faut te connecter, d'une façon ou d'une autre, j'utilise mon compte github perso.
Et là tu as un jeu de donnée personnalisées en entrée, et tu peux fournir le résultat dans un champs spécifique en bas de page.
Ăa te donne accĂšs au second exercice.
[^] # Re: OĂč est la partie 2 ?
PostĂ© par đČ Tanguy Ortolo (site web personnel) . ĂvaluĂ© Ă 4.
Oui, la seconde partie apparaßt alors avoir rentré la bonne réponse à la premiÚre partie. Et les données d'entrée et donc les bonnes réponses sont associées à une identité en effet.
[^] # Re: OĂč est la partie 2 ?
PostĂ© par gled . ĂvaluĂ© Ă 1.
Ah d'accord, merci Ă vous deux, Yth et đČ Tanguy Ortolo de la confirmation, bien dommage alors.
# Plus simple
PostĂ© par GaMa (site web personnel) . ĂvaluĂ© Ă 3.
J'ai trouvé ce jour assez facile.
J'ai pas modélisé un CPU complet comme Tanguy, c'est un peu l'enclume pour écraser la mouche.
L'astuce pour rester simple, c'est de remplacer une instruction add (sur deux cycles) par une instruction noop et une instruction add (sur un cycle). AprÚs ça roule tout seul.
Matthieu Gautier|irc:starmad
[^] # Re: Plus simple
PostĂ© par đČ Tanguy Ortolo (site web personnel) . ĂvaluĂ© Ă 3.
Ăa reste Ă voir, ça. Il y a eu un AoC oĂč on n'arrĂȘtait pas de ressortir un processeur bizarroĂŻde pour l'enrichir de nouvelles instructions et variantes d'instructions existantes.
Il y a un risque pour que ce ne soit pas la derniĂšre fois que nous aurons Ă bidouiller avec du code machine de communicateur elfique...
[^] # Re: Plus simple
PostĂ© par Yth (Mastodon) . ĂvaluĂ© Ă 2. DerniĂšre modification le 10 dĂ©cembre 2022 Ă 20:17.
C'est un peu l'idée derriÚre mon propre code.
Et si on l'enrichissait ?
Par exemple si on veut ajouter une commande
affxy a b- qui fait la fonction affinea*x+b- à deux arguments et trois cycles par exemple, dans mon code il suffit d'ajouter cette méthode :Voilà , c'est géré.
[^] # Re: Plus simple
PostĂ© par steph1978 . ĂvaluĂ© Ă 3.
C'est l'AoC 2019 au moins un jour sur deux il fallait ressortir son processeur "intcode".
# un bout de AWK
PostĂ© par steph1978 . ĂvaluĂ© Ă 4.
Je me suis laissé emporté par le python du jour 9.
Le problĂšme du jour passe trĂšs bien en AWK.
part 1, 11 lines
part 2, 20 lines
[^] # Re: un bout de AWK
PostĂ© par steph1978 . ĂvaluĂ© Ă 3.
Pour la partie deux, aucun intĂ©rĂȘt Ă bufferiser avant d'afficher :
awk, 14 loc
Suivre le flux des commentaires
Note : les commentaires appartiennent Ă celles et ceux qui les ont postĂ©s. Nous nâen sommes pas responsables.