Added article AoC2021-Day1
Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
parent
0e49ead29a
commit
2bc3878090
111
src/aoc-2021-jour-1-sonar-sweep.md
Normal file
111
src/aoc-2021-jour-1-sonar-sweep.md
Normal file
@ -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<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 :
|
||||
|
||||
- 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>) -> 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<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](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::<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 é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
|
||||
|
Loading…
Reference in New Issue
Block a user