Calendrier de l'avent 🎄 (mais sans chocolats)

Faut que je rattrape mes jours.

part 1 en php, plutĂŽt simple
$timestart = microtime(true);
$lignes = file("input5");
if ($lignes === false) die("erreur de lecture");
$boarding_passes = array();

for ($i=0; $i<count($lignes); $i++)
{
	$ligne = trim($lignes[$i]);
	
	//row
	$idmin = 0;
	$idmax = 127;
	for ($j=0; $j<7; $j++)
	{
		if (strtoupper($ligne[$j] == 'F')) $idmax -= ceil(($idmax - $idmin)/2);
		else $idmin += 1+floor(($idmax - $idmin)/2);
	}
	
	//column
	$jdmin = 0;
	$jdmax = 7;
	for (1; $j<10; $j++)
	{
		if (strtoupper($ligne[$j] == 'L')) $jdmax -= ceil(($jdmax - $jdmin)/2);
		else $jdmin += 1+floor(($jdmax - $jdmin)/2);

	}

	array_push($boarding_passes, 8* $idmin + $jdmin);
}

echo "max: " . max($boarding_passes);
$timeend = microtime(true);
echo "<hr>temps : " . number_format($timeend-$timestart, 4);

J’essaie de rattraper mon retard. ^^

Jour6 en JS
let convertedData = data
// concat all group of rows separated by an empty string ''
.reduce((acc,d) => {
    if (d === ''){
        return [...acc,d]
    } else {
        let clone = [...acc]
        let last = clone.pop()
        return [...clone,last.concat(d).concat(' ')]
    }    
},[''])
// separe all pair entry/value separated by a ' '
.map(d => d.split(' ').slice(0,-1))
// convert all strings to arrays
.map(d => d.map(answers => answers.split('')))


let result1 = convertedData
// concat answers and use Set to remove duplicate, it gets all answers for each group
.map(d => d
    .reduce((acc,answers) => [...new Set([...acc, ...answers])] , []))
// convert list of answers to number of answers
.map(d => d.length)
// add all those numbers to get final result
.reduce((acc,d) => acc+d,0)


let result2 = convertedData
// intersect arrays using a combination of filter and includes
.map(d => d
    .reduce((acc,answers, i, arr) => i===0 ? arr[0] : acc.filter(accElem => answers.includes(accElem)), []))
// convert list of answers to number of answers
.map(d => d.length)
// add all those numbers to get final result
.reduce((acc,d) => acc+d,0)

console.log(result1)
console.log(result2)

on ne juge pas :sweat_smile: je suis partie n’importe oĂč.

Résumé

def day7_1(data,tag,taboo):
    bags = 0
    exploration = []
    for d in data:
        if d['bag'] not in taboo and tag in [b[1] for b in d['contain']]:
            bags+=1
            taboo.append(d['bag'])
            exploration.append(d['bag'])

    for b in exploration:
        bags += day7_1(data, b, taboo)
    return bags


def day7_2(data,tag):
    cpt = 0
    for b in [d["contain"] for d in data if d["bag"]==tag][0]:
        print(b)
        cpt += b[0] * (1 + day7_2(data,b[1]))

    return cpt

if __name__ == "__main__":
    fichier = open('input.txt', 'r')
    linesDeMonFichier = fichier.readlines()
    data = [ {'bag':d.strip().split("contain")[0].split(" bags")[0],'contain':[ [int(b[0]),b.split(" bag")[0][2:]] for b in d.strip().split("contain ")[1].split(", ") if d.strip().split("contain ")[1] != "no other bags."]}  for d in linesDeMonFichier ]
    print(day7_1(data,'shiny gold',[]))
    print(day7_2(data,'shiny gold'))

En retard mais bon je fais ce que je peux

