Calendrier de l'avent 🎄 (mais sans chocolats)

ha ok, du coup c’est pas que cosmetique ! merci pour l’info !

pour rire:

import re

def day4_1(keys,data):

    passportKey = [ d.split(":")[0] for d in data]
    list1_as_set = set(keys)
    intersection = list1_as_set.intersection(passportKey)
    intersection_as_list = list(intersection)

    return len(intersection_as_list)

if __name__ == '__main__':
   fichier = open('input.txt', 'r')
   linesDeMonFichier = fichier.read()

   keys = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']
   data = [  day4_1(keys ,re.split('\n| ', d)) for d in linesDeMonFichier.split('\n\n')]
   print(data.count(len(keys)))

CleanShot 2020-12-04 at 12.32.02@2x

:scream:

hop, l’etoile 2 :

Jour 4 - Etoile 2 (Python)
import re

MANDATORY = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
RANGE_VALIDATOR = {"byr":(".*byr:(\d+).*", 1920, 2002), "iyr":(".*iyr:(\d+).*", 2010, 2020), "eyr":(".*eyr:(\d+).*", 2020, 2030), "hgtcm":(".*hgt:(\d+)cm.*", 150, 193), "hgtin":(".*hgt:(\d+)in.*", 59, 76)}
REG_VALIDATOR = {"hcl":".*hcl:#(([0-9]|[a-f]){6}).*", "ecl":".*ecl:(amb|blu|brn|gry|grn|hzl|oth).*", "pid":".*pid:(\d+).*"}

def isValide(password):
    for check in MANDATORY:
        if password.get(check) != "Valide":
            print("Passpord INVALIDE - missing {0}: {1}".format(check, password))
            return(False)
    print("Passpord VALIDE {0}".format(password))
    return(True)

f = open("Z:\donnees\developpement\Python\AdventOfCode\day4.txt", "r")
validePassport = 0

currentPassword = {}
for line in f:
    if line == "\n":
        #Changing password - validate current one
        if isValide(currentPassword):
            validePassport += 1
        currentPassword = {}
    else:
        #looking for fields
        for key, value in RANGE_VALIDATOR.items():
            result = re.match(value[0], line)
            if result:
                digit = int(result.group(1))
                if value[1] <= digit <= value[2]:
                    currentPassword[key[0:3]] = "Valide"

        for key, value in REG_VALIDATOR.items():
            result = re.match(value, line)
            if result:
                if key == "pid":
                    if len(result.group(1)) == 9:
                        currentPassword[key] = "Valide"
                else:
                    currentPassword[key] = "Valide"

#validating last password:
if isValide(currentPassword):
    validePassport += 1
f.close()
print("Star 1 : Nombre de valide: %d"%validePassport)

J’ai rĂ©ussi a grouper un peu les types de validation :slight_smile:
Sinon pour ma culture, je n’ai pas trouvĂ© de regexp pour valider exactement 9 digits. Ca match toujours avec 9+, ou ca ne match plus quand il n’y a rien derriĂšre 

Du coup j’ai du rajoutĂ© une exception pour pid pour verifier que ca fait bien pile 9 digit.

Y’en a qui on trouvĂ© une regexp qui fait ca ?

/[0-9]{9}/

Non ca marche pas. Ca ne fonctionne que si ta chaine est seul. /[0-9]{9}/ ne va pas matché si ton expression est au millieu de ta chaine :

iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm

J’ai pas trouvĂ© d’autre moyen que ".*pid:(\d+).*", et verifier ensuite qu’on a que 9 digits (et pas 10 ou 8)

Avec la partie 2 (toujours pour rire et avec des comprehention pour @anon10092024 :stuck_out_tongue_winking_eye: ):

Résumé
# main
import itertools
import re

def byr(value):
    return 1920 <= int(value) <= 2002

def iyr(value):
    return 2010 <= int(value) <= 2020

def eyr(value):
    return 2020 <= int(value) <= 2030

def hgt(value):
    if value.endswith("cm"):
        return 150 <= int(value[0:-2]) <= 193
    else:
        if value.endswith("in"):
            return 59 <= int(value[0:-2]) <= 76
        else:
            return False

def hcl(value):
    return re.search(r'^#(?:[0-9a-fA-F]{6})$', value) is not None

def ecl(value):
    e = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']
    return value  in e

def pid(value):
    return re.search(r'^(?:[0-9]{9})$', value) is not None

def cid(value):
    pass

def day4_2(keys,data):
    passport = [globals()[d.split(":")[0]](d.split(":")[1]) for d in data]

    return passport.count(True)

def day4_1(keys,data):
    passportKey = [ d.split(":")[0] for d in data]
    list1_as_set = set(keys)
    intersection = list1_as_set.intersection(passportKey)
    intersection_as_list = list(intersection)

    return len(intersection_as_list)


if __name__ == '__main__':
   fichier = open('input.txt', 'r')
   linesDeMonFichier = fichier.read()

   keys = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']
   data = [  day4_2(keys ,re.split('\n| ', d)) for d in linesDeMonFichier.split('\n\n')]
   print(data.count(7))
3 « J'aime »

Je me suis fait un peu plaisir avec une validation des champs un peu générique :slight_smile:

/^[\d]{9}$/

commence (^) par 9 digits et doit se terminer ($)

Non plus : ca marche que si tu as déjà isolé ta chaine. Moi je veux le faire en une seule passe, au milieu de la ligne globale.
Il faut que ca matche ca :

iyr:2010 hgt:158cm hcl:#b6652a pid:120931547 ecl:blu byr:1944 eyr:2021

mais pas ca :

iyr:2010 hgt:158cm hcl:#b6652a pid:1209315475 ecl:blu byr:1944 eyr:2021


  1. \d ↩

Essaye de matcher (se termine ou il y a un espace aprĂšs)

amuse toi avec https://www.geekzone.fr/2019/04/18/wildgem-un-outil-de-recherche-et-remplacement-gratuit-pour-windows/

^^

j’utilise https://pythex.org/, ca marche bien :slight_smile:

Mais je suis pas sur que ce soit possible en une seule passe. Je vois pas comment coder « 9 digits et peut etre quelque chose apres tant que c’est pas un digit » :slight_smile:

Et ça ? ^.*pid:(\d{9})\D.*$

edit : petite amélioration :slight_smile:

Nope :slight_smile:

Ca match ca (ce qui est bien): iyr:2010 hgt:158cm hcl:#b6652a pid:120931547 ecl:blu byr:1944 eyr:2021
Ca matche pas ca (ce qui est bien): iyr:2010 hgt:158cm hcl:#b6652a pid:1209315475 ecl:blu byr:1944 eyr:2021
Ca matche pas ca (ce qui est PAS bien :slight_smile: ): iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:120931547

J’ai fais les memes essaie :slight_smile: Dans le 3eme cas, si le pid est en derniùre position avec rien derriùre, ca ne match pas 

La difficultĂ©, c’est le « il faut pas qu’il y ait de 10eme digit, mais rien derriĂšre, ca va »
Pas evident :slight_smile:

Le topic a été renommé Advent of Regex

1 « J'aime »

/\s?pid:(\d{9})[\R\s]/g

alors on avance :slight_smile: ^.*pid:(\d{9})(?:\D|$).*$

edit : non capturing group

@Donjohn : toujours pas :slight_smile: Dans ton 3eme exemple, il y a un espace à la fin, si tu l’enleves, ca ne marche plus :

Il est plus pratique ce site, merci pour le lien :slight_smile:

alors alors elle fonctionne ma regex :arrow_up: ?