# Advent of Code 2022, day 8from__future__importannotationsfrommathimportprodfromtypingimportIterable,Iterator,Set,Tuple,TypeimportnumpyasnpCoords=Tuple[int,int]classGrid:def__init__(self,matrix:np.ndarray)->None:self.matrix=matrixself.ly=matrix.shape[0]self.lx=matrix.shape[1]def__scans(self)->Iterator[Iterator[Iterator[Coords]]]:yield(((y,x)forxinrange(self.lx))foryinrange(self.ly))yield(((y,x)forxinrange(self.lx-1,-1,-1))foryinrange(self.ly))yield(((y,x)foryinrange(self.ly))forxinrange(self.lx))yield(((y,x)foryinrange(self.ly-1,-1,-1))forxinrange(self.lx))defvisible_from_outside(self)->Set[Coords]:visible_trees=set()# type: Set[Coords]forscaninself.__scans():forlineinscan:max_height=-1forcoordsinline:cur_height=self.matrix[coords]ifcur_height>max_height:visible_trees.add(coords)max_height=cur_heightreturnvisible_treesdef__viewing_distance(self,orig:Coords,line:Iterator[Coords])->int:height=self.matrix[orig]d=0forcoordsinline:d+=1ifself.matrix[coords]>=height:returndreturnddef__lines_of_sight(self,coords:Coords):y,x=coordsyield((y,x_)forx_inrange(x+1,self.lx))yield((y,x_)forx_inrange(x-1,-1,-1))yield((y_,x)fory_inrange(y+1,self.ly))yield((y_,x)fory_inrange(y-1,-1,-1))defscenic_score(self,coords:Coords):returnprod(self.__viewing_distance(coords,line)forlineinself.__lines_of_sight(coords))@classmethoddefimport_lines(class_:Type[Grid],lines:Iterable[str])->Grid:matrix=np.genfromtxt(lines,delimiter=1,autostrip=True,dtype=int)returnclass_(matrix)defsolve_both(lines:Iterable[str])->Tuple[int,int]:"""Solve both parts of today's puzzle"""# Importgrid=Grid.import_lines(lines)# Part 1visible=len(grid.visible_from_outside())# Part 2max_score=max(grid.scenic_score(coords)forcoordsinnp.ndindex(grid.matrix.shape))returnvisible,max_score
$ cd /
$ ls
4212 aoc.py
dir 2021
dir 2022
$ cd 2021
$ ls
dir 12
$ cd ..
$ cd 2022
$ ls
dir 12
$ cd ..
$ cd 2021
$ cd 12
$ ls
42 01.py
12 02.py
51 03.py
$ cd ..
$ cd ..
$ cd 2022
$ cd 12
$ ls
12 01.py
51 02.py
42 03.py
C'est idiot, on est d'accord. Mais ce n'est pas un parcours en profondeur d'abord.
Et surtout pas de yield dans la fonction recursive qui aplatit les repertoires (je copie les references dans une nouvelle list). J'avoue que ta solution est plus elegante, et c'est marrant que tu fasses du code presque prod ready (mypy…).
# Advent of Code 2022, day 7from__future__importannotationsimportrefromenumimportEnumfromtypingimportDict,Iterable,Iterator,Optional,TupleclassFile:def__init__(self,size:int):self.size=sizeclassRegularFile(File):def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)classDirectory(File):def__init__(self,parent:Optional[Directory]=None):ifparentisNone:# root directoryparent=selfself.files={'..':parent}# type: Dict[str, File]self._size=None# type: Optional[int]@property# https://github.com/python/mypy/issues/4125defsize(self)->int:# type: ignoreifself._sizeisNone:self._size=sum(f.sizeforname,finself.files.items()ifname!='..')# mypy does not realize self._size can no longer be Nonereturnself._size# type: ignoredefadd(self,name,f:File)->None:self.files[name]=fdefdirs(self)->Iterator[Directory]:yieldselfforname,finself.files.items():ifisinstance(f,Directory)andname!='..':yield fromf.dirs()classState:re_cd=re.compile(r'^\$ cd (.*)\n?$')re_ls=re.compile(r'^\$ ls\n?$')re_reg=re.compile(r'^(\d+) (.*)\n?$')# regular filere_dir=re.compile(r'^dir (.*)\n?$')def__init__(self,root:Directory):self.root=rootself.cwd=rootself.in_ls=Falsedefcd(self,name:str)->None:# Only 'cd /' or 'cd subdir'!ifname=='/':self.cwd=self.rootelse:target=self.cwd.files[name]ifisinstance(target,Directory):self.cwd=targetelse:raiseValueError('cannot cd to a regular file')definput(self,line:str)->None:if(m:=self.re_cd.match(line))isnotNone:self.in_ls=Falseself.cd(m.group(1))elif(m:=self.re_ls.match(line))isnotNone:self.in_ls=Trueelifself.in_lsand(m:=self.re_reg.match(line))isnotNone:size=int(m.group(1))name=m.group(2)self.cwd.add(name,RegularFile(size))elifself.in_lsand(m:=self.re_dir.match(line))isnotNone:name=m.group(1)self.cwd.add(name,Directory(parent=self.cwd))else:raiseValueError("unexpected line '{}'".format(line.rstrip()))defimport_tree(lines:Iterable[str])->Directory:root=Directory()state=State(root)forlineinlines:state.input(line)returnrootdefsolve_both(lines:Iterable[str])->Tuple[int,int]:"""Solve both parts of today's puzzle"""root=import_tree(lines)result1=sum(d.sizefordinroot.dirs()ifd.size<=100000)total=70000000# total storage spaceneeded=30000000# storage space needed for system updateused=root.size# used storage spaceavailable=total-used# currently available storage spaceto_free=needed-available# storage space to freeresult2=min(d.sizefordinroot.dirs()ifd.size>=to_free)returnresult1,result2
fromtypingimportIterabledefsolve1(lines:Iterable[str])->int:"""Solve part 1 of today's puzzle"""forlineinlines:# There is actually only one line :-)foriinrange(4,len(line)-1):# ignore final '\n'iflen(set(line[i-4:i]))>=4:returnireturn0defsolve2(lines:Iterable[str])->int:"""Solve part 2 of today's puzzle"""forlineinlines:# There is actually only one line :-)foriinrange(14,len(line)-1):# ignore final '\n'iflen(set(line[i-14:i]))>=14:returnireturn0
Vous vous souvenez sans doute encore d'une petite phrase de l'intro :
To supply enough magical energy, the expedition needs to retrieve a minimum of fifty stars by December 25th. Although the Elves assure you that the grove has plenty of fruit, you decide to grab any fruit you see along the way, just in case.
# Procrastination
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 8. Évalué à  3.
Alors qu'on a enfin quitté le camp pour aller chercher des caramboles, je ne peux m'empêcher que ça procrastine encore :
– Voilà , le verger c'est par là …
– Oh, regardez, la forêt que nous avons planté il y a quelques années, on pourrait y construire une cabane !
– Oui, super, ça nous changera les idées. Lutin drone-opérateur, tu nous cartographie ça ?
– Patron, venez nous donner un coup de main pour calculer le meilleur emplacement pour notre cabane au lieu d'essayer de régler votre communicateur. On vous l'a déjà dit, il est défectueux, et vous aurez tout le temps pour le réparer plus tard. On a plus important à faire là  !
– Et les fruits pour les rennes alors ?
– Les quoi ? Ah, ça… On n'y est pas encore, soyez patient. Vous êtes pressé, vous avez un rendez-vous qui approche ou quoi ?
# Python avec Numpy
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 8. Évalué à  4.
Bon, j'ai sorti Numpy du coup. C'est modélisé, et assez long en fait.
[^] # Re: HS
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  3.
En fait, en matière d'assurance, et d'assurance de quoi que ce soit en fait, je pense qu'il serait possible d'autoriser la modulation de cotisation en fonction de n'importe quoi qui relève du choix de l'assuré, à condition que le traitement des informations correspondantes soit légal évidemment. L'âge et l'état de santé par exemple, ne relèvent pas du tout du choix.
Mais le tabagisme, le nombre d'infractions routières ou encore le nombre de soirées passées au cinéma chaque mois, relèvent du choix. Le dernier exemple n'a rien de pertinent, mais inutile d'interdire la modulation d'un tarif en fonction de cela : lorsque ce n'est pas pertinent, c'est inintéressant à appliquer, parce que cela ne correspond pas au risque assuré, que ça attirera juste une clientèle spécifique et que la remise correspondante s'avérera coûteuse pour l'assureur.
[^] # Re: HS
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  4.
Il y a plusieurs choses lĂ -dedans. Les taxes ont deux rĂ´les :
Ça n'a rien de subjectif, ça a été étudié, et surprise, le vélotaf est dangereux, mais ne pas en faire l'est encore plus. Les assureurs sont d'accord, ce qui est l'essentiel, dans cette discussion.
https://www.matmut.fr/assurance/nvei/conseils/velo-travail-bonnes-raisons
https://www.ors-idf.org/nos-travaux/publications/les-benefices-et-les-risques-de-la-pratique-du-velo/
Non, pas du tout, c'est une question de justice. C'est comme les assurances emprunteur par exemple : non fumeur, ça coûte moins cher que fumeur, c'est juste normal. Et ça ne pénalise que ceux qui le veulent bien.
Pas forcément moduler ainsi les cotisations, simplement permettre de le faire. Pour la vaccination, c'est pertinent aussi en effet. Beaucoup plus pertinent qu'une obligation plus ou moins forte en fait, puisqu'il s'agit de répercuter directement le coût statistique d'un choix personnel sur le budget de celui qui le fait. Pour responsabiliser les gens, on ne peut pas faire mieux je pense. Tant qu'il s'agit simplement de critères qui relèvent du choix des gens, aucun problème.
# Procrastination
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 7. Évalué à  4.
On dirait que le Père Noël, ou les lutins, ou les deux, ne sont pas si motivés que ça pour aller effectivement courir la jungle pour récolter des caramboles. Ça traîne à faire des inventaires, à monter le camp, à nettoyer le camp, à décharger le bateau, à réorganiser le matériel déchargé, à bidouiller des communicateurs, à mettre à jour ces communicateurs…
Ça fait six jours qu'on a débarqué, et n'a pas encore bougé du camp ! Vivement que les lutins nous fournissent une carte pour aller quelque part.
[^] # Re: C'est parti !
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Calendrier de l'Avent du code. Évalué à  4.
Sujets plus simple, je suis d'accord… pour le moment. Ça pourrait se corser d'un coup !
[^] # Re: Vivement , le 1
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Calendrier de l'Avent du code. Évalué à  6.
Pareil pour moi, surtout que j'aime faire du beau code, et que ça ne va pas bien avec l'idée de faire la course.
Mais pas d'inquiétude, on devrait finir par avoir des problèmes qu'on sera déjà content de parvenir à résoudre tout court, au bout d'un moment. :-)
[^] # Re: un bout de AWK
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 7. Évalué à  3. Dernière modification le 07 décembre 2022 à 15:19.
C'est idiot, on est d'accord. Mais ce n'est pas un parcours en profondeur d'abord.
[^] # Re: En Python bref
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 2. Évalué à  3. Dernière modification le 07 décembre 2022 à 14:52.
Waouh. C'est pour le moins original ça.
Si je comprends bien, ça fait de
~
une opération pour récupérer la valeur normalisée. Bien joué le(valeur % 3) or 3
, c'est bien plus lisible que(valeur - 1) % 3 + 1
.La valeur qui me vainc et la valeur que je vaincs, si je ne m'abuse.
Je suis plus inférieur à un autre si la valeur qui me vainc est la même que la valeur normalisée de l'autre. Et mutatis mutandis pour la supériorité. Tu aurais pu utiliser functool.total_ordering().
Ensuite, le reste est assez simple à comprendre, une fois ces bases posées. La réutilisation des opérateurs est… intéressante. Je ne peux pas dire que je suis fan, c'est un peu bizarre à lire quand même.
Tiens, j'ignorais la possibilité d'instancier un dictionnaire avec des mots-clefs. C'est amusant, ça aussi.
[^] # Re: Mutuelle
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  1.
Je suis tout aussi critique que toi sur le fait de ne pas avoir le choix. Je rêve d'avoir le choix entre la CPAM et d'autres assureurs. Et je ne vois pas le problème que ça poserait, du moment que la couverture est règlementée (obligation de couvrir au moins ceci et cela à tel taux ou plafond de remboursement), ainsi et que l'éligibilité et la tarification différenciée : concrètement, interdiction de refuser les vieux et les cancéreux et de leur faire payer plus cher parce que ce n'est pas un choix, mais permission de faire payer plus cher les fumeurs, et moins cher les gens qui font trois heures d'exercice par semaine, vélotaf inclus.
[^] # Re: En Python
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 7. Évalué à  3.
Pas en ReiserFS, le système de fichier qui tue le gaspillage d'espace de stockage.
[^] # Re: En Python
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 7. Évalué à  5.
Je profite en fait de l'AoC pour découvrir les fonctionnalités de typage de Python. Une fois passé l'apprentissage, qui n'est vraiment pas horrible, ça ne fait pas perdre du temps, au contraire, ça permet de détecter certaines erreurs de façon bien plus rapide et de mieux identifier d'où elles viennent.
[^] # Re: un bout de AWK
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 7. Évalué à  3.
Bien joué, je n'avais pas remarqué cela. Ceci dit, je n'aime pas trop me baser sur des suppositions qui ne sont absolument pas garanties par l'énoncé.
# En Python
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 7. Évalué à  5.
Ça commence à devenir un tout petit peu sérieux. Aucune vraie difficulté à comprendre ou à implémenter le problème, mais on commence à sortir des trucs un peu récursifs.
En bon unixien, je considère bien sûr qu'un répertoire est un type particulier de fichier, qu'il contient toujours une vraie entrée
..
, et que le nom d'un fichier n'est pas une propriété intrinsèque mais simplement un nom qu'il porte dans une entrée de répertoire.[^] # Re: Mutuelle
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  8.
Exact, mais sans intérêt. Ce qui est intéressant, c'est de comprendre de quoi on parle : un système régi par la loi et des assurances qui en sont l'implémentation, sous la forme d'une sorte d'oligopole légal assez unique en son genre.
L'utilisation de termes aussi vague que « la sécu » me semble donner l'impression qu'il s'agirait d'une administration d'État, avec laquelle les citoyens auraient la même relation qu'avec le fisc ou la préfecture du coin. Ça en fait un organisme puissant et distant de ses clients.
Alors que c'est bien plus clair en parlant simplement d'assurance : il n'est pas question de citoyens mais d'adhérents (voire de clients), et la relation est la même que celle qu'on peut avoir avec son assureur habitation ou automobile (d'ailleurs c'est obligatoire aussi, seulement pour celles-là , on a le choix de l'assureur).
[^] # Re: Mutuelle imposée
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  7.
Sauf que ce n'est pas du tout offert, c'est payé par les cotisation des employés. À moins qu'ils n'y ait des preuves, ou au moins de soupçons que l'employeur paie discrètement un supplément de cotisation sans le déclarer justement.
Sinon, ça ce compte-là , on pourrait aussi dire que le remboursement de l’ostéopathie est « offerte » puisqu'il n'y a pas de surcoût. C'est idiot, ça fait partie du contrat, en échange de la cotisation.
[^] # Re: Mutuelle imposée
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  6.
Avantage en nature non déclaré ‽ Avantage en nature, d'accord, mais non déclaré, c'est n'importe quoi, la cotisation apparaît sur la fiche de paie !
Je comprendrais que des célibataires se sentent lésés par le fait de cotiser ce qu'il faut pour couvrir les conjoints des autres, mais ce n'est pas du tout un problème de déclaration de l'avantage en question.
[^] # Re: Mutuelle imposée
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  8.
Pas tout ça fait, c'est pire que ça. L'assurance complémentaire peut exigée une preuve que tu es couvert obligatoirement par celle de ton conjoint. Si c'est facultatif, même sans surcoût, ils peuvent refuser.
Ça fait partie des idées de lois dont je dois parler à mon député. Dans le même sens que la liberté de choisir son assurance emprunteur, ce serait bien d'avoir la liberté de choisir son assurance complémentaire santé. L'obligation pour l'employeur d'en fournir une pourrait être maintenue, avec la possibilité de cesser d'y cotiser sur preuve qu'on a déjà une complémentaire santé, sans plus de contrainte.
[^] # Re: Mutuelle imposée
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  6. Dernière modification le 06 décembre 2022 à 16:37.
Oui. On a le droit de ne pas adhérer à la
mutuelleassurance complémentaire santé (cf. infra) obligatoirement proposée par son employeur, à condition de prouver qu'on est obligatoirement couvert par celle de son conjoint.C'est très subtil, parce que si par exemple, l'assurance de ton conjoint te couvre de façon optionnelle, mais sans surcoût, ça ne te donne pas le droit de ne pas adhérer à la tienne.
(Bon, après, la seule différence entre un certificat comme quoi on est couvert sans surcoût, et un certificat comme quoi on est obligatoirement couvert sans surcoût, c'est un seul mot, donc rien d'insurmontable, si vous voyez ce que je veux dire. o:-) )
# Mutuelle
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au journal Mutuelle et mot de passe. Évalué à  10.
Non. Tu nous parles de ton assurance santé et prévoyance. Une mutuelle, c'est une forme d'entreprise, assez répandue dans le domaine de l'assurance et de la banque, mais ce n'est sans doute pas le cas de la tienne. C'est très facile à vérifier : est-ce que tu es invité à voter pour élire les dirigeants de cette société d'assurance ? Sinon, ce n'est pas une mutuelle.
Je ne sais pas d'où sort cette utilisation du terme de « mutuelle » pour désigner de façon générique une assurance santé, mais il faut vraiment arrêter ça.
C'est comme l'utilisation du terme de « sécurité sociale » pour désigner un organisme imaginaire, je trouve que cela nuit à la compréhension de la réalité. La sécurité sociale, c'est un système, pas une entreprise. Ce système est essentiellement composé de multiples compagnies d'assurance, la plus grosse d'entre elles étant la Caisse primaire d'assurance maladie. On ne cotise pas à « la sécu », on est adhérent d'un assureur particulier, en l'occurrence la CPAM pour les salariés du privé, mais il y en a d'autres.
[^] # Re: En Python
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 6. Évalué à  3.
Ça n'optimise rien du tout, si ?
Je veux dire, nous avons tous deux la ligne entière en mémoire, mais là où j'en prends à chaque fois une tranche pour la convertir en ensemble et regarder sa longueur, tu enfonces un par un chacun de ses caractères dans une file à taille limitée, que tu convertis en ensemble pour regarder sa longueur.
Quoique, ça évite une copie de chaîne à chaque étape, c'est ça ? La file à taille limitée étant persistante et ne copiant qu'un caractère à chaque fois.
# En Python
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 6. Évalué à  4.
Le fait que mes fonctions mangent un itérable de chaînes vient des fonctions utilitaires que j'ai codées pour intégrer ça facilement. Ici, ça donne quelque chose d'un peu artificiel puisqu'il n'y a qu'une ligne à lire.
Je ne suis pas du tout satisfait par le fait de transformer à chaque fois un bout glissant de la chaîne d'entrée en un ensemble. J'aimerais bien faire quelque chose d'un peu mieux optimisé, mais je n'ai rien de probant en tête.
[^] # Re: On va peut-ĂŞtre enfin y aller ?
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 5. Évalué à  3.
Au fait, avez-vous remarqué ce qu'on trouve dans la boutique de l'Avent du Code cette année ? On dirait qu'on va bientôt changer de moyen de transport.
# On va peut-ĂŞtre enfin y aller ?
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 5. Évalué à  3.
Vous vous souvenez sans doute encore d'une petite phrase de l'intro :
Juste au cas où, bien sûr… Cette précaution commence à prendre du sens, vu que les lutins ont visiblement besoin d'être babysittés en permanence ! Quelle surprise, à se demander comment ils arrivaient à ramener ce qu'il faut les Noëls précédents. Heureusement qu'on a pris de l'avance en collectant des fruits en étoile au fur et à mesure !
Bref, j'ai l'impression qu'on arrive au bout de l'installation et qu'on va pouvoir partir en expédition dans la jungle. Et quelque chose me dit que ça ne va pas tout à fait se passer comme prévu.
Vous imaginez quoi pour demain ? Je verrais bien quelque chose à base de carte de zones plus ou moins dangereuses et de détermination de parcours optimisé…
[^] # Re: un bout de AWK
Posté par 🚲 Tanguy Ortolo (site web personnel) . En réponse au message Avent du Code, jour 4. Évalué à  3.
C'est tout à fait ça. Mais à vrai dire, dès que le problème que je cherche à résoudre n'est pas un truc jetable, en particulier lorsqu'il s'agira de le montrer à d'autres ou de revenir dessus, j'utilise de moins en moins Awk.
Je trouve en effet que, sauf quand c'est vraiment très simple, ça donne quelque chose de très peu compréhensible à la lecture ou à la relecture.