Calendrier de l'avent 🎄 (mais sans chocolats)

Idem ici en Python, j’utilise un environnement de base sans libs supplĂ©mentaires :slight_smile: Bon clairement ce matin j’ai dĂ» me mettre Ă  faire des regex (j’aime pas ça :frowning:). On commencerait presque Ă  avoir besoin de tests unitaires vu la validation requise au step 2. Ma solution en Python sur GitHub. J’ai un peu grugĂ© certaines vĂ©rifs (par exemple les annĂ©es ont toujours 4 chiffres, jamais une autre longueur ou des lettres).

1 « J'aime »

Meme pas « re » ? :face_with_monocle:

(J’ai pas encore lu le puzzle :innocent:)

En php, on considùre ça plus comme une extension qu’une lib externe :wink: Non je parle de components complet qui reprennent des patterns.

(si on s’empĂȘche le regex on devient fou ^^)

Moi ca me va, mais je ne suis pas certain que tous les langages se valent d’un point de vue nombre de fonctionnalitĂ©s :slight_smile:

Les gens : La difficulté des problÚmes va augmenter jour aprÚs jour.
Also les gens : Vous devez écrire en assembleur, les yeux bandés :smiley:

3 « J'aime »

(vous m’avez compris
 tsss)

Sinon

Day 4 Part 1 PHP
    $nbValide = 0;
    $pattern = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid'];
    $documentKey = [];

    $isValide = static function($documentKey) use ($pattern, $output)
    {
        return count(array_diff($pattern, $documentKey))=== 0;
    };

    foreach ($lines as $line)
    {
        if ($line === '')
        {
            if ($isValide($documentKey)) {
                $nbValide++;
            }
            $documentKey = [];
        } else {
            preg_match_all('/((?P<key>\w+):(?P<value>[\w\s#]\s?))/', $line, $match);
            foreach ($match['key'] as $key)
            {
                $documentKey[] = $key;
            }
        }

    }

    if ($isValide($documentKey)) {
        $nbValide++;
    }

Voici mon code :slight_smile: Fallait ĂȘtre rigoureux mais niveau algo c’est pas trop compliquĂ©.
Le pattern matching d’Elixir est un rĂ©gal pour ce type de problĂšme

Part1

advent/part1.ex at master · cblavier/advent · GitHub

Part2

advent/part2.ex at master · cblavier/advent · GitHub

Au fait pour ceux qui n’aiment pas les regex (les humains quoi), connaissez vous rubular ?
Des années que je fais mes regex là dedans avant de les mettre dans mon code :slight_smile:

Sympa, ça reste concis en effet :slight_smile:
Et c’est vrais que ça reste facile pour l’instant, je regarde mes solutions de 2018 et c’était dĂ©jĂ  vachement plus prise de tĂȘte Ă  ce stade lĂ  :sweat_smile:

Il y a un paquet d’outils du genre et c’est vrai que c’est bien pratique, pour ma part j’utilise regexr

Ma solution en groovy

Day 4
File f = new File("../../resources/day4Input.txt")
    def lines = f.readLines()

    void phase1(){

        Integer nbOfFieldsInCurrentPassport = 0
        Integer nbOfValidPassports = 0

        lines.forEach(){line ->

            if(line.size() == 0){
                if(nbOfFieldsInCurrentPassport == 7){
                    nbOfValidPassports++
                }
                nbOfFieldsInCurrentPassport = 0
            } else {
                List<String> fields = line.tokenize(' ')
                fields.forEach(){field ->
                    if (!field.contains('cid')){
                        nbOfFieldsInCurrentPassport++
                    }
                }
            }
        }
        println "Phase 1 answer is: " + nbOfValidPassports
    }

    void phase2(){

        Integer nbOfValidFieldsInCurrentPassport = 0
        Integer nbOfValidPassports = 0

        lines.forEach(){line ->

            if(line.size() == 0){
                if(nbOfValidFieldsInCurrentPassport == 7){
                    nbOfValidPassports++
                }
                nbOfValidFieldsInCurrentPassport = 0
            } else {
                List<String> fields = line.tokenize(' ')
                fields.forEach(){field ->

                    if (field.contains('byr')){
                        Integer byr = Integer.valueOf(field.split(':')[1])
                        if ( byr >= 1920 && byr <= 2002){
                            nbOfValidFieldsInCurrentPassport++
                        }
                    }
                    if (field.contains('iyr')){
                        Integer iyr = Integer.valueOf(field.split(':')[1])
                        if ( iyr >= 2010 && iyr <= 2020){
                            nbOfValidFieldsInCurrentPassport++
                        }
                    }
                    if (field.contains('eyr')){
                        Integer eyr = Integer.valueOf(field.split(':')[1])
                        if ( eyr >= 2020 && eyr <= 2030){
                            nbOfValidFieldsInCurrentPassport++
                        }
                    }
                    if (field.contains('hgt')){
                        if (field.endsWith('cm')){
                            Integer hgt = Integer.valueOf((field.split(':')[1]).replace('cm',''))
                            if (hgt >= 150 && hgt <= 193){
                                nbOfValidFieldsInCurrentPassport++
                            }
                        }
                        if (field.endsWith('in')){
                            Integer hgt = Integer.valueOf((field.split(':')[1]).replace('in',''))
                            if (hgt >= 59 && hgt <= 76){
                                nbOfValidFieldsInCurrentPassport++
                            }
                        }
                    }
                    if (field.contains('hcl')){
                        String hcl = field.split(':')[1]
                        if(hcl.matches('^#[a-f|0-9]{6}$')){
                            nbOfValidFieldsInCurrentPassport++
                        }
                    }
                    if (field.contains('ecl')){
                        String ecl = field.split(':')[1]
                        if(ecl.matches('^(amb|blu|brn|gry|grn|hzl|oth)$')){
                            nbOfValidFieldsInCurrentPassport++
                        }
                    }
                    if (field.contains('pid')){
                        String pid = field.split(':')[1]
                        if(pid.matches('^[0-9]{9}$')){
                            nbOfValidFieldsInCurrentPassport++
                        }
                    }
                }
            }
        }
        println "Phase 2 answer is: " + nbOfValidPassports
    }
1 « J'aime »

Pas de regex chez moi. J’aime po !

part 1

$timestart = microtime(true);
$lignes = file("input4");
if ($lignes === false) die("erreur de lecture");
$valid = 0;
$passport = array();

function valider($p, $v)
{
	//valider
	if (count($p) == 8 || (count($p)==7 && !array_key_exists('cid', $p))) $v++;
	return $v;
}

for ($i=0; $i<count($lignes); $i++)
{
	if ($lignes[$i] != "\n" )
	{
		$ligne = explode(" ", $lignes[$i]);
		for ($j=0; $j<count($ligne); $j++)
		{
			$mots = explode(":", $ligne[$j]);
			//affecte en dynamique
			for ($k=0; $k<count($mots); $k = $k+2) $passport[$mots[$k]] = trim($mots[$k+1]);
		}
	}
	else 
	{
		$valid = valider($passport, $valid);
		//raz du passeport	
		$passport = array();	
	}
}
//dernier tableau
$valid = valider($passport, $valid);
echo "valides: $valid";
$timeend = microtime(true);
echo "<hr>temps : " . number_format($timeend-$timestart, 4);

J’ai trichĂ© car je valide pas les noms des champs sauf cid (j’aurais pu facilement, ni la qualitĂ© des valeurs).

Part 1 (Python)
import re
MANDATORY = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]

def isValide(password):
    for check in MANDATORY:
        if password.get(check) != "Valide":
            return(False)
    return(True)


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

currentPassword = {}
for line in f:
    if line == "\n":
        #Changing password - validate current one
        if isValide(currentPassword):
            validePassportStar1 += 1
        currentPassword = {}
    else:
        for check in MANDATORY:
            if check in line:
                currentPassword[check] = "Valide"
#validating last password:
if isValide(currentPassword):
    validePassportStar1 += 1
f.close()
print("Star 1 : Nombre de valide: %d"%validePassportStar1)

Pour la part 2, je cherche un moyen de coder la validation du champs dans la regexp pour tout faire d’un coup, mais c’est chaud :slight_smile:
Je voulais eviter le switch sur les critĂšres, mais ca va aller plus vite je crois :slight_smile:

On a dit qu’on jugeait pas le code donc
 un switch : pourquoi pas.

Par contre, je t’encourage Ă  regarder « list comprĂ©hension » en python :wink:

part2
$timestart = microtime(true);
$lignes = file("input4");
if ($lignes === false) die("erreur de lecture");
$valid = 0;
$passport = array();

function valider($p, $v)
{
	//valider
	if (count($p) == 8 || (count($p)==7 && !array_key_exists('cid', $p))) 
	{
		if ( $p['byr']>=1920 && $p['byr']<=2002)
		{
			if ($p['iyr']>=2010 && $p['iyr']<=2020)
			{	
				if ($p['eyr']>=2020 && $p['eyr']<=2030)
				{	
					$u = substr($p['hgt'], -2);
					$t = substr($p['hgt'], 0, strlen($p['hgt']-2));
					if ( ($u == "cm" && $t>=150 && $t <= 193) || ($u == "in" && $t>=59 &  $t<=76) )
					{
						if (preg_match('/^\#[0-9a-f]{6}/i', $p['hcl']))
						{
							$valid_ecl = [ 'amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'];
							if (in_array($p['ecl'], $valid_ecl))
							{
								if (strlen($p['pid']) == 9)
								{
									$v++;
								}
							}
						}
					}
				}
			}
		}
	}
	return $v;
}

for ($i=0; $i<count($lignes); $i++)
{
	if ($lignes[$i] != "\n" )
	{
		$ligne = explode(" ", $lignes[$i]);
		for ($j=0; $j<count($ligne); $j++)
		{
			$mots = explode(":", $ligne[$j]);
			//affecte en dynamique
			for ($k=0; $k<count($mots); $k = $k+2) $passport[$mots[$k]] = trim($mots[$k+1]);
		}
	}
	else 
	{
		$valid = valider($passport, $valid);
		//raz du passeport	
		$passport = array();	
	}
}
//dernier tableau
$valid = valider($passport, $valid);
echo "valides: $valid";
$timeend = microtime(true);
echo "<hr>temps : " . number_format($timeend-$timestart, 4);

bin si, faut juger le code :slight_smile: c’est meme ca qui est interessant dans le fait de partager. Perso je suis preneur de conseil !
Quand je parle d’un switch, c’est de tester toutes les validateurs 1 par 1, alors que sur l’etoile 1, je l’ai fais avec un tableau de check.
La c’est pas evident d’integrer le critùre de validation dans le tableau de check.

Pour le « list comprĂ©hension », je connais, et je trouve que ca n’a aucun interet : ca rends le code illisible, et ca fait exactement la meme chose.
J’ai jamais trouvĂ© d’argument interessant pour ce format d’ecriture. A moins que ce soit plus efficaces, mais j’ai pas l’impression non ?

Pour la part 2, j’ai commencĂ© Ă  Ă©crire un regex de la mort pour tout faire d’un coup, mais c’est quasi indebuggable (mes yeux vrillent :x) et il y a des conditions qui sont pas facile Ă  transposer en regex.

Je suis reparti sur un truc plus simple, soluce soon.

Ça dĂ©pend : parfois ça reste clair (par exemple en Python, faire list_filtered = [l for l in full_list if valid(l)] je trouve que c’est plus Ă©lĂ©gant que :

list_filtered = []
for l in full_list:
    if valid(l):
        list_filtered.append(l)

Mais c’est vrai que certains poussent le bouchon loin :slight_smile:

Perso je trouve ça toujours plus lisible :wink:
Pour la performance, en fonction des opĂ©rateurs, c’est beaucoup plus rapide (append par exemple)

Tu veux dire que certains operateurs sont plus rapides que d’autres non ?
Parce que si j’ai bien compris, le liste comprehension, c’est juste une autre forme d’ecriture. Si tu utilises les memes operateurs en liste comprehension et en bloc indentĂ© standard, c’est exactement les memes performances non ?
Perso, je deteste le liste comprehension, je trouve que ca rends le code illisible. Quand je vois une boucle for, je la comprends tout de suite. Quand je tombe sur une liste comprehension, il me faut toujours 10secondes pour comprendre ce qu’elle fait :slight_smile: Mais je concois que d’autres puissent prĂ©fĂ©rer :slight_smile:

J’aime bien certaines features de python, comme l’extraction de sous liste avec [:], c’est cool et c’est vachement efficaces. Mais liste comprehension, je trouve ca bof :slight_smile:

Justement non, quand tu utilises une « comprehention Â», l’ajout n’utilise pas append (qui est une mĂ©thode avec attribut et tout ce qui va avec) mais un bytecode LIST_APPEND dĂ©diĂ© pour un ajout plus rapide Ă  la liste rĂ©sultats (si je dis pas de bĂȘtise).

Day 4 part 2 en php
    $nbValide = 0;
    $pattern = [
        'byr' => static function ($value) {
            return (int) $value >= 1920 && (int) $value <= 2002;
        },
        'iyr' => static function($value) {
            return (int) $value >= 2010 && (int) $value <= 2020;
        },
        'eyr' =>  static function($value) {
            return (int) $value >= 2020 && (int) $value <= 2030;
        },
        'hgt' => static function($value) {
            return preg_match_all('/^(\d{2,3})(cm|in)$/', $value, $matches ) &&
                (
                    ($matches[2][0]==='cm' && $matches[1][0]>=150 && $matches[1][0]<=193) ||
                    ($matches[2][0]==='in' && $matches[1][0]>=59 && $matches[1][0]<=76)
                );
        },
        'hcl' => static function($value) {
            return preg_match('/^#[0-9a-f]{6}$/i', $value);
        },
        'ecl' => static function($value) {
            return preg_match('/^(amb|blu|brn|gry|grn|hzl|oth)$/i', $value);
        },
        'pid' => static function($value) {
            return strlen($value) === 9;
        }
    ];
    $document = [];


    $isValide = static function($document) use ($pattern)
    {
        if (count(array_diff_key($pattern, $document)) !== 0)
        {
            return false;
        }

        foreach ($document as $key => $value)
        {
            if ($key !== 'cid' && !$pattern[$key]($value)) {
                return false;
            }
        }

        return true;
    };

    foreach ($lines as $line)
    {
        if ($line === '')
        {
            if ($isValide($document)) {
                $nbValide++;
            }
            $document = [];
        } else {
            preg_match_all('/((?P<key>\w+):(?P<value>[#\w0-9]+))+/', $line, $match);
            foreach ($match['key'] as $index => $key)
            {
                $document[$key] = $match['value'][$index];
            }
        }

    }

    if ($isValide($document)) {
        $nbValide++;
    }