AoC 2021 Jour 1: Sonar Sweep

À la recherche de la clef du traîneau à l’aide d’un sonar.

Le défi peut être trouvé ici, et le code lié est sur gitlab.

Consigne du défi

Le premier puzzle est assez simple, et peut se résumer en “compter les variations dans un fichier d’entrée”.

Lecture du fichier d’entrée

Pour lire le fichier, rien de plus simple. L’entrée étant une simple liste d’entiers séparés par des retours à la ligne, il est assez facile de le transformer en tableau d’entiers.

En code, cela se traduit par :

fn parse_input(s: &str) -> Vec<i32> {
    return s.split("\n").into_iter().filter_map(|f| f.parse::<i32>().ok()).collect::<Vec<i32>>();
}

Maintenant que j’ai acquis un peu plus d’expérience en Rust, je le ferais d’une manière assez différente :

Première partie

La première partie nécessite de compter les augmentations de nombres un-à-un.

Nous avons donc un tableau (vecteur) d’entiers, alors il suffira simplement de le parcourir, et si l’entier actuel est plus grand que le précédent, alors on retient qu’on a vu une augmentation supplémentaire.

Le code de cette partie est le suivant :

fn get_increase_nb(e: &Vec<i32>) -> i32 {
    let mut n = 0;
    for i in 1..e.len() {
        n += if e[i] > e[i - 1] { 1 } else { 0 };
    }
    return n;
}

On a donc un entier n qui va retenir le nombre d’augmentations observées, et pour tous les entiers du tableau, de la case 1 (les tableaux en informatique débutent à la case 0), à la case taille (non incluse, toujours parce que les tableaux commencent à 0). Si le nombre actuel est plus grand que le précédent, alors n augmente de 1.

Deuxième partie

Pour cette deuxième partie, le concept est le même mais cette fois on prend les entiers d’entrée par groupe de 3 et on compte les augmentations entre chaque sommes d’entiers.

On transforme donc le tableau d’entiers en un second tableau correspondant aux sommes de 3 entiers selon une fenêtre flottante.

fn get_sums(v: &Vec<i32>) -> BTreeMap<usize, i32> {
    let mut sums = BTreeMap::new();
    for i in 0..(v.len() - 2) {
        sums.insert(i, v[i] + v[i + 1] + v[i + 2]);
    }
    return sums;
}

Ici, une BTreeMap est totalement inutile. Je ne sais pas trop pourquoi j’ai choisi ce type de structure de données. Surtout qu’après, cette Map est convertie en simple tableau en ignorant totalement la clef :

let map = get_sums(&vec_in).iter().map(|e| e.1.to_owned()).collect::<Vec<i32>>();

Ici il serait beaucoup plus intéressant d’utiliser un simple tableau, et à chaque nouvelle somme on peut l’envoyer sur le dessus du tableau (de sommes) d’entiers.

Ce tableau enfin obtenu sera alors envoyé à la même méthode que pour la partie une pour en obtenir le nombre d’augmentations.

Évidemment il serait aussi possible de simplement compter les augmentations en même temps que l’on parcourt les tableaux, pour éviter de multiples passages.

Conclusion

Ce puzzle était loin d’être compliqué. J’ai passé un peu de temps sur la compréhension du système de sommes de la partie 2, ne sachant que faire dans le cas où il n’y avait plus assez d’entiers pour faire une somme.

Après un peu de temps et d’essais, j’ai pu m’en sortir sans difficulté.

Concernant la qualité du code, je me demande bien ce que j’ai pu penser sur le moment pour choisir de stocker les sommes dans une map à arbre binaire…

À suivre