C'est un problème qui peut se faire un parcours en longueur ou largeur.
Problème: selon la direction du faisceau, les cases à visiter suivantes peuvent être différentes.
Du coup un sommet du graphe que l'on veut parcourir ne sera pas seulement une position dans la grille mais un couple (position, direction).
Je commence par importer mes fonctions nécessaires et définir les types utilisés dans le problème.
Les positions et directions sont des vecteurs de dimension 2.
J'appelerai le couple (Position, Direction) est un Beam.
Ensuite, vient le parcours en largeur. Je réutilise une fonction reachableFrom définie pour des problèmes précédents.
Elle prend deux arguments
- une fonction qui étant donné renvoit la liste des sommets voisins
- un sommet de départ
et renvoit l'ensemble des sommets accessibles depuis le sommet de départ.
Pour utiliser reachableFrom, je dois calculer, étant donné un beam, les beams suivants.
Je le fais en deux temps en définissant d'abord une fonction nextDirections qui étant donné une direction et une tuile me renvoit les directions suivantes.
Je peux maintenant définir ma fonction energized qui me renvoit le nombre de tuiles énergisées en utilisant les fonctions reachableFrom et neighbors définis plus haut.
Pour la partie 2, c'est du brute-force sur toutes les positions de départ possibles, j'ai pas trouvé mieux.
Ca se parallélise bien, j'utilise parMap qui est une version parallèle de map.
1400ms sur un seul core et 800ms en multicore pour la partie 2. Pas terrible le parallélisme, j'aurais espéré mieux. Je ne me suis peut-être pas pris comme il fallait.
# Solution en Haskell
Posté par Guillaume.B . En réponse au message Advent of Code, jour 16. Évalué à 2. Dernière modification le 16 décembre 2023 à 17:31.
C'est un problème qui peut se faire un parcours en longueur ou largeur.
Problème: selon la direction du faisceau, les cases à visiter suivantes peuvent être différentes.
Du coup un sommet du graphe que l'on veut parcourir ne sera pas seulement une position dans la grille mais un couple (position, direction).
Je commence par importer mes fonctions nécessaires et définir les types utilisés dans le problème.
Les positions et directions sont des vecteurs de dimension 2.
J'appelerai le couple (Position, Direction) est un
Beam.Ensuite, le parsing, rien de bien intéressant
Ensuite, vient le parcours en largeur. Je réutilise une fonction
reachableFromdéfinie pour des problèmes précédents.Elle prend deux arguments
- une fonction qui étant donné renvoit la liste des sommets voisins
- un sommet de départ
et renvoit l'ensemble des sommets accessibles depuis le sommet de départ.
Pour utiliser
reachableFrom, je dois calculer, étant donné un beam, les beams suivants.Je le fais en deux temps en définissant d'abord une fonction
nextDirectionsqui étant donné une direction et une tuile me renvoit les directions suivantes.A partir de ça, je peux définir ma fonction
neighborsnécessaire à `reachableFromJe peux maintenant définir ma fonction
energizedqui me renvoit le nombre de tuiles énergisées en utilisant les fonctionsreachableFrometneighborsdéfinis plus haut.Pour la partie 2, c'est du brute-force sur toutes les positions de départ possibles, j'ai pas trouvé mieux.
Ca se parallélise bien, j'utilise
parMapqui est une version parallèle demap.1400ms sur un seul core et 800ms en multicore pour la partie 2. Pas terrible le parallélisme, j'aurais espéré mieux. Je ne me suis peut-être pas pris comme il fallait.