Day 5 part 1 PHP
         foreach ($lines as $line) {

            $startingRow = 0;
            $endingRow = 127;
            $nbRow = 128;
            $startingColumn = 0;
            $endingColumn = 7;
            $nbColumn = 8;

            $i = 0;
            while ($i < 7) {
                $nbRow /= 2;
                if ($line[$i] === 'B')
                {
                    $startingRow += $nbRow;
                } elseif ($line[$i] === 'F'){
                    $endingRow -= $nbRow;
                }
                $i++;
            }
            $row = $startingRow < $endingRow ? $startingRow : $endingRow;

            while ($i < 10) {
                $nbColumn /= 2;
                if ($line[$i] === 'R')
                {
                    $startingColumn += $nbColumn;
                } elseif ($line[$i] === 'L'){
                    $endingColumn *= $nbColumn;
                }
                $i++;
            }

            $column = $startingColumn < $endingColumn ? $startingColumn : $endingColumn;

            $calc = $row*8 + $column;
            $value = $calc > $value ? $calc : $value;
        }
        $output->writeln($value);
1 « J'aime »

Hop et voilĂ , j’ai un peu galĂ©rĂ© bĂȘtement sur la rĂ©cursion dans la partie 2 (on multiplie, on additionne, on fait les deux ?)

Part1 / Part2

Sinon je commence à utiliser de plus en plus de doctests, des sortes de commentaires exécutables qui font office de tests unitaires.

Par exemple ici pour parser une ligne de l'input
@doc ~S"""
iex> import Advent.Y2020.Day07.Part1
iex> parse_rule("plaid brown bags contain 3 bright lime bags, 5 plaid coral bags.")
{"plaid brown", [{3, "bright lime"}, {5, "plaid coral"}]}
iex> parse_rule("plaid brown bags contain 1 bright lime bag, 1 plaid coral bag.")
{"plaid brown", [{1, "bright lime"}, {1, "plaid coral"}]}
iex> parse_rule("plaid brown bags contain no other bags.")
{"plaid brown", []}
"""
def parse_rule(rule) do
  [key, tail] = String.split(rule, " bags contain ")

  values =
    tail
    |> String.split([", ", ".", " bags", "bag"])
    |> Enum.reject(&(&1 == "" || &1 == "no other"))
    |> Enum.map(fn count_and_color ->
      [count, color] = String.split(count_and_color, " ", parts: 2)
      {String.to_integer(count), String.trim(color)}
    end)

  {key, values}
end

Bon j’ai commence aujourd’hui en GoLang (je suis un vrai). Je code a la semi-crade. Pour l’instant j’ai fait 2 jours part1/2, donc j’ai 4 etoiles. Je suis tropfort!!!

Day1
package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() {
    strs := strings.Split(exerciseInput, "\n")
    numbers := make([]int, len(strs))
    for i := range numbers {
        numbers[i], _ = strconv.Atoi(strs[i])
    }
    fmt.Println(numbers)
    for i, v := range numbers {
        for j := i + 1; j < len(numbers); j++ {
            for k := j; k < len(numbers); k++ {
                if k == j || k == i {
                    continue
                }
                if v+numbers[j]+numbers[k] == 2020 {
                    fmt.Println("Found number that add to 2020", v, numbers[j], numbers[k])
                    fmt.Println("Multiplied: ", v*numbers[j]*numbers[k])
                }
            }
        }
    }
}
Day2
package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() {
    strs := strings.Split(exerciseInput, "\n")
    bad := 0
    good := 0

    for _, entry := range strs {
        minCount, _ := strconv.Atoi(strings.Split(strings.Split(entry, ": ")[0], "-")[0])
        maxCount, _ := strconv.Atoi(strings.Split(strings.Split(strings.Split(entry, ": ")[0], "-")[1], " ")[0])
        letter := strings.Split(strings.Split(strings.Split(strings.Split(entry, ": ")[0], "-")[1], " ")[1], ":")[0]
        password := strings.Split(entry, ": ")[1]
        //fmt.Println(minCount, maxCount, letter, password)
        //count := strings.Count(password, letter)
        if (password[minCount-1:minCount] == letter && password[maxCount-1:maxCount] != letter) ||
            (password[minCount-1:minCount] != letter && password[maxCount-1:maxCount] == letter) {
            good++
        } else {
            fmt.Println("Bad password: ", password, "Index1/Index2: ", minCount, maxCount, "Letter: ", letter)
            bad++
        }
    }
    fmt.Println("Good: ", good, "Bad: ", bad)
}
1 « J'aime »

