Advent of Code - dia 1
Ja tenim el primer problema de'Advent of Code 2022, espero que
l'hageu resolt (sinó no, no mireu aquest document: encara teniu temps de fer-lo!).
Per si ja l'heu fet us explico una forma elegant de fer-lo amb Kotlin amb una mica de programació funcional.
Part 1
En la primera part hem de calcular la suma total de calories de l'elf que porta més calories.
Lectura fitxer
Per llegir el fitxer, creem un Path i carreguem tot el contingut a una variable String (input) amb readText(). En aquesta explicació faré servir les dades de l'exemple de l'enunciat.
val input = Path.of("src/main/resources/day1.input").readText()
1000\n2000\n3000\n\n4000\n\n5000\n6000\n\n7000\n8000\n9000\n\n10000 |
Llista d'elfs
El següent pas serà convertir l'String en una llista, on cada cel·la tindrà la informació de cada elf.
El doble salt de línia ("\n\n") ens serveix de separador entre els diferents elfs i la funció split crea una llista d'un String utilitzant un separador:
1000
2000
3000 |
4000 |
5000
6000 |
7000
8000
9000 |
10000 |
Matriu d'elfs
Ara volem convertir la llista d'strings en una llista de llistes on cada fila serà un elf, i cada cel·la un String amb les calories d'un aliment.
Per cada un dels elfs (cel·les) podem crear una llista d'aliments amb la funció lines().
Això ho hem de fer per cada un dels elfs: hem de transformar cada cel·la en una llista. Farem servir la funció map() que transforma cada element
amb l'acció que li passem per paràmetre.
input.split("\n\n").map{it.lines()}
Llista de calories
Ara volem tenir per cada elf la suma de les seves calories. Per cada elf tenim una llista de strings,
que podem sumar amb la funció sumOf, indicant-li com sumem els String.
Per sumar un String, només l'hem de convertir a int amb toInt().
Ja tenim una llista de enters on cada cel·la és la suma total de les calories que porta cada elf.
val elves = input.split("\n\n").map{it.lines().sumOf { it.toInt() }}
6000 |
4000 |
11000 |
24000 |
10000 |
Resultat
Ara només ens queda obtenir el màxim dels enters que tenim. La funció max ens serà d'ajuda
El resultat és 72478, que és el que indica l'enunciat. Ho enviem i ja tenim una estrella!
Part 2
En la segona part necessitem obtenir els tres elfs amb més calories totals i sumar-los.
A l'apartat anterior ja tenim una llista amb els totals de caloríes de cada elf.
Necessitem:
- Ordenar-los: sortedDescending() ens ordena la llista començant pel més gran
- Agafar els tres primers: take(3) afaga els 3 primes elements
- Sumar-los: sum() suma la llista de tres enters que ens queda
24000 |
11000 |
10000 |
6000 |
4000 |
elves.sortedDescending().take(3)
elves.sortedDescending().take(3).sum()
El resultat és 210367, que és el que indica l'enunciat. Ho enviem i ja tenim dues estrelles!