From 2bc3878090690eed0a5e50b1b890c16fb6c868ee Mon Sep 17 00:00:00 2001 From: Louis Vallat Date: Tue, 18 Jan 2022 12:17:03 +0100 Subject: [PATCH] Added article AoC2021-Day1 Signed-off-by: Louis Vallat --- src/aoc-2021-jour-1-sonar-sweep.md | 111 +++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/aoc-2021-jour-1-sonar-sweep.md diff --git a/src/aoc-2021-jour-1-sonar-sweep.md b/src/aoc-2021-jour-1-sonar-sweep.md new file mode 100644 index 0000000..ace0287 --- /dev/null +++ b/src/aoc-2021-jour-1-sonar-sweep.md @@ -0,0 +1,111 @@ +# 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](https://adventofcode.com/2021/day/1). + +## 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 : + +```rust +fn parse_input(s: &str) -> Vec { + return s.split("\n").into_iter().filter_map(|f| f.parse::().ok()).collect::>(); +} +``` + +Maintenant que j'ai acquis un peu plus d'expérience en Rust, je le ferais d'une +manière assez différente : + +- tout d'abord, `s.split("\n").into_iter()` peut être remplacé par `s.lines()`, +plus robuste et [System Agnostic](https://en.wikipedia.org/wiki/Agnostic_(data)), +les systèmes Windows utilisant une fin de ligne [différente](https://en.wikipedia.org/wiki/Newline#In_programming_languages). +- ensuite, utiliser des `u16`, soit des entiers non signés et encodés sur 16 bits. +Ici utiliser 32 bits signés pour stocker des valeurs relativement faibles (dans ce +jeu de données) et strictement positives n'est pas optimal. + +## 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 : + +```rust +fn get_increase_nb(e: &Vec) -> 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. + +```rust +fn get_sums(v: &Vec) -> BTreeMap { + 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](https://doc.rust-lang.org/std/collections/struct.BTreeMap.html) +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 : + +```rust +let map = get_sums(&vec_in).iter().map(|e| e.1.to_owned()).collect::>(); +``` + +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 étaient loin d'être compliqués. 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 +