Étant donné une matrice composée d'entiers positifs, affichez le chemin avec la somme la plus faible lorsque vous passez de l'élément supérieur gauche au coin inférieur droit. Vous pouvez vous déplacer verticalement, horizontalement et en diagonale. Notez qu'il est possible de se déplacer vers le haut / bas, droite / gauche et en diagonale de tous les côtés.
Exemple:
1* 9 7 3 10 2 2
10 4* 1* 1* 1* 7 8
3 6 3 8 9 5* 7
8 10 2 5 2 1* 4
5 1 1 3 6 7 9*
Le chemin donnant la somme la plus faible est marqué d'astérisques et donne la somme suivante: 1 + 4 + 1 + 1 + 1 + 5 + 1 + 9 = 23 .
Cas de test:
1 1 1
1 1 1
Output: 3
7 9 6 6 4
6 5 9 1 6
10 7 10 4 3
4 2 2 3 7
9 2 7 9 4
Output: 28
2 42 6 4 1
3 33 1 1 1
4 21 7 59 1
1 7 6 49 1
1 9 2 39 1
Output: 27 (2+3+4+7+7+1+1+1+1)
5 6 7 4 4
12 12 25 25 25
9 4 25 9 5
7 4 25 1 12
4 4 4 4 4
Output: 34 (5+12+4+4+4+1+4)
1 1 1 1
9 9 9 1
1 9 9 9
1 9 9 9
1 1 1 1
Output: 15
2 55 5 3 1 1 4 1
2 56 1 99 99 99 99 5
3 57 5 2 2 2 99 1
3 58 4 2 8 1 99 2
4 65 66 67 68 3 99 3
2 5 4 3 3 4 99 5
75 76 77 78 79 80 81 2
5 4 5 1 1 3 3 2
Output: 67 (2+2+3+3+4+5+4+3+3+3+1+2+2+1+3+1+1+4+5+1+2+3+5+2+2)
Il s'agit de code-golf, donc le code le plus court dans chaque langue l'emporte.
code-golf
number
graph-theory
optimization
matrix
Stewie Griffin
la source
la source
Réponses:
JavaScript,
442 412 408358 octetsCeci est ma première soumission PPCG. Des commentaires seraient appréciés.
Cela prend un tableau multidimensionnel en entrée.
Explication
Fondamentalement, parcourez toutes les cellules à plusieurs reprises en ajustant le coût connu le plus bas pour atteindre chacun des voisins. Finalement, la grille atteindra un état où le coût total pour atteindre le coin inférieur droit est le coût le plus bas pour y arriver.
Démo
Edit: Un merci spécial à @ETHproductions pour m'avoir aidé à raser des dizaines d'octets savoureux.
Merci à @Stewie Griffin pour vos conseils qui ont fait tomber 50 octets.
la source
}
qui devrait économiser quelques octets. Vous n'avez pas non plus besoin de déclarer vos variables; Je pense que la suppression desvar
s devrait vous faire économiser 24 octets de plus au total.m[v][t]
tant que variable:t=x+X;v=y+Y;k=m[v][t]
sera encore plus court ...?Python 3 + numpy + scipy ,
239222186 octetsEssayez-le en ligne!
la source
Octave + Image paquet de traitement,
175162157151142139 octets14 octets enregistrés grâce à @Luis Mendo et 1 octet grâce à @notjagan
Utilise le package de traitement d'image, car pourquoi pas? N'est-ce pas ainsi que tout le monde résout les problèmes graphiques?
Essayez-le en ligne!
A explosé
Explication
Étant donné un éventail de poids:
Initialisez un tableau de coûts pour que le coût pour atteindre chaque élément soit Infinity, sauf le point de départ (l'élément supérieur gauche) dont le coût est égal à son poids.
Il s'agit de l'itération 0. Pour chaque itération suivante, le coût pour atteindre une cellule est fixé au minimum:
Après la première itération, le coût du chemin vers l'élément (2,2) (en utilisant une indexation basée sur 1) sera
Le tableau de coût complet après la première itération serait:
Après l'itération
k
, chaque élément sera le coût le plus bas pour atteindre cet élément dès le début en prenant la plupart desk
étapes. Par exemple, l'élément à (3,3) peut être atteint en 2 étapes (itérations) pour un coût de 22:Mais à la 4ème itération, on trouve un chemin de 4 étapes avec un coût de 20:
Puisqu'aucun chemin à travers la matrice mxn ne peut être plus long que le nombre d'éléments dans la matrice (comme une limite supérieure très lâche), après les
m*n
itérations, chaque élément contiendra le coût du chemin le plus court pour atteindre cet élément depuis le début.la source
while
et~
.while
àfor
et j'ai toujours pu utiliser votre astuce. Merci!JavaScript, 197 octets
Enjoliver:
la source
Mathematica 279 octets
L'idée de base est de créer un graphique avec des sommets correspondant aux entrées de la matrice et des arêtes dirigées entre deux sommets séparés par un
ChessboardDistance
supérieur à zéro mais inférieur ou égal à 1. Par ailleurs, cela se trouve être connu sous le nom de graphe King , car il correspond à les mouvements valides d'un roi sur un échiquier.FindShortestPath
est ensuite utilisé pour obtenir le chemin minimal. Cela fonctionneEdgeWeight
, nonVertexWeight
, donc il y a du code supplémentaire pour définir l'EdgeWeight
entrée de la matrice correspondant à la destination de chaque bord dirigé.Code:
Notez que le
caractère est le symbole de transposition. Il sera collé dans Mathematica tel quel.Usage:
Production:
Si vous définissez
g=Graph[...,GraphLayout->{"GridEmbedding","Dimension"->d},VertexLabels->Thread[s->m]
etp=FindShortestPath[...
ensuite le graphique suivant affichera visuellement la solution ( en haut de la matrice correspond au bas du graphique):la source
Haskell, 228 octets
Les positions sont des listes de deux éléments, car ceux-ci sont faciles à générer avec
sequence
et tout aussi faciles à mettre en correspondance que les 2-tuples.Commencez par
-1,-1
et comptez le coût de chaque champ de destination des étapes.Deux premières lignes alternatives: commencer à
0,0
, compter les champs de départ, terminer aux coordonnées égales aux dimensions de la matrice (donc en bas à droite de l'objectif, qui doit être ajouté à la liste des destinations légales) - même longueur exacte mais plus lente:L'utilisation d'un infixe pour
map
ne permet pas d'économiser des octets ici, mais je le remplace dès qu'il n'en coûte pas un, car il ne peut s'améliorer qu'avec plus d'utilisations, et parfois avec d'autres restructurations qui rasent une autre paire de parenthèses.Points à améliorer: Redundant
filter
s. Les fusionner / les aligner avecfilter(flip elem$(s$(\x->[0..x])#m)\\p)
avecimport Data.List
pour des\\
coûts de 3 octets.Aussi, dommage,
(fromEnumTo 0)
c'est 2 octets de plus que(\x->[0..x])
.sum$concat c
est le coût de tous les champs résumé et donc une limite supérieure exprimable de manière concise sur le coût du chemin qui est donné àminimum
pour éviter une liste vide (mon vérificateur de type a déjà déterminé le tout pour travailler surInteger
s, donc pas de codage en dur le maximum , hehe). Peu importe comment je restreins les étapes basées sur la précédente (ce qui accélérerait beaucoup l'algorithme, mais coûterait également des octets), je ne peux pas éviter les impasses qui rendent cette solution de repli nécessaire.Une idée de filtre était
((not.e n).zipWith(-)(head r))
avec l'extractionn=s[[-1..1],[-1..1]]
, ce qui nécessite d'ajouter,[-1,-1]
au chemin initial. L'algorithme évite alors d'aller là où il aurait déjà pu aller à l'étape précédente, ce qui fait que marcher sur un champ de bord orthogonalement à ce bord est une impasse.Un autre était
((>=0).sum.z(*)d)
d'extrairez=zipWith
, qui introduit un nouvel argumentd
à la fonction récursive qui est donnée comme(z(-)p q)
dans la récursivité et[1,1]
dans le cas initial. L'algorithme évite les étapes successives avec un produit scalaire négatif (d
étant l'étape précédente), ce qui signifie pas de tours brusques de 45 °. Cela rétrécit encore considérablement les choix et évite l'impasse triviale précédente, mais il y a encore des chemins qui finissent enfermés dans des champs déjà visités (et peut-être une `` évasion '' qui serait cependant un virage serré).la source
Python 2,
356320 octetsEssayez-le ici!
-36 octets grâce à notjagan !
Reçoit une liste de listes en entrée et affiche le coût le plus bas lors de la navigation dans la matrice du coin supérieur gauche au coin inférieur droit.
Explication
Trouvez tous les itinéraires possibles du coin supérieur gauche au coin inférieur droit de la matrice, en créant une liste de coordonnées x, y pour chaque itinéraire. Les itinéraires ne peuvent pas revenir en arrière et doivent se terminer à
(len(s)-1,len(s[0])-1)
.Additionnez les entiers sur chaque chemin de coordonnées et retournez le coût minimum.
Le
print
peut être facilement modifié pour afficher la liste des coordonnées de l'itinéraire le plus court.la source
or
conditionnels. Je vous remercie!APL (Dyalog Classic) , 33 octets
Essayez-le en ligne!
{ }
fonction avec argument⍵
+\+⍀⍵
prendre des sommes partielles par ligne et par colonne pour établir une limite supérieure pessimiste sur les distances de chemin( )⍣≡
répéter jusqu'à convergence:(⍉3⌊/⊣/,⊢,⊢/)⍣2
minimum de distances avec les voisins, c.-à-d. faire deux fois (( )⍣2
): ajouter la colonne la plus à gauche (⊣/,
) à self (⊢
) et ajouter les colonnes à l'extrême droite (,⊢/
), trouver les minima dans les triplets horizontaux (3⌊/
) et transposer (⍉
)⍵+
ajouter la valeur de chaque nœud à son minimum de distances aux voisins⊢⌊
essayez de battre les meilleures distances actuelles⊃⌽,
enfin, retournez la cellule en bas à droitela source