Beaucoup moins académique que Guillaume, très itératif, les deux parties en 22 lignes:
boxes=[tuple(map(int,line.split(",")))forlineinopen(0).read().strip().split('\n')]clusters=dict()forc,(_,(i,j))inenumerate(sorted(((x-l)**2+(y-m)**2+(z-n)**2,(i,i+1+j))fori,(x,y,z)inenumerate(boxes)forj,(l,m,n)inenumerate(boxes[i+1:]))):icl=[[kfor(k,v)inclusters.items()ifiinv]or["ALONE"]][0][0]jcl=[[kfor(k,v)inclusters.items()ifjinv]or["ALONE"]][0][0]match(icl=="ALONE",jcl=="ALONE",icl==jcl):case(False,False,False):# both belongs to different clusters, merge clustersclusters[f'{i}_{j}']=clusters[icl]|clusters[jcl]delclusters[icl]delclusters[jcl]case(False,True,_):clusters[icl].add(j)case(True,False,_):clusters[jcl].add(i)case(True,True,_):# both out of clusters, create a new cluster with themclusters[f'{i}_{j}']={i,j}# else (False, False, True), i and j are in the same clusterifc==1000:s=sorted(map(len,clusters.values()))print(s[-1]*s[-2]*s[-3])ifc>1000andlen(clusters)==1:print(boxes[i][0]*boxes[j][0])# 5267 connsbreak
J'étais ravi d'ouvrir un problème en 3D, ça fait des jolies illustrations.
J'ai trouvé rapidement l'algo mais j'ai perdu énormément de temps sur:
1/ une mauvaise lecture du calcul qu'il fallait produire pour la première partie ; my bad
2/ le fait qu'il fallait compter comme un connexion le fait de ne rien faire :/
à force de tâtonner, j'ai finit par incrémenter dans tous les cas pour voir et je suis tombé sur la solution ; pas agréable
Première partie très simple, pour chaque line, à chaque fois qu'on split, incrémenter de 1.
Seconde partie, je n'ai pas vu la technique de programmation dynamique que vous évoqués.
J'ai vu un parcours de graphe.
Par flemme de l'implémenter moi même, j'ai voulu le faire avec une lib. Grosse erreur, elle a tournée pendant des plombes et de retour de promenade, je l'ai killé (heureusement que c'est l'hiver et qu'on chauffe).
J'ai finalement implémenté moi même et ça s'est bien passé. Pour éviter l'explosion combinatoire, j'ai utilisé un cache.
Je ne suis pas très fan du problème de ce jour. Je préfère les problèmes avec des astuces algorithmiques (enfin, il y en a peut-être mais je ne les ai pas vu).
Tout pareil.
Je mets le code de la partie 1, c'est le moins laid des deux:
I=open(0).read().strip().split("\n\n")R=[i.split("-")foriinI[0].split("\n")]R=sorted((int(a),int(b))for(a,b)inR)ans=0t=R[0]# tailforrinR[1:]:(a,b)=t(c,d)=rifa<=c<=b:# if can merget=(a,max(b,d))# extendelse:# count rangeans+=b-a+1t=r(a,b)=tans+=b-a+1print(ans)
C'était un produit déjà compliqué à l'époque. La migration v2 vers v3 avait été très pénible. Et là on peut constater qu'ils prennent un virage très entreprise donc plus vraiment intéressant pour du selfhosting.
Va falloir que je me trouve un autre object storage …
Difficile de départager ces trois premiers jours en terme de difficulté. On est peut être sur un "hockey stick" et on attend le point d'inflexion, peut être demain.
Ce jour, première partie en one shot, sans passer par l’exemple 😎. Pour la deuxième partie, j'ai un peu ratatouillé sur les conditions d'arrêt de ma fonction récursive 😩 et perdu un peu de temps.
Pour les curieux (ou masochiste), je mets le code dans le commentaire en dessous.
Vous pouvez le fermer en appuyant sur [-] pour éviter le spoil.
Ça, ça veut dire que le navigateur ne fera plus la transformation XSTL lui-même.
Il y a eu un monde dans lequel un producteur de contenus envoyait son contenu sous format XML, peu importe lequel, et une feuille de style XSLT et le navigateur faisait la transformation - et le rendu si possible, c'est-à-dire si la transformation produisait du XHTML.
Mais ça ne veut pas dire que XSLT est déprécié en tant que tel. Tu peux toujours le faire dans une extension pour transformer sur XHTML en un autre XHTML. C'est l'idée ici.
Je mets le code, même si je ne lui trouve rien d'intéressant:
defis_invalid_p1(n):s=str(n)m=len(s)//2returns[:m]==s[m:]defchunk_str(s,l):foriinrange(0,len(s),l):yields[0+i:l+i]defis_invalid_p2(n):s=str(n)l=len(s)forminrange(1,1+(l//2)):if(l%m)==0:# if str can be chunked equallya=chunk_str(s,m)b=chunk_str(s,m)next(b)ifall(u==vfor(u,v)inzip(a,b)):returnTruereturnFalseans1=ans2=0forlineinopen(0).read().split(','):f,t=line.split("-")f=int(f)t=int(t)foriinrange(f,t+1):ifis_invalid_p1(i):ans1+=iifis_invalid_p2(i):ans2+=iprint(ans1,ans2)
(C'est dans ces moments que j'aimerai que linuxfr supporte le details/summary).
Jour que j'ai trouvé plus facile que le précédent, mais plus laborieux.
J'ai blêmi en voyant une énoncée avec des "ranges" car j'ai un très mauvais souvenir d'un problème d'intersection de range ; mais il n'en est rien ici.
J'ai aussi pensé qu'on aurait un problème de passage à l'échelle pour la partie 2 ; mais il n'en est rien non plus.
Je m'étais fait un petit dessin ; ça m'a aidé.
À l'inverse, retourner le cadran pour se retrouver systématiquement sur le cas "sens des aiguilles d'une montre" (="R") m'a paru une gymnastique plus compliquée.
Premier jour facile. J'ai même pas pensé à brut-forcer la partie deux. Si j'avais galéré sur un cas limite, je l'aurai fait. Mais là c'est passé du premier coup.
En réorganisant un peu le code, la solution aux deux parties en 9 lignes :
Le contenu qui reste en haut sur la page d'accueil. Pour moi, ça prend de la place et je l'ai la plupart du temps déjà lu. Je ne sais pas comment ça s'appelle mais dans la CSS, c'est "phare".
[^] # Re: Jour 8
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Beaucoup moins académique que Guillaume, très itératif, les deux parties en 22 lignes:
# Jour 8
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 3 (+1/-0).
J'étais ravi d'ouvrir un problème en 3D, ça fait des jolies illustrations.
J'ai trouvé rapidement l'algo mais j'ai perdu énormément de temps sur:
1/ une mauvaise lecture du calcul qu'il fallait produire pour la première partie ; my bad
2/ le fait qu'il fallait compter comme un connexion le fait de ne rien faire :/
à force de tâtonner, j'ai finit par incrémenter dans tous les cas pour voir et je suis tombé sur la solution ; pas agréable
La deuxième partie après cela était triviale.
[^] # Re: Jour 7
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Exactement
Il propose
all_simple_path(source, destination)et je voulais juste les compter mais du coup, ça explose en combinatoire.Je suis tristement pas très familier de cette technique mais de ma compréhension, un algo récursif avec mise en cache, ça s'en rapproche grandement.
[^] # Re: Jour 7
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Première partie très simple, pour chaque line, à chaque fois qu'on split, incrémenter de 1.
Seconde partie, je n'ai pas vu la technique de programmation dynamique que vous évoqués.
J'ai vu un parcours de graphe.
Par flemme de l'implémenter moi même, j'ai voulu le faire avec une lib. Grosse erreur, elle a tournée pendant des plombes et de retour de promenade, je l'ai killé (heureusement que c'est l'hiver et qu'on chauffe).
J'ai finalement implémenté moi même et ça s'est bien passé. Pour éviter l'explosion combinatoire, j'ai utilisé un cache.
[^] # Re: jour 5
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 4 (+2/-0). Dernière modification le 06 décembre 2025 à 15:58.
Et comme le jour 6 ne m'a pas plu, je me suis vengé avec cette version de la partie 2 du jour 5 en une ligne de 199 caractères :
🏌️
[^] # Re: Jour 6
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Tout pareil.
Je mets le code de la partie 1, c'est le moins laid des deux:
[^] # Re: jour 5
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 4 (+2/-0). Dernière modification le 05 décembre 2025 à 20:56.
Et en 4 lignes en utilisant
reduce:Pour comprendre, l'accumulateur est, à tout moment de la réduction, un tuple[la somme accumulé, le max atteint].
[^] # Re: jour 5
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 3 (+1/-0).
Tu ne crois pas si bien dire.
Les deux parties en 11 linges :
[^] # Re: jour 5
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 3 (+1/-0).
Partie 1:
Partie 2
# jour 5
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0). Dernière modification le 05 décembre 2025 à 09:48.
Pas sur de voir une différence de difficulté entre ces cinq premiers jours.
Aujourd'hui, première partie en oneshot. Par contre j'ai trop ramé pour faire l'algo de fusion des intervalles alors que c'est tout bête au final 😕
Je mets le code dans le commentaire en dessous. Vous pouvez le fermer en appuyant sur [-] pour éviter le spoil.
[^] # Re: Jour 4
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Je te confirme que c'est plus rapide. C'était ma première version, celle avec laquelle j'ai validé les étoiles.
Mais ça ne tient pas en 6 lignes 😄
[^] # Re: Jour 4
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 4 (+2/-0).
Très bon jour.
Première partie en one shot, sans passer par l'exemple ; deuxième partie en 1 essai ; en moins de 10 minutes.
Je suis passé par des sets, très facile à manipuler en python et plutôt efficaces en perf.
Voici le code, un peu refactoré pour tenir en 6 lignes:
Cela prend 16MB de RAM et 0.7s de CPU.
# dommage
Posté par steph1978 . En réponse au lien Minio ferme les portes. Évalué à 3 (+1/-0).
C'était un produit déjà compliqué à l'époque. La migration v2 vers v3 avait été très pénible. Et là on peut constater qu'ils prennent un virage très entreprise donc plus vraiment intéressant pour du selfhosting.
Va falloir que je me trouve un autre object storage …
[^] # Re: Jour 3
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0). Dernière modification le 03 décembre 2025 à 19:26.
C'est normal, parce que l'étape
retirer c2 de cellsest coûteuse car il faut créer une nouvelle structure de données à chaque fois.Alors qu'une boucle (ou de la récursivité) sur une même structure de données, ça ne coûte pas très cher.
[^] # Re: Jour 3
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Voici le code, 11 lignes, refactoré pour traiter les deux parties en une fois:
# Jour 3
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Difficile de départager ces trois premiers jours en terme de difficulté. On est peut être sur un "hockey stick" et on attend le point d'inflexion, peut être demain.
Ce jour, première partie en one shot, sans passer par l’exemple 😎. Pour la deuxième partie, j'ai un peu ratatouillé sur les conditions d'arrêt de ma fonction récursive 😩 et perdu un peu de temps.
Pour les curieux (ou masochiste), je mets le code dans le commentaire en dessous.
Vous pouvez le fermer en appuyant sur
[-]pour éviter le spoil.[^] # Re: XSLT, ça alors
Posté par steph1978 . En réponse au journal Démerdifier le web avec Unmerdify et Offpunk. Évalué à 10 (+8/-0).
Ça, ça veut dire que le navigateur ne fera plus la transformation XSTL lui-même.
Il y a eu un monde dans lequel un producteur de contenus envoyait son contenu sous format XML, peu importe lequel, et une feuille de style XSLT et le navigateur faisait la transformation - et le rendu si possible, c'est-à-dire si la transformation produisait du XHTML.
Mais ça ne veut pas dire que XSLT est déprécié en tant que tel. Tu peux toujours le faire dans une extension pour transformer sur XHTML en un autre XHTML. C'est l'idée ici.
[^] # Re: XSLT, ça alors
Posté par steph1978 . En réponse au journal Démerdifier le web avec Unmerdify et Offpunk. Évalué à 9 (+7/-0). Dernière modification le 02 décembre 2025 à 12:19.
HTML n'ayant pas fondamentalement changé ces dernières années, il y a peu de raison que XSLT ne fonctionne plus.
Ce qui a probablement beaucoup changé, c'est que le DOM est produit par du JavaScript côté client.
Mais si tu es dans un navigateur, il suffit d'attendre qu'il ait exécuté le JS pour travailler sur le DOM résultant.
En fait, le gros intérêt d'utiliser XSLT dans le moteur, c'est de pouvoir utiliser des XPath dans les fichiers de configuration.
[^] # Re: Jour 2
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Je mets le code, même si je ne lui trouve rien d'intéressant:
(C'est dans ces moments que j'aimerai que linuxfr supporte le details/summary).
# Jour 2
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Jour que j'ai trouvé plus facile que le précédent, mais plus laborieux.
J'ai blêmi en voyant une énoncée avec des "ranges" car j'ai un très mauvais souvenir d'un problème d'intersection de range ; mais il n'en est rien ici.
J'ai aussi pensé qu'on aurait un problème de passage à l'échelle pour la partie 2 ; mais il n'en est rien non plus.
Patience, ce sera pour la prochaine :)
[^] # Re: Jour 1
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 2 (+0/-0).
Je m'étais fait un petit dessin ; ça m'a aidé.
À l'inverse, retourner le cadran pour se retrouver systématiquement sur le cas "sens des aiguilles d'une montre" (="R") m'a paru une gymnastique plus compliquée.
[^] # Re: démerdifier linuxfr??
Posté par steph1978 . En réponse au journal Démerdifier le web avec Unmerdify et Offpunk. Évalué à 5 (+3/-0).
Exact mais je ne visite pas toujours en mode connecté. En particulier au boulot. Alors que j'ai toujours ublock 😉
[^] # Re: Jour 1
Posté par steph1978 . En réponse au journal Advent of Code 2025. Évalué à 3 (+1/-0).
o/
Premier jour facile. J'ai même pas pensé à brut-forcer la partie deux. Si j'avais galéré sur un cas limite, je l'aurai fait. Mais là c'est passé du premier coup.
En réorganisant un peu le code, la solution aux deux parties en 9 lignes :
[^] # Re: démerdifier linuxfr??
Posté par steph1978 . En réponse au journal Démerdifier le web avec Unmerdify et Offpunk. Évalué à 4 (+2/-0).
Le contenu qui reste en haut sur la page d'accueil. Pour moi, ça prend de la place et je l'ai la plupart du temps déjà lu. Je ne sais pas comment ça s'appelle mais dans la CSS, c'est "phare".
[^] # Re: démerdifier linuxfr??
Posté par steph1978 . En réponse au journal Démerdifier le web avec Unmerdify et Offpunk. Évalué à 4 (+2/-0).
Pour ma part, j'utilise ublock0 pour supprimer le "phare" et les avatars.