cool un peu de variété au milieu de tous ces pythonistas :slight_smile:
je prendrai surement un peu de temps pour apprendre le Rust sur les premiers puzzles

1 « J'aime »

Pas de spoil pls
 Cachez votre code, on arrive Ă  lire un algo mĂȘme dans un langage inconnu. J’ai demandĂ© plus haut comment faire avec [ details ].
Indiquez bien quel jour/part vous collez comme code, avec le retard de certains (dont moi), on s’y perd un peu ^^

S’il vous plait !

Day 5 part 2 PHP
        $seats = [];
        foreach ($lines as $line) {
            $seats[] = $this->getIdSeat($line);
        }
        sort($seats);

        $allSeats = array_fill($seats[0], count($seats), '');

        $value = current(array_diff(array_keys($allSeats), $seats));

        $output->writeln($value);

(j’ai factorisĂ© part 1)

Day 6 part 1 PHP
        $answers = [];
        $value = 0;
        foreach ($lines as $line) {

            if ($line === '')
            {
                $value+=count($answers);
                //new group
                $answers = [];
            } else {
                $answer = array_flip(str_split($line));

                $answers = array_merge($answers,$answer);
            }

        }

        $value+=count($answers);

        $output->writeln($value);
Day 6 part 2 PHP
        $newGroup = true;
        $value = 0;
        foreach ($lines as $line) {

            if ($line === '')
            {
                $value+=count($answers);
                $newGroup = true;
            } else {
                $answer = array_flip(str_split($line));

                $answers = $newGroup ? $answer : array_intersect_key($answers, $answer);
                $newGroup = false;
            }

        }

        $value+=count($answers);

        $output->writeln($value);

Hahaha cette ligne data =[] de l’enfer :slight_smile:

Ouais
 je sais pas pourquoi, je me suis dis « je vais faire un dict, ca sera plus simple pour la suite Â»â€Š puis apres, la flemme de changer.

Tout petit high jack du thread pour parler d’un autre AoC, mais cette fois-ci pour le cĂŽtĂ© sĂ©curitĂ© du dev et/ou de l’info en gĂ©nĂ©ral !

Sur tryhackme.com vous trouverez dans la mĂȘme veine que advent of code des dĂ©fis journaliers dont le but est de trouver les failles de sĂ©curitĂ©s, ça ce passe ici : https://tryhackme.com/room/adventofcyber2

Dans le mĂȘme esprit, on commence tout doucement avec des choses pour les dĂ©butants, puis ça devient progressivement plus difficile.
Il n’y a vraiment aucun prĂ©requis, et les premiers jours peuvent mĂȘme ĂȘtre considĂ©rĂ©s comme Ă©tant trop facile :wink:

Je pense que ça peut ĂȘtre amusant d’essayer, car pour une fois le but est de casser des implĂ©mentations (trouver les failles).
Si des gens veulent essayer je suis disponible sur discord (@Grey) pour les questions, sinon - et s’il y a du monde d’intĂ©ressĂ© - on ouvrira un thread dĂ©diĂ© :).

:christmas_tree: That’s all! Merry coding and happy hacking! :christmas_tree:

3 « J'aime »

Allez hop, Jour 7 fini. J’ai eu envi de faire un systĂšme d’épuisement de liste pour l’étoile 1, et une bonne vieille rĂ©cursion pour l’étoile 2, histoire de varier les plaisirs :slight_smile:

