Calendrier de l'avent 🎄 (mais sans chocolats)

Une journĂ©e de repos aura fait le plus grand bien Ă  mes neurones. Non seulement j’ai rĂ©ussi Ă  comprendre la partie 2 de ce jour, mais j’ai repris de zĂ©ro le jour 12, j’ai fait simple et ça passe en moins d’ une seconde :slight_smile:

Une journĂ©e 16 Ă©galement sans difficultĂ© particuliĂšre. C’est surprenant, en gĂ©nĂ©ral les problĂšmes du week-end lors des deux derniĂšres semaines sont plutĂŽt corsĂ©s.
Bon ben week-end Ă  tous alors :slight_smile:

Oui, pas de piĂšge sur ce jour 16. Va-t-on prendre cher demain ? :scream:

Pas eu de soucis si ce n’est une erreur entre un + et un - qui m’a retardĂ©. C’est bien du brute force qu’il faut faire pour la partie 2 (ça me prend 11s :open_mouth:) ?

Le brute force marche trĂšs bien oui. Juste une grosse seconde pour moi pour la partie 2 Ă  essayer chaque entrĂ©e, sans ajouter d’optimisation particuliĂšre par rapport Ă  la partie 1.
J’ai aussi tendance Ă  n’utiliser que des structures « lourdes Â» (genre je prĂ©fĂšre une Map<Pair<Int, Int>, Char> plutĂŽt qu’un tableau 2D de Char, faut pas chercher), mais comme je fais ça en Kotlin c’est beaucoup moins punitif que le Python niveau perf.

Moi aussi, parcours systĂ©matique de toutes les entrĂ©es, pas d’optimisation sur un cache des chemins.
Et utilisation d’un bon vieux dict. 2.6s en python sur proc de 5 ans.
→ part 1 (0.006s): 7632
→ part 2 (2.591s): 8023
Day 16

edit
→ part 2 (1.548s): 8023 : j’avais laissĂ© des deepcopy qui ne servent a rien. 1s de gagnĂ©! :sweat_smile:

Pour le coup je stock un set de (int, int, str) (i,j, direction) les parties visitĂ©es. Je vais voir si je peux faire mieux si j’ai le temps.

Edit: en changeant une queue.Queue pour une collection.deque ça va 10x plus vite j’ai l’impression. Je ne vais pas chercher plus :smiley:

2 « J'aime »

Oui Jour 16 ça se brute force bien, idem entre 1 et 2 secondes sur mon vénérable pc portabe de 2015.

Jour 17 pas de problĂšme particulier. J’avais peur au dĂ©but la partie 1 ramait beaucoup, mais je testais plusieurs fois les mĂȘmes possibilitĂ©.
Pour la partie 2 ça tourne en 2-3 sec, et pas besoin de retoucher à beaucoup de code pour y arriver. Bref pas de piùge aujourd’hui

Hmm moi je bloque sur 1 : je tente un Dijkstra, en ajoutant une condition sur les voisins non visitĂ©s. Quand j’arrive sur une position, je regarde les 3 prĂ©dĂ©cesseurs. S’ils sont tous sur la mĂȘme colonne ou ligne, alors je suis obligĂ© de tourner. Sur l’exemple, j’obtiens 127 comme rĂ©sultat, donc pas bon.

Je bloque aussi sur la partie 1.

J’ai essayĂ© un algo maison au dĂ©but, mais sans grande surprise ça part vite en sucette.

Ce qui me gĂȘne c’est que sur l’example le chemin ne se recoupe jamais, alors que je pense qu’en thĂ©orie il devrait ĂȘtre possible d’avoir un trajet optimal qui passe plusieurs fois sur une mĂȘme case - et je n’ose pas partir sur un Dijsktra « standard Â» (ou modifiĂ© comme le tient) qui ne prendrait a priori pas en compte cette possibilitĂ©.

Je pense que ça vient du fait que si tu gardes les 3 derniers trajets d’un node « optimal Â», tu vas te couper des routes alors qu’une arrivĂ©e sur le mĂȘme node avec un moins bon score (dĂ©jĂ  Ă©liminĂ© chez toi) permettrait de continuer tout droit par un chemin meilleur au final.
Peut-ĂȘtre qu’il faudrait exploser chaque node du graphe en sous-node diffĂ©rente selon la direction d’arrivĂ©e et le nombre de pas dans cette direction prĂ©cĂ©dents.

.

Oui j’ai fait ça. Je garde un Ă©tat qui est la position, la direction en cours et le nombre de fois successives que je suis cette direction. Et ça aide pour la partie 2.

Et oui, il ne faut pas se couper d’une arrivĂ©e sur un noeud en gardant uniquement l’arrivĂ©e optimale.
Un pattern frĂ©quent est qu’on veut aller tout droit, mais la limite de 3 impose de faire un pas de cĂŽtĂ©, d’avancer d’un cran et de revenir sur la trajectoire initiale.

Et pas de boucle constatĂ© dans mon cas. D’ailleurs je ne vois pas comment ça pourrait se produire. Sur la partie 2 Ă  la rigueur, mais le coĂ»t de faire la boucle sera trop grand je pense par rapport Ă  une autre solution.

