Forum Programmation.autre Advent of Code 2023 : Day 1

PostĂ© par . Licence CC By‐SA.
Étiquettes :
2
3
déc.
2023

Le premier d'une série de 25 forums qui proposeront de partager vos solutions pour l'édition 2023 de l'Advent of Code.

Vous pouvez vous inscrire à un leadboard privé que j'ai créé pour LinuxFR : 2423220-c94050af

Jour 1 (résumé) :

Partie 1

Les petits lutins vont vous envoyer voir oĂč la production de neige a des problĂšmes, et utilisent pour cela un trĂ©buchet.

Pour cela, ils ont besoin des valeurs de calibrations écrites dans un document qui a été « amélioré » par un jeune lutin.

Image

Le document se présente ainsi :

1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet

Pour obtenir les valeurs de calibration, il suffit de combiner le premier et le dernier chiffre de chaque ligne pour obtenir un nombre Ă  deux chiffres. Les valeurs qui correspondent Ă  cet exemple sont 12,38,15,77. La solution est la somme de ses chiffres, soit 142.

Partie 2

C'était trop simple, en fait les chiffres écrits en lettre comptent aussi.
Par exemple :

two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen

Donne les valeurs 29,83,13,24,42,14,76, pour une somme de 281.

Image

  • # Premier jour : on n'optimise pas, on fonce dans l'tas !

    PostĂ© par (Mastodon) . ÉvaluĂ© Ă  2.

    Le premier exercice est trivial :

    import sys
    print(sum(
     int(f"{digit[0]}{digit[-1]}")
     for line in sys.stdin
     for digit in [[x for x in line if x in "0123456789"]]
     if digit
    )

    On fait python3 01.py < 01.input ou 01.demo pour les données de test, et hop, résultat en une commande.

    Le second exercice sans optimisation consiste à rechercher les chiffres et les chiffres écrits, ajouter ça dans une liste, et faire pareil :

    import sys
    text = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
    def analyze(line):
     def _iter():
     for n in range(len(line)):
     if line[n] in "0123456789":
     yield line[n]
     continue
     for t in text:
     if line[n:].startswith(t):
     yield str(text.index(t))
     continue
     return _iter()
    print(sum(
     int(f"{digit[0]}{digit[-1]}")
     for line in sys.stdin
     for digit in [list(analyze(line))]
     if digit
    )

    La fonction analyze prend une ligne, la parcours charactÚre par charactÚre, et regarde si c'est un chiffre, ou l'écriture d'un chiffre, et envoie dans l'itérateur.
    Zéro intelligence, zéro optimisation, zéro plantage.
    BientÎt on pourra plus faire comme ça !
    Mais bon, jour 1, on se dérouille les neurones, on reprend le pli des traitements de flux, on essaie déjà de mettre des itérateurs plutÎt que de tout traiter en mémoire, juste pour reprendre les futurs bonnes habitudes...

    • Yth.
  • # Python

    PostĂ© par . ÉvaluĂ© Ă  1.

    Ma solution :

    #!/bin/python3
    replaces = {
     "one":1,
     "two":2,
     "three":3,
     "four":4,
     "five":5,
     "six":6,
     "seven":7,
     "eight":8,
     "nine":9,
    }
    def extract(word):
     fd = 0
     ld = 0
     for l in word:
     n = 0
     if l.isdigit():
     n = int(l)
     if n != 0:
     if fd == 0:
     fd = n
     ld = n
     return fd*10+ld
    def digitalize(word):
     fd = 0
     ld = 0
     for i in range(len(word)):
     n = 0
     if word[i].isdigit():
     n = int(word[i])
     else:
     for k in replaces.keys():
     if word[i:].replace(k,str(replaces[k]))[0].isdigit():
     n = replaces[k]
     break
     if n != 0:
     if fd == 0:
     fd = n
     ld = n
     return fd*10+ld
    def solve1(testinput,testing=False):
     s = 0
     for line in testinput:
     d = extract(line)
     if testing:
     print(line, "=", d)
     s += d
     if testing:
     print(s)
     return s
    def solve2(testinput,testing=False):
     s = 0
     for line in testinput:
     d = digitalize(line)
     if testing:
     print(line, "=", d)
     s += d
     if testing:
     print(s)
     return s
    test1 = """1abc2
    pqr3stu8vwx
    a1b2c3d4e5f
    treb7uchetn"""
    result1 = 142
    test2 = """two1nine
    eightwothree
    abcone2threexyz
    xtwone3four
    4nineeightseven2
    zoneight234
    7pqrstsixtee"""
    result2 = 281
    def solve(short=False):
     print("----Part 1----")
     if short == False:
     if solve1(test1.split("\n"),testing=True) != result1:
     print("Not working.")
     return False
     else :
     print("Maybe working?")
     with open("input.txt",'r') as file:
     lines = file.read().split("\n")
     s1 = solve1(lines)
     print(s1)
     print("----Part 2----")
     if short == False:
     if solve2(test2.split("\n"),testing=True) != result2:
     print("Not working.")
     return False
     else :
     print("Maybe working?")
     with open("input.txt",'r') as file:
     lines = file.read().split("\n")
     s2 = solve2(lines)
     print(s2)
     return s1, s2
    if __name__ == "__main__":
     from sys import argv
     try:
     if argv[1] == "--summary" or argv[1] == "-s":
     solve(short=True)
     except IndexError:
     solve()

    AprÚs quelques essais en remplaçant avant de traiter, je me suis rendu compte que le plus simple était de reprendre intégralement la logique de la partie 1 en vérifiant une chaine plutÎt qu'un nombre.

    Et c'est plutĂŽt propre.

    L'informatique n'est pas une science exacte, on n'est jamais Ă  l'abri d'un succĂšs

    • [^] # Re: Python

      PostĂ© par (site web personnel) . ÉvaluĂ© Ă  4.

      Et pour 0 et zéro ? (Nb : je n'ai pas essayé de faire l'exercice, je regardais juste les 2 réponses fournies ici et leurs différences)

      • [^] # Re: Python

        PostĂ© par (Mastodon) . ÉvaluĂ© Ă  2.

        "zero" n'est pas dans les données, mais l'ajouter chez moi permet d'avoir la correspondance entre les textes et les index de la liste Python qui commence à 0.

        C'est une optimisation facile de lisibilité on va dire.

        Par ailleurs, j'ai codé sans regarder les données justement, donc en fait je ne savais pas que le zéro était inutilisé.
        Dans l'idĂ©e, il aurait pu l'ĂȘtre.

        • Yth.
      • [^] # Re: Python

        PostĂ© par . ÉvaluĂ© Ă  2.

        J'ai vérifié avant et avait fais quelques tests dans la premiÚre partie, il n'y a pas de zéro. Et si c'était le cas, il suffirait d'ajouter une ligne au dictionnaire.

        L'informatique n'est pas une science exacte, on n'est jamais Ă  l'abri d'un succĂšs

Suivre le flux des commentaires

Note : les commentaires appartiennent Ă  celles et ceux qui les ont postĂ©s. Nous n’en sommes pas responsables.