Sinon, je viens de dĂ©couvrir qu’on peut nommer les groupes dans les regexp. Ca change tout :smiley:

Jour 7 (python)
import re
from collections import defaultdict

FirstLevelRegExp = "(?P<outerBox>.*) bags contain (?P<inside>(\d [a-zA-Z ]* bags?(, |.))+|no other bags.)"
SecondLevelRegExp = "(?P<Nb>\d) (?P<name>[a-zA-Z ]*) bags?"
myBag = "shiny gold"


def star1():
    possibleHolder = set()
    searchedBag = []
    searchedBag.append(myBag)
    while len(searchedBag) > 0:
        bag = searchedBag.pop()
        if bag in BagContainIn:
            possibleHolder.update(BagContainIn[bag])
            searchedBag.extend(BagContainIn[bag])
    print("Star1 : Nb holder = {0}".format(len(possibleHolder)))

def star2(currentBag):
    totalBags = 0
    if currentBag in BagContenersRules:
        innerBags = BagContenersRules[currentBag]
        if len(innerBags) > 0:
            for inBagName, inBagNb in innerBags.items():
                totalBags += inBagNb + inBagNb * star2(inBagName)
            return(totalBags)
        else:
            return(0)

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

BagContenersRules = {}
BagContainIn = defaultdict(lambda: [])
for line in f:
    line = line.rstrip("\n")

    match = re.match(FirstLevelRegExp, line)

    if match:
        outerBoxName = match.group('outerBox')
        insideStr = match.group('inside')

        insideList = {}
        matches = re.finditer(SecondLevelRegExp, insideStr)
        for matchNum, matchval in enumerate(matches, start=1):
            boxName = matchval.group("name")
            nbBox = matchval.group("Nb")
            insideList[boxName] = int(nbBox)
            BagContainIn[boxName].append(outerBoxName)

        BagContenersRules[outerBoxName] = insideList
    else:
        print("Error in parsing of line {0}".format(line))
f.close()

star1()
bagStar2 = star2(myBag)
print("Star2 : {0}".format(bagStar2))

Et le resultat :

Star1 : Nb holder = 254
Star2 : 6006
[Finished in 0.079s]
2 « J'aime »
Day 7 part 1 PHP
public function day7part1(OutputInterface $output)
    {
        $lines = file($this->projectDir.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.__FUNCTION__.'.txt',FILE_IGNORE_NEW_LINES);


        preg_match_all('/([a-z]+\s[a-z]+)\sbags\scontain\s.+(shiny\sgold+)\sbags/m', implode("\n", $lines), $matches);

        $goodBags = $matches[1];
        $value = 0;

        foreach($lines as $line)
        {
            preg_match('/([a-z]+\s[a-z]+)\sbags\scontain\s(.*)/', $line, $bag);
            preg_match_all('/([a-z]+\s[a-z]+)\sbag/', $bag[2], $bags);
            $cargo[$bag[1]] = $bags[1];
        }

        foreach ($cargo as $bag => $bags)
        {
            if (in_array($bag, $goodBags, true))
            {
                $value++;
            } else {
                $value = $this->validBag($bag, $cargo, $goodBags) ? $value+1 : $value;
            }
        }

        $output->writeln($value);
        return $value> 0 ? Command::SUCCESS: Command::FAILURE;
    }

    /**
     * @param string $bag
     * @param array  $cargo
     * @param array  $goodBags
     *
     * @return bool
     */
    private function validBag(string $bag, array $cargo, array $goodBags)
    {
        if (in_array($bag, $goodBags, true)) {
            return true;
        }

        if (isset($cargo[$bag])) {
            foreach($cargo[$bag] as $newBag) {
                if($this->validBag($newBag, $cargo, $goodBags))
                {
                    return true;
                }
            }
        }

        return false;
    }

