Idem ici en Python, jâutilise un environnement de base sans libs supplĂ©mentaires
Bon clairement ce matin jâai dĂ» me mettre Ă faire des regex (jâaime pas ça
). 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).
Meme pas « re » ? ![]()
(Jâai pas encore lu le puzzle
)
En php, on considĂšre ça plus comme une extension quâune lib externe
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 ![]()
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 ![]()
(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
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
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 
Sympa, ça reste concis en effet ![]()
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Ă ![]()
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
}
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 
Je voulais eviter le switch sur les critĂšres, mais ca va aller plus vite je crois 
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 
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
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 
Perso je trouve ça toujours plus lisible ![]()
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
Mais je concois que dâautres puissent prĂ©fĂ©rer 
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 
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++;
}