guitou a écrit 110 commentaires

  • # Canard decevant

    Posté par  . En réponse à la dépêche Le numéro 8 du Lama déchainé promeut la diversité. Évalué à 1 (+0/-0).

    J'avoue que, moi aussi, j'ai un peu tique a la lecture du dit article, ils nous ont habitue a mieux. Mais il n'en reste pas moins que le sujet aborde est problematique.
    Le systeme anterieur posait probleme, car le cout de la validation excluait de fait toute petite structure du marche, entre le prix, le delai et le fait que le moindre changement de code oblige a repasser par cette etape.
    Le systeme actuel pose aussi probleme, avec l'auto-attestation, c'est carrement la fete a neuneu pour la fraude. Et oui, le LL est malheureusement indirectement en cause (meme si on peut, de fait, ergoter sur la distinction entre LL et open source): ce sera tjs plus facile pour un margoulin de produire une version verolee d'un programme dont il peut aisement obtenir les sources, ou d'y trouver un faille a exploiter, que d'avoir a decompiler de l'assembleur ou dechiffrer des E/S.
    Personnellement, je doute que revenir en arriere ou maintenir le systeme en place soit une bonne idee, mais je n'ai pas d'alternative a proposer.

    ++
    Gi)

  • [^] # Re: Jour 8

    Posté par  . En réponse au journal Advent of Code 2025. Évalué à 2 (+1/-0).

    J'aurai bien traine aussi ce soir pour plier le bouzin, en partie pour cause de boulettes a traquer, puis pour polish ensuite et reiterer sur la partie boulette.
    Au final, rien de bien original (mais promis, j'ai pas copie):

    from __future__ import annotations
    from functools import reduce
    from itertools import combinations, count
    from operator import mul
    from typing import NamedTuple
    
    
    class SpaceCoord(NamedTuple):
        x: int
        y: int
        z: int
    
        def square_distance(self, other: SpaceCoord) -> int:
            return pow(other.x - self.x, 2) + pow(other.y - self.y, 2) + pow(other.z - self.z, 2)
    
        @classmethod
        def from_data(cls, data: str) -> SpaceCoord:
            return cls(*map(int, data.split(',')))
    
    class Junction:
        def __init__(self, data: list[str]) -> None:
            self.boxes = [SpaceCoord.from_data(line) for line in data]
            self.ordered_pairs = sorted(combinations(self.boxes, 2), key=lambda t: t[0].square_distance(t[1]))
    
        def _join(self, steps: int|None = None) -> tuple[list[int],tuple[SpaceCoord,SpaceCoord]]:
            groups: list[list[SpaceCoord]] = []
            length = len(self.boxes)
    
            def in_group(box: SpaceCoord) -> int|None:
                for i, g in enumerate(groups):
                    if box in g:
                        return i
                return None
    
            for i in count():
                b1, b2 = self.ordered_pairs[i]
                g1 = in_group(b1)
                g2 = in_group(b2)
                match g1, g2:
                    case None, None:
                        groups.append([b1, b2])
                    case None, int():
                        groups[g2].append(b1)
                    case int(), None:
                        groups[g1].append(b2)
                    case _:
                        if g2 != g1:
                            groups[g1] += groups[g2]
                            groups.remove(groups[g2])
                if steps and i == steps -1:
                    break
                elif len(groups) == 1 and len(groups[0]) == length:
                    break
            return ([len(g) for g in groups], (b1, b2)) # pyright: ignore[reportPossiblyUnboundVariable]
    
        def join_steps(self, steps: int) -> list[int]:
            return sorted(self._join(steps)[0], reverse=True)
    
        def join_all(self) -> tuple[SpaceCoord,SpaceCoord]:
            return self._join()[1]
    
    def exo1(data: list[str], steps: int) -> int:
        lengths = Junction(data).join_steps(steps)
        return reduce(mul, lengths[:3])
    
    def exo2(data: list[str]) -> int:
        b1, b2 = Junction(data).join_all()
        return b1.x * b2.x

    ++
    Gi)

  • # Jour 7

    Posté par  . En réponse au journal Advent of Code 2025. Évalué à 2 (+1/-0).

    Rien de bien complique ajd, mais j'ai quand meme perdu un peu de temps sur la premiere partie, faute de tenir compte du fait qu'un splitter devait voir passer un beam pour etre active… Ce qui donne

    from typing import Iterable, NamedTuple
    
    
    class Position(NamedTuple):
        x: int
        y: int
    
    
    class Manifolder:
        def __init__(self, data: list[str]) -> None:
            self.grid = data
            self.height = len(self.grid)
            self.width = len(self.grid[0])
    
        def is_divider(self, pos: Position) -> bool:
            return self.grid[pos.y][pos.x] == '^'
    
        def divisions(self) -> Iterable[int]:
            beams = {self.grid[0].index('S')}
            for y in range(2, self.height, 2):
                splitters = [p for p in map(lambda x: Position(x, y), range(self.width)) if self.is_divider(p) and p.x in beams]
                beams |= {p.x-1 for p in splitters}
                beams |= {p.x+1 for p in splitters}
                beams -= {p.x for p in splitters}
                yield len(splitters)
    
        def timelines(self) -> int:
            timelines = { i: int(self.grid[0][i] == 'S') for i in range(self.width)}
            for y in range(2, self.height, 2):
                splitters = [p for p in map(lambda x: Position(x, y), range(self.width)) if self.is_divider(p) and p.x in timelines.keys()]
                for s in splitters:
                    v = timelines[s.x]
                    timelines[s.x] = 0
                    timelines[s.x-1] += v
                    timelines[s.x+1] += v
            return sum(timelines.values())
    
    def exo1(data: list[str]) -> int:
        return sum(Manifolder(data).divisions())
    
    def exo2(data: list[str]) -> int:
        return Manifolder(data).timelines()

    ++
    Gi)

  • [^] # Re: Jour 6

    Posté par  . En réponse au journal Advent of Code 2025. Évalué à 2 (+1/-0).

    Hello.

    Assez d'accord avec les jugements precedents: pas de difficulte ajd, mais une transformation prealable des donnees pour la partie 2 un peu delicate (la seule fonction a ne pas faire 1 ou 2 lignes).

    from __future__ import annotations
    from functools import reduce
    import operator
    import re
    from typing import Iterable
    
    RE_OP = re.compile(r'([+*]) +')
    
    class Operation:
        operations = {
            '+': sum,
            '*': lambda l: reduce(operator.mul, l)
        }
    
        def __init__(self, operator: str, operands: Iterable[int]):
            self.operator = operator
            self.operands = operands
    
        @classmethod
        def from_data_1(cls, data: tuple[str]) -> Operation:
            return cls(data[-1], map(int, data[:-1]))
    
        def operate(self) -> int:
            return self.operations[self.operator](self.operands)
    
    
    def parse_input_1(data: str) -> Iterable[tuple[str]]:
        return zip(*[line.split() for line in data.strip('\n').split('\n')])
    
    def parse_input_2(data: str):
        def to_numbers(lines: list[str]) -> Iterable[int]:
            for i in range(len(lines[0])):
                if n := ''.join([l[i] for l in lines]).replace(' ', ''):
                    yield int(n)
    
        lines = data.strip('\n').split('\n')
        ops = lines[-1]
        lines = lines[:-1]
        for m in RE_OP.finditer(ops):
            yield Operation(m.group(1), to_numbers(list(map(lambda s: s[::-1], map(lambda l: l[m.start():m.end()][::-1], lines)))))
    
    def exo1(data: str) -> int:
        operations = map(Operation.from_data_1, parse_input_1(data))
        return sum(map(lambda o: o.operate(), operations))
    
    def exo2(data: str) -> int:
        operations = parse_input_2(data)
        return sum(map(lambda o: o.operate(), operations))

    ++
    Gi)

  • [^] # Re: jour 5

    Posté par  . En réponse au journal Advent of Code 2025. Évalué à 1 (+0/-0).

    Hello

    Perso, j'ai trouve l'exercice de ce jour presque plus facile que ceux des jours precedents.
    Je me suis bien embourbe un peu a vouloir gerer ca avec des sets, donc le plus long ce fut de kill mon process python pendant que sa conso memoire mettait mon systeme a mal.
    Au final, une solution assez similaire aux deux proposees plus haut a ceci pres que:

    • plus lourd car decompose en fonctions, dont parse_input et is_fresh qui sont lourdingues

    • usage de range plutot que tuple, pas sur que ca fasse une grande difference, si ce n'est que ca deplace la gestion des +1

    • un test un poil plus efficace pour l'exo 2 (a <= c ou t[0] <= r[0] sont inutiles, la liste etant triee :p)

    Ce qui donne:

    def parse_input(data: list[str]) -> tuple[list[range],list[int]]:
        fresh = []
        ingredients = []
        first = True
        for line in data:
            if line:
                if first:
                    low, high = map(int, line.split('-'))
                    fresh.append(range(low, high+1))
                else:
                    ingredients.append(int(line))
            else:
                first = False
        return (fresh, ingredients)
    
    def is_fresh(ingredient: int, known_fresh: list[range]) -> bool:
        for r in known_fresh:
            if ingredient in r:
                return True
        return False
    
    def exo1(data: list[str]) -> int:
        fresh, check = parse_input(data)
        return sum([is_fresh(i, fresh) for i in check])
    
    def exo2(data: list[str]) -> int:
        fresh, _ = parse_input(data)
        fresh.sort(key=lambda r: (r.start, r.stop), reverse=True)
        r = fresh.pop()
        count = 0
        while fresh:
            next_r = fresh.pop()
            if next_r.start > r.stop:
                count += len(r)
                r = next_r
            else:
                r = range(r.start , max([r.stop, next_r.stop]))
        return count + len(r)

    ++
    Gi)

  • [^] # Re: Jour 4

    Posté par  . En réponse au journal Advent of Code 2025. Évalué à 2 (+1/-0).

    Bien traine encore ajd, un peu sur la partie 1 pour cause de boulette tellement plus grosse que moi que j'ai peine a mettre la main dessus, puis sur la partie 2 quand j'ai realise que du bete parcours de tableau, ca peut etre looooooooooooooooong, ce qui m'a valu de tt refacto.

    Au final, mes 2 fonctions:

        def count_reachable_rolls(self) -> int:
            return len(self._reachable_rolls(self.rolls))
    
        def count_removable_rolls(self) -> int:
            rolls = self.rolls.copy()
            while rem := self._reachable_rolls(rolls):
                rolls -= rem
            return len(self.rolls) - len(rolls)

    Et l'integralite ici

  • # version python

    Posté par  . En réponse au message Autre version de python3 dans un virtualenv. Évalué à 4 (+3/-0).

    Pour Ubuntu, je ne connais pas vraiment, mais il y' a apparemment un ppa qui permet de gerer ca simplement.

    Pour Debian, a ma connaissance tu peux utiliser pyenv notamment, ou pour suivre la mode rust uv (au revoir l'enfer des dependances python, bonjour l'enfer des dependances rust :p)

    ++
    Gi)

  • [^] # Re: Jour 3

    Posté par  . En réponse au journal Advent of Code 2025. Évalué à 2 (+1/-0).

    Hello.

    Un peu bataille jour 1, a trop vouloir resoudre mathematiquement pour la partie 2 (alors que mes souvenirs sur le sujet commencent a se faire vieux, comme moi) et j'ai fini par me resoudre au mode bourrin. Un peu traine hier, mais sans difficulte pour autant, et aujourd'hui, en effet rien de complique.
    Ma solution partielle (en python), dans la meme veine que les premieres propositions:

        def joltage(self, batteries: int) -> int:
            s = ''
            idx = 0
            for i in range(batteries - 1, -1, -1):
                subi, nc = max([t for t in enumerate(self.batteries[idx:-i if i else None])], key=lambda t: (t[1], -t[0]))
                s += nc
                idx += subi + 1
            return int(s)

    Et si je puis me permettre un peu d'auto-promotion, la solution complete ici

    ++
    Gi)

  • # Mots croises

    Posté par  . En réponse à la dépêche Le numéro 6 du Lama déchainé recycle, reconditionne et réemploie. Évalué à 3 (+2/-0).

    Hello.

    J'ai bien aime les defs 5, 7, 10, 16 et 18, simples et efficaces.

    J'ai moins aime:
    - 24 j'aurais cherche moins bateau (reputee pour sa beauté?)
    - 14 probablement parce que j'avais oublie que ca avait existe (quitte a faire dans l'informatique, j'aurais plutot mis: fait du liant sur commande)
    - 28V le rapport m'echappe encore

    J'ai appris un mot avec la 13

    Lachez rien!

    ++
    Gi)

  • # Mots croises

    Posté par  . En réponse à la dépêche Le numéro 5 du Lama déchainé crie Non à Google !. Évalué à 1 (+0/-0).

    Un peu depite d'avoir loupe la def originale pour la 24, j'aime bien l'humour grincant… tant pis pour moi.
    Sinon, reste encore une petite coquille: def 13, il manque un T, non?

    ++
    Gi)

  • [^] # Re: Mots croises

    Posté par  . En réponse à la dépêche Un nouveau numéro pour le Lama déchainé et une page d'accueil en anglais. Évalué à 2 (+1/-0).

    Reponse a moi-meme: me suis plante lamentablement, c'est le numero 4 que je visais!

  • # Mots croises

    Posté par  . En réponse à la dépêche Un nouveau numéro pour le Lama déchainé et une page d'accueil en anglais. Évalué à 2 (+1/-0).

    Hello.

    2 erreurs se sont glissees dans la grille:
    - defs 19 et 20: c'aurait du etre une seule et meme def pour une solution en 2 mots
    - defs 16 et 17: coquille, ou modification de la grille en derniere minute et oubli d'adaptation des defs?

    Pour le coup, ca m'a donne un peu de fil a retordre.

    Je critique, je critique… mais j'insiste encore sur le fait que c'est quand meme de la belle ouvrage (autrement dit pour les auteurs, pas de honte a avoir) !

    ++
    Gi)

  • [^] # Re: Grille presque remplie

    Posté par  . En réponse à la dépêche Parution du troisième numéro du Lama déchainé la gazette de l'April. Évalué à 2 (+1/-0).

    En effet ^

  • [^] # Re: Mots croisés

    Posté par  . En réponse à la dépêche Parution du deuxième numéro de la gazette Le Lama déchainé de l'April. Évalué à 2 (+1/-0).

    Faut pas avoir honte: elles sont vraiment pas si pires ces grilles.

    Petite question de curiosite: production personnelle ou collegiale?

  • [^] # Re: Mots croisés

    Posté par  . En réponse à la dépêche Parution du deuxième numéro de la gazette Le Lama déchainé de l'April. Évalué à 1 (+0/-0).

    Pfiou, je peine moi-meme a me relire!

    Le grand classique des mots croises c'est le 27!

  • [^] # Re: Mots croisés

    Posté par  . En réponse à la dépêche Parution du deuxième numéro de la gazette Le Lama déchainé de l'April. Évalué à 3 (+2/-0). Dernière modification le 27 octobre 2025 à 19:32.

    Hello,

    Pour le 7, c'est un grand classique des mots croises, tu risques de le retrouver souvent si tu prends gout au jeu.
    Personnellement, c'est sur le 7 que j'ai peine! Et pourtant, une fois trouve, ca tombe sous le sens (jolie definition, de fait!).
    Et pour le procede douteux, n'est pas Scipion qui veut, d'ailleurs lui-meme pouvait parfois recourir a tel artifice.

    Mon avis personnel: grille moins equilibree que la precedente (plus on voit grand, plus c'est delicat), mais definitions globalement plus travaillees. Ca fait plaisir de voir le progres du Lama dans l'exercice depuis ses debuts.

    ++
    Gi)

  • [^] # Re: definitions

    Posté par  . En réponse à la dépêche Le Lama Déchainé, campagne de l'April 2025. Évalué à 2 (+1/-0).

    En toute sincerite, je la trouve plutot bien cette grille :)

  • # definitions

    Posté par  . En réponse à la dépêche Le Lama Déchainé, campagne de l'April 2025. Évalué à 2 (+1/-0).

    Hello.

    Y'a 2 defs (8 et 12) qui m'ont completement laisse perplexe, meme avec la solution sous les yeux.
    Par contre, mention TB pour la palme… on la lui decernerait.

    ++
    Gi)

  • # Vas-y Raymond, tou ondoules

    Posté par  . En réponse au journal Il est où le lien avec Linux?. Évalué à 2 (+2/-1).

    En guise de vagues, on est proche du tsunami dans le bassin d'Arcachon!

    Mais trèves de billevesées. Si j'ai tout bien lu, les lignes et entre, le consensus semble plutôt s'établir autour du statu quo: les choses sont bien comme elles sont et les vaches seront bien gardées. Ca me va aussi.

    ++
    Gi)

  • # Hello

    Posté par  . En réponse au message Serveurs à donner, sur chambery ou grenoble. Évalué à 1 (+0/-0).

    C'est cornelien. Etant grenoblois, je serais presque tente de me "devouer" pour te debarrasser, mais je redoute tant, le cas echeant, de me retrouver au final avec un gros bouzin qui prend la poussiere inutilement, que je vais passer mon tour.

    Bravo toutefois pour l'initiative.

    ++
    Gi)

  • # overkill

    Posté par  . En réponse au message modifier des fichiers. Évalué à 1.

    Hello,

    Tu peux toujours faire mumuse a installer ansible pour faire usage des commandes dites ad hoc et plus specifiquement module lineinfile dans ton cas, mais t'as aussi vite fait de te familiariser avec grep, sed et plus generalement les regexp

    ++
    Gi)

  • # Hello

    Posté par  . En réponse au message [RESOLU] sqlite3 UPDATE entrée json. Évalué à 2.

    Pas tout a fait au point sur sqlite3 (j'apprends en te lisant que ca supporte le json!),
    mais j'ai comme l'impression que tu as tout betement inverse les ' et les [] dans ta commande.

    ++
    Gi)

  • # http

    Posté par  . En réponse au message Linux embarqué sur NAS DLINK DNS-320L - installations et mises à jour de packages. Évalué à 2. Dernière modification le 12 mars 2025 à 20:30.

    Hello, a tout hasard, au vu de ta commande wget, je suppose que l'option --no-check-certificate implique du https, ce qui entre en contradiction avec la requete en http
    Avec un peu de chance, tu peux donc esperer corriger le pb en supprimant l'option si le site requis ne supporte que http ou en rajoutant un s à (http s ://…) dans le cas contraire

    ++
    Gi)

  • [^] # Re: un buzzer distribyé qui passe par du HTTP(s) ou autre c'est complqué

    Posté par  . En réponse au message Recherche logiciel ou site de buzzers virtuels. Évalué à 2.

    Hello.

    Sauf a etre vraiment ambitieux, on peut se baser sur la reception de la requete buzz sur le serveur, d'autant sur un reseau local ou les latences devraient etre minimes et donc les ecarts negligeables.

    Cependant, si les clients font du poll, pour avoir la dispo du buzzer au debut, la, y'a deja plus de risques d'inegalites (de l'ordre de l'intervalle entre 2 requetes, mais pas plus). Le plus simple reste sans doute de trouver un intervalle de poll acceptable (bien supportable pour le serveur, mais assez court pour la jouabilite), mais on peut aussi gerer ca avec un service cote clients pour etre au plus juste.

    ++
    Gi)

  • [^] # Re: Simple comme bonjour

    Posté par  . En réponse au message Image? . Évalué à 2.

    Hello

    Ah ben si, c'est faux, Kamoulox, c'etait Kad et olivier :p

    ++
    Gi)