si t’étais un vrai, t’aurais fait les 24 jours du calendrier en une seule fois :stuck_out_tongue:

Je viens de lire day 7, part 1.
j’ai rigolĂ© en dĂ©couvrant le sujet.

light red bags contain 1 bright white bag, 2 muted yellow bags.
dark orange bags contain 3 bright white bags, 4 muted yellow bags.
bright white bags contain 1 shiny gold bag.
muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
dark olive bags contain 3 faded blue bags, 4 dotted black bags.
vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
faded blue bags contain no other bags.
dotted black bags contain no other bags.

Puis je me suis dis que l’UE en Ă©tait capable, pour les aĂ©roports en 2021, j’ai eu un rictus nerveux.

1 « J'aime »

Jour 7 en JS (vaguement) en fonctionnel, en essayant de commenter mon code pour ceux qui veulent relire.

Jour 7
// Get the direct parents of the given bag according to the list of rules
let bagsContaining = (listRules) => (bagInside) => {
    return listRules
        // get all rules having child equal to the given bag
        .filter(rule => rule.vals.filter(val => val.id === bagInside).length > 0)
        // get all the parents of those rules
        .map(rule => rule.id)        
}

// Get the all ascendants of the given bag according to the list of rules
let bagContainingRec = (listRules) => (bagInside) => {
    // get the parents of the tested bag and return empty list if no parents
    let firstLevel = bagsContaining(listRules)(bagInside);
    if (firstLevel === []) {
        return firstLevel
    } else {
        let parents = firstLevel
            // get all the parents of the direct parents, so we get a list of lists of ansestors
            .map(bag => bagContainingRec(listRules)(bag))
            // remove all the empty lists: there are no ancestors for those parents
            .filter(bags => bags.length >= 0)
            // merge the ancestors alltoghether, merge this to the first level of parent
            .reduce((acc,bags) => [...new Set([...acc, ...bags])] , firstLevel)
        return parents
    }
}

// get the number of bags contained in given bag according to the rules
let numberBagContainedIn = (listRules) => (bag) => {
    let allBagsInside = listRules.filter(rule => rule.id === bag)[0].vals
    // if no bag found inside, return 0
    if (allBagsInside === []){
        return 0
    } else {
        // if bags found inside, do a sum of all the bags multiplied by their quantities 
        // plus all the bags inside those bags recursively
        return allBagsInside.reduce((acc,bagInside) => (
            acc + 
            bagInside.qty + 
            (bagInside.qty * numberBagContainedIn(listRules)(bagInside.id))), 0)
    }
}

let formatedData = data
// split the text to get an array: in index 1 the bag and in index 2 what it contains
.map(d => d.match(/^([a-z]+ [a-z]+) bags contain (.*)\.$/))
.map(d => ({
    id:d[1], 
    vals:(d[2].split(', ')
        .map(val => val.match(/^([0-9]+) ([a-z]+ [a-z]+)/))
        .filter(val => val != null)
        .map(val => ({id:val[2], qty:parseInt(val[1], 10)})))
}))

let result = bagContainingRec(formatedData)('shiny gold').length

console.log(result)

let result2 = numberBagContainedIn(formatedData)('shiny gold')

console.log(result2)

Et finalement, je rattrape mon retard :