1 « J'aime »

Je vois la limite de mon approche, sur un exemple simple

11111
21191

ça ne marche pas


Formalisme

En rĂ©flĂ©chissant, est-ce que les noeuds devraient donc ĂȘtre (i, j, dir, k), tous initialisĂ©s avec une distance max (avec dir entre 0 et 3) ? Et ensuite, pour chaque noeud, je trouve celui de distance min pas encore visitĂ©, et je mets Ă  jour les voisins potentiels ? J’ai pas l’impression que ça va marcher :frowning:

Edit: je m’en suis sorti : il faut changer un peu l’algo de Dijkstra pour en remettre dans la boucle si nĂ©cessaire. Une fois que j’ai compris ça, le reste dĂ©roule simplement. Et la partie 2 se fait bien si on stock la direction et le nombre de pas dĂ©jĂ  fait.

1 « J'aime »

Oui, mais chez moi chaque noeud doit ĂȘtre dupliquĂ© avec la distance k entre 1 et 3 (pas 0 et 3) vu que c’est le nombre de cases parcourues dans cette distance sans tourner, et ce pour chacunes de 4 directions. Du coup quand tu vas insĂ©rer un nouveau noeud, il aura toujours dĂ©jĂ  parcouru une case dans cette direction. Ça donne donc 12 noeuds pour chaque case dans le graphe Ă©clatĂ© sur lequel on fait ensuite tourner Dijkstra.

Et pas de souci concernant ma rĂ©serve sur le fait que Dijkstra ne couvre pas les chemins se coupant: Ça marche tout Ă  fait, car un chemin optimal se recoupera forcĂ©ment selon des directions perpendiculaires - et comme les directions sont diffĂ©rentes, ce sont donc 2 noeuds diffĂ©rents dans le graphe « Ă©clatĂ© Â», donc pas de souci, aucun noeud du graphe Ă©clatĂ© ne doit ĂȘtre parcouru 2 fois par le chemin optimal.

Sinon pour la partie 2 j’ai galĂ©rĂ© un peu en oubliant le fait que le wagon ne peut pas s’arrĂȘter sur la case finale sans avoir parcouru au moins 4 cases dans la mĂȘme direction. Heureusment que le deuxiĂšme exemple m’a aidĂ© Ă  identifier le problĂšme !

En effet je n’ai pas trouvĂ© de cas avec une boucle pour ces rĂšgles du problĂšme. J’ai Ă©tĂ© un peu trop prĂ©cautionneux car je m’attendais Ă  une partie 2 du genre « maintenant les wagons doivent toujours tourner du mĂȘme cĂŽtĂ© Â», ce qui aurait rendu possible les cycles sur le chemin optimal.

Et donc le code que j’ai oubliĂ© de poster. Pour ceux que ça intĂ©resse, j’ai mis pas mal de commentaires si vous bloquez et que vous cherchez Ă  comprendre.

17.1 faite en s’inspirant du jour 10 pour intĂ©rieur/extĂ©rieur, par contre j’ai peur que le brute force ne fonctionne pas pour la partie 2. Il va falloir rĂ©flĂ©chir


Je me prend grave la tĂȘte sur la partie 2 du jour 18. Je suis sĂ»r qu’il doit y avoir un moyen plus simple que ce que je tente, quitte Ă  faire un peu de brute force, mais j’hĂ©site Ă  tout reprendre de zĂ©ro
 Dans tous les cas c’est trĂšs intĂ©ressant comme problĂšme !

J’ai une idĂ©e que je n’arrive pas Ă  mettre en oeuvre:

Idée

On rĂ©cupĂšre les segments horizontaux et verticaux sĂ©parĂ©ment. On rĂ©cupĂšre aussi tous les corners, on met les x dans abs, et les y dans ord. Ensuite, on teste chaque rectangle possible avec les x dans abs et ord. Pour chaque rectangle, on calcule son centre, et on regarde combien de segments horizontaux il intersecte en haut, si impair on regarde combien de verticaux Ă  gauche, si impair on ajoute l’air du rectangle. Mais je dois me planter dans des indices

C’est vraiment la galùre avec les indices. J’ai choisi une approche encore moins simple:

Idée
  • Je stocke tous les coins (points) dans une liste.
  • Je cherche le point le plus en haut puis le plus Ă  gauche de la forme
  • J’écrase cette excroissance jusquĂ  arriver au prochain coins, je calcule l’aire du rectangle ainsi Ă©crasĂ©. Faut faire gaffe Ă  bien tout calculer quand ça fait une ligne qui sort de la forme en bas de l’écrasement.
  • Rebelotte jusqu’à arriver Ă  un rectangle.
  • C’est plus corsĂ© si il y a une boucle Ă  l’intĂ©rieur du rectangle que j’écrase - dans ce cas, aprĂšs avoir ajoutĂ© l’aire du rectangle Ă©crasĂ©, ça va me faire deux circuits fermĂ©s de part et d’autre de la boucle, et j’utilise le mĂȘme algo pour calculer l’aire de chacun

LĂ  j’en suis au cas oĂč je tombe sur une boucle en Ă©crasant le rectangle, je m’embrouille de partout mais j’avance petit Ă  petit !