Suite de l'Avent du Code, jour 12.
Le Père Noël cherche à sortir de la gorge de la rivière où il est tombé, avec l'aide de son ami Dijkstra son communicateur-suisse qui a aussi une fonction de cartographie d'altitude.
Suite de l'Avent du Code, jour 12.
Le Père Noël cherche à sortir de la gorge de la rivière où il est tombé, avec l'aide de son ami Dijkstra son communicateur-suisse qui a aussi une fonction de cartographie d'altitude.
# En Python
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 4.
Ma première idée fonctionnait sur l'exemple mais pas sur les données réelles : parcourir récursivement une matrice de proche en proche en évitant simplement les endroits où on est déjà passé, ça atteint vite la limites de longueur de la pile d'appels.
Du coup, j'ai fait du Dijkstra. Enfin quelque chose inspiré de son algorithme en tout cas. Ça pourrait être fait de façon entièrement itérative, mais ça ne valait pas la peine, ça reste raisonnable en récursif.
Une fois qu'on a ça, la deuxième partie du puzzle ne pose pas spécialement de problème. Il y a tout de même deux façons de l'implémenter, une bête et méchante (on prend la première solution et on l'applique plusieurs fois), et une un rien plus futée.
[^] # Re: En Python
Posté par Eric P. . Évalué à 1.
Par rapport a la deuxieme partie, pour moi la version bete et mechante ne marchait pas. Le calcul pour chaque point de depart prenait plusieurs minutes, donc il etait obligatoire de 'cacher' les distances a partir de chaque point.
Excusez l'absence d'accents dans mes commentaires, j'habite en Australie et n'ai pas de clavier francais sous la main.
[^] # Re: En Python
Posté par steph1978 . Évalué à 2.
Dans mon input, tous les b ne sont que dans la deuxième colonne. Et la première colone ne contient que des a. Comme il faut nécessairement passer par un b, je n'ai testé que des départs depuis la première colonne.
# python et lib de graph
Posté par steph1978 . Évalué à 4.
J'ai passé plusieurs heures à ne pas comprendre pourquoi je ne trouvais pas la solution. Et puis j'ai compris ; j'ai loupé une phrase cruciale dans l'énoncée : on a le droit de redescendre, bordel !
J'ai utilise la très précieuse bibliothèque de manipulation de graph en Python, networkx. Mon code ne fait que parser l'input et construire la liste de transitions possibles et présente donc peu d'intérêt. Mais permet au moins de faire une joli nimage du résultat:
Si vous vous baladez sur Reddit, y en a qui ont fait des représentations de ouf.
La seconde partie était triviale dans ces conditions et m'a pris moins de deux minutes.
[^] # Re: python et lib de graph
Posté par Yth (Mastodon) . Évalué à 2.
Ah, classe :)
J'ai rien de joli à montrer ce coup-ci.
Mais bon, journée présentiel au taf hier, trois heures dans la voiture, 4h en réunions, j'ai à peine eu le temps de bricoler une solution, en ayant réfléchi sur le trajet…
J'ai fait un parcours de graphe inventé à la volée : je n'ai jamais été fichu de retenir le moindre des algos de parcours que j'ai pu apprendre, alors je suis condamné à réinventer la roue !
J'ai des cases en entrée, je regarde pour chacune d'elles où elles peuvent aller (haut, bas, gauche, droite, si la différence de hauteur est bonne), et si je n'ai pas déjà été là (donc matrice des cases visitées avec distance au départ dedans).
Je note l'ensemble des cases nouvellement visitées, et j'itère sur cet ensemble.
Donc a priori inutile de stocker le score pour le retrouver et calculer la suite comme dans mon code plus bas : il suffit de compter les étapes.
Instinctivement, je me suis dis que ça pouvait grossir, et donc j'ai décidé de manger le problème par les deux bouts, donc j'explore en montant depuis "S" et en descendant depuis "E".
Je stocke des scores positifs en montant, et négatifs en descendant.
Si je rencontre une case visitée depuis l'autre bout (case négative si je monte ou positive si je descends), j'ai fait la liaison.
En pratique je peux m'arrêter là : si je suis en train de monter c'est étape*2+1, si je suis en train de descendre c'est étape*2+2.
Dans mon code j'additionne les valeurs absolues : la valeur que j'aurais dû mettre dans la case, et celle déjà présente, et j'ai mon résultat.
Pour l'exercice 2, comme je fournis déjà une liste de case par itération, il suffit de mettre comme liste de démarrage tout les "a" et le "S", vraiment rien à coder, la dernière ligne du programme et basta.
Ah, et j'ai aligné, je bosse sur un tableau à une dimension, au lieu d'une matrice.
Et les mouvements possibles ne sont pas (haut, bas, gauche droite) mais (-1, +1, -largeur, +largeur) et un mouvement doit être dans [0, taille[
Allez, trêve de blabla, code !
[^] # Re: python et lib de graph
Posté par Yth (Mastodon) . Évalué à 3.
Pour faire du joli on fait ça :
Et il faut mettre le terminal en grand, parce que sinon ça va faire très très moche et buggé !
On a une animation des cases en cours de visite, sur fond de montagne enneigée (dégradé noir en bas, et blanc en haut).
[^] # Re: python et lib de graph
Posté par steph1978 . Évalué à 3.
image disparue :
[^] # Re: python et lib de graph
Posté par steph1978 . Évalué à 3.
en plus joli : l'input et le resultat.
# Sans lib, avec visualisation et deuxième partie non bourrine
Posté par GaMa (site web personnel) . Évalué à 2.
J'ai beaucoup aimé l'exo du jour.
Comme beaucoup (tout le monde), un petit algo de parcours de graph pour trouver le chemin le plus court.
J'ai fait une première version "naïve" qui priorisait pas les chemin et donc avançait par "inondation" (D'où le nom de fonction
flood_map
). J'avais un "front" (le point de départ au début) et à chaque passe je calculais un nouveau front (les cases accessibles à partir du front actuel). Dès qu'on arrive à l'arrivée, on sait combien il faut d'étapes.Ça marche très bien, et ça a l'avantage d'être la valeur exacte.
Et je me suis amuser à faire du A*, et donc explorer une seule case du front (au lieu de toutes) et de choisir la case à privilégier en fonction d'un heuristique.
C'est beaucoup plus efficace en terme de performance (nb de case étudiées) mais ça ne donne pas forcement le résultat le plus optimal selon l'heuristique utilisé. (Heureusement que j'avais la première version)
Pour la partie deux, l'astuce c'est de partir de la fin et de s'arrêter dès qu'on trouve une case 'a'. Ça évite de faire du brute force à partant de toutes les cases
a
.Voici la version A* :
(Vous pouvez le lancer avec votre input pour avoir une petite animation)
Matthieu Gautier|irc:starmad
# Étoile
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 4.
Au fait, vu les visualisations, vous avez évidemment remarqué que loin d'être une gorge de rivière, nous avions plutôt affaire à
l'île de Numenorune montagne en forme d'étoile, n'est-ce pas ?[^] # Re: Étoile
Posté par Yth (Mastodon) . Évalué à 3.
Le rendu de mon paysage, en doublant la largeur pour faire moins écrasé.
Complètement Numénor oui.
[^] # Re: Étoile
Posté par steph1978 . Évalué à 2.
j'ai la même mais avec une rotation.
# vizu
Posté par steph1978 . Évalué à 5.
après la version ascii, la version png, voici la version 3D. ma préférée.
[^] # Re: vizu
Posté par Yth (Mastodon) . Évalué à 2.
J'aime beaucoup :)
Bravo !
# En retard
Posté par barmic 🦦 . Évalué à 2.
J'ai commencé avec beaucoup de retard donc je poste ma solution en retard. Comme je voulais être certains d'avoir le chemin optimal, j'ai fais un parcourt complet.
Je stocke la carte sous la forme d'une seule chaine de caractères et je met à jour une table position -> distance pour y parvenir, à chaque itération je repars de toute les nouvelles distances parcourues. C'est très naïf mais très flexible. Si certains chemin commencent à avoir des coûts différents c'est facile à prendre en compte.
Je me suis fais avoir du fait que dans l'entrée on a une case
S
et une caseE
qui sont pas des altitudes.En groovy sans dépendances (que je maitrise pas très bien) ça donne ça :
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.