Day 7 part 2 PHP
    /**
     * @param OutputInterface $output
     *
     * @return int
     */
    public function day7part2(OutputInterface $output)
    {
        $lines = file($this->projectDir.DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.'day7part1.txt',FILE_IGNORE_NEW_LINES);


        $value = 0;
        $cargo = [];

        foreach($lines as $line)
        {
            preg_match('/(\w+\s\w+)\sbags\scontain\s(.*)/', $line, $bag);
            preg_match_all('/((?P<number>\d+)\s(?P<bag>\w+\s\w+))\sbag/', $bag[2], $bags);
            $cargo[$bag[1]] = array_combine($bags['bag'], $bags['number']);
        }

        foreach ($cargo['shiny gold'] as $bag => $number)
        {
            $value+= $number + ($number*($this->countBag($bag, $cargo)));
        }

        $output->write($value);
        return $value> 0 ? Command::SUCCESS: Command::FAILURE;
    }

    /**
     * @param string $bag
     * @param array  $cargo
     *
     * @return int
     */
    private function countBag(string $bag, array $cargo)
    {
        if (count($cargo[$bag])===0)
        {
            return 0;
        }

        $value = 0;
        foreach($cargo[$bag] as $newBag => $number) {
            $value+= $number + ($number*($this->countBag($newBag, $cargo)));
        }
        return $value;

    }

Code cachĂ©! Mais c’est du Go, y a que les vrais qui peuvent comprendre =)

Allez, je fais le truc en RUST paske NOFEAR:

DAY 3 - PART1
use std::str;
use colored::*;

fn main() {
    
    println!("{}", "ALLEZ, jour 3 en Rust bitches".color("red"));
    let mut line_number  = 0;
    let mut char_index  = 0;

    let inputs: Vec<&str> = EXERCISE_INPUT.split_whitespace().collect::<Vec<&str>>();


    let mut number_of_tree_hit = 0;

    while line_number < inputs.len() {
       let index_in_string = char_index % inputs[line_number].len();
       
       if inputs[line_number].chars().nth(index_in_string).unwrap() == '#' {
            number_of_tree_hit += 1;
       }
        
       line_number += 1;
       char_index  += 3;
    }
    println!("Ouch trees: {}", number_of_tree_hit.to_string().blue());
    
}


const EXERCISE_INPUT : &str = r#"....#............#.###...#.#.#."#
DAY 3 - PART2
use std::str;

fn main() {
    
    println!("{}", "ALLEZ, jour 3 en Rust bitches");

    let inputs: Vec<&str> = EXERCISE_INPUT.split_whitespace().collect::<Vec<&str>>();

    let step_1 = count_tree_hit(1, 1, &inputs);
    let step_2 = count_tree_hit(1, 3, &inputs);
    let step_3 = count_tree_hit(1, 5, &inputs);
    let step_4 = count_tree_hit(1, 7, &inputs);
    let step_5 = count_tree_hit(2, 1, &inputs);

    println!("Ouch trees: {} {} {} {} {}", step_1, step_2, step_3, step_4, step_5);
    println!("Multiplied: {}", step_1* step_2 * step_3 * step_4 * step_5);
}


fn count_tree_hit(line_offset: usize, char_offset: usize, inputs: &Vec<&str>) -> usize {

    let mut line_number  = 0;
    let mut char_index  = 0;
    let mut number_of_tree_hit = 0;
    
    while line_number < inputs.len() {
       let index_in_string = char_index % inputs[line_number].len();
       
       if inputs[line_number].chars().nth(index_in_string).unwrap() == '#' {
            number_of_tree_hit += 1;
       }
        
       line_number += line_offset;
       char_index  += char_offset;
    }
    return number_of_tree_hit;
}

const EXERCISE_INPUT : &str = r#"....#............#.###...#.#.#.

Particulierement elegant en Rust le Day4


DAY 4 - PART 1

fn main() {
    let inputs: Vec<&str> = EXERCISE_INPUT.split("\n\n").collect();

    let output : Vec<bool> = inputs.par_iter().map(|passport_entry| {
        let mut valid : bool = true;
        for s in ["byr","iyr","eyr", "hgt", "hcl", "ecl", "pid"].iter() {
            let found = passport_entry.contains(s);
            valid = valid & found;
        }
        valid 
    }).collect();
    println!("{}", output.iter().filter(|&n| *n == true).count())

}


const EXERCISE_INPUT: &str = r#"eyr:2029 iyr:2013..."#;
1 « J'aime »