Geben Sie bei einer Matrix aus positiven Ganzzahlen den Pfad mit der niedrigsten Summe aus, wenn Sie vom linken oberen Element zum rechten unteren Element wechseln. Sie können sich vertikal, horizontal und diagonal bewegen. Beachten Sie, dass es möglich ist, sich nach oben / unten, rechts / links und diagonal nach allen Seiten zu bewegen.
Beispiel:
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*
Der Pfad mit der niedrigsten Summe ist mit Sternchen markiert und ergibt die folgende Summe: 1 + 4 + 1 + 1 + 1 + 5 + 1 + 9 = 23 .
Testfälle:
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)
Das ist Code-Golf, also gewinnt der kürzeste Code in jeder Sprache.
code-golf
number
graph-theory
optimization
matrix
Stewie Griffin
quelle
quelle
Antworten:
JavaScript,
442 412 408358 BytesDies ist meine erste PPCG-Einreichung. Rückmeldungen sind erwünscht.
Dies nimmt ein mehrdimensionales Array als Eingabe.
Erläuterung
Grundsätzlich sollten Sie alle Zellen immer wieder durchlaufen und die niedrigsten bekannten Kosten anpassen, um zu jedem der Nachbarn zu gelangen. Irgendwann erreicht das Gitter einen Zustand, in dem die Gesamtkosten für das Erreichen der unteren rechten Ecke die niedrigsten Kosten sind.
Demo
Edit: Besonderer Dank geht an @ETHproductions, die mir geholfen haben, Dutzende leckerer Bytes zu rasieren.
Vielen Dank an @Stewie Griffin für Ihre Tipps, die 50 Bytes gekostet haben .
quelle
}
wodurch ein paar Bytes gespart werden sollten. Sie müssen Ihre Variablen auch nicht deklarieren. Ich denke, das Entfernen desvar
s sollte Ihnen insgesamt 24 weitere Bytes sparen.m[v][t]
als Variable speichern :t=x+X;v=y+Y;k=m[v][t]
wird noch kürzer ...?Python 3 + numpy + scipy ,
239222186 BytesProbieren Sie es online!
quelle
Octave + Bildverarbeitungspaket,
175162157151142139 BytesDank @Luis Mendo 14 Byte und dank @notjagan 1 Byte gespeichert
Verwendet das Bildverarbeitungspaket, warum nicht? Lösen nicht alle so Grafikprobleme?
Probieren Sie es online!
Explodiert
Erläuterung
Eine Reihe von Gewichten gegeben:
Initialisieren Sie ein Kostenarray so, dass die Kosten für das Erreichen jedes Elements unendlich sind, mit Ausnahme des Startpunkts (oberes linkes Element), dessen Kosten gleich seinem Gewicht sind.
Dies ist Iteration 0. Für jede nachfolgende Iteration werden die Kosten zum Erreichen einer Zelle auf das Minimum von festgelegt:
Nach der ersten Iteration betragen die Kosten für den Pfad zum Element (2,2) (unter Verwendung einer 1-basierten Indizierung)
Das vollständige Kostenarray nach der ersten Iteration wäre:
Nach der Iteration
k
stellt jedes Element die niedrigsten Kosten für das Erreichen dieses Elements von Anfang an dar, wobei höchstensk
Schritte unternommen werden. Zum Beispiel kann das Element bei (3,3) in 2 Schritten (Iterationen) zu einem Preis von 22 erreicht werden:Bei der 4. Iteration wird jedoch ein Pfad mit 4 Schritten mit Kosten von 20 gefunden:
Da kein Pfad durch die mxn- Matrix länger sein kann als die Anzahl der Elemente in der Matrix (als sehr lockere Obergrenze), enthält
m*n
jedes Element nach Iterationen die Kosten des kürzesten Pfades, um dieses Element von Anfang an zu erreichen.quelle
while
und~
.while
zufor
und konnte trotzdem deinen Tipp verwenden. Vielen Dank!JavaScript, 197 Byte
Verschönern Sie:
quelle
Mathematica 279 Bytes
Grundidee ist einen Graph mit den Eckpunkten entsprechend Matrixeinträge und gerichtete Kanten zwischen zwei beliebigen Vertices von einer getrennt zu schaffen
ChessboardDistance
größer als Null aber kleiner als oder gleich 1. Im übrigen geschieht dies als bekannt seinen König Graph , da sie entspricht die gültigen Züge eines Königs auf einem Schachbrett.FindShortestPath
wird dann verwendet, um den minimalen Pfad zu erhalten. FunktioniertEdgeWeight
nichtVertexWeight
, daher gibt es einen zusätzlichen Code, um denEdgeWeight
als Matrixeintrag zu definieren, der dem Ziel jeder gerichteten Kante entspricht.Code:
Beachten Sie, dass das
Zeichen das Transponierungssymbol ist. Es wird unverändert in Mathematica eingefügt.Verwendung:
Ausgabe:
Wenn Sie
g=Graph[...,GraphLayout->{"GridEmbedding","Dimension"->d},VertexLabels->Thread[s->m]
undp=FindShortestPath[...
dann festlegen, zeigt die folgende Grafik die Lösung visuell an (der obere Rand der Matrix entspricht dem unteren Rand der Grafik):quelle
Haskell, 228 Bytes
Positionen sind Listen mit zwei Elementen, da diese einfach zu generieren
sequence
und genauso einfach zu kopieren sind wie 2-Tupel.Beginnen Sie mit
-1,-1
und zählen Sie die Kosten für jedes Schrittzielfeld.Alternative erste beiden Zeilen: Beginnen Sie mit
0,0
, zählen Sie die Abflugfelder und enden Sie an den Koordinaten, die den Matrixabmessungen entsprechen (also rechts unten vom Ziel, das zur Liste der zulässigen Ziele hinzugefügt werden muss) - exakt dieselbe Länge, aber langsamer:Das Verwenden eines Infixes für
map
spart hier keine Bytes, aber ich ersetze es, sobald es keinen kostet, weil es nur mit mehr Verwendungen und manchmal auch mit anderen Umstrukturierungen besser werden kann, die ein anderes Klammerpaar abschneiden.Zu verbessern: Redundante
filter
s. Merging / in-Futter siefilter(flip elem$(s$(\x->[0..x])#m)\\p)
mitimport Data.List
für\\
Kosten 3 Bytes.Auch zu schade,
(fromEnumTo 0)
ist 2 Bytes länger als(\x->[0..x])
.sum$concat c
werden die Kosten aller Felder aufsummiert und damit eine präzise ausdrückbare Obergrenze für die Pfadkosten angegeben,minimum
um eine leere Liste zu vermeiden (meine Typprüfung hat bereits festgelegt, woran alles gearbeitet werden sollInteger
, also kein hartes Kodieren des Maximums) hehe). Egal, wie ich Schritte einschränke, die auf den vorherigen Schritten basieren (was den Algorithmus erheblich beschleunigen würde, aber auch Byte kosten würde), ich kann die Sackgassen nicht vermeiden, die dieses Zurückfallen erforderlich machen.Eine Filteridee war das
((not.e n).zipWith(-)(head r))
Extrahierenn=s[[-1..1],[-1..1]]
, was das Hinzufügen,[-1,-1]
zum Anfangspfad erfordert . Der Algorithmus vermeidet dann, dorthin zu gehen, wo er bereits im vorherigen Schritt hätte sein können, wodurch das orthogonale Betreten eines Kantenfelds zu einer Sackgasse wird.Eine andere war das
((>=0).sum.z(*)d)
Extrahierenz=zipWith
, dasd
der rekursiven Funktion, die wie(z(-)p q)
in der Rekursion und[1,1]
im Anfangsfall angegeben ist, ein neues Argument hinzufügt . Der Algorithmus vermeidet aufeinanderfolgende Schritte mit einem negativen Skalarprodukt (d
das der vorherige Schritt ist), was bedeutet, dass keine scharfen 45 ° -Drehungen auftreten. Dies schränkt die Auswahlmöglichkeiten immer noch erheblich ein und vermeidet die vorherige triviale Sackgasse, aber es gibt immer noch Wege, die in bereits besuchten Feldern eingeschlossen sind (und möglicherweise eine „Flucht“, die jedoch eine scharfe Wendung darstellen würde).quelle
Python 2,
356320 BytesProbieren Sie es hier aus!
-36 bytes dank notjagan !
Erhält eine Liste mit Listen als Eingabe und gibt die niedrigsten Kosten aus, wenn Sie in der Matrix von links oben nach rechts unten navigieren.
Erläuterung
Suchen Sie jede mögliche Route von links oben nach rechts unten in der Matrix, und erstellen Sie für jede Route eine Liste mit x- und y-Koordinaten. Die Routen können nicht zurückverfolgt werden und müssen bei enden
(len(s)-1,len(s[0])-1)
.Summieren Sie die Ganzzahlen auf jedem Koordinatenpfad und geben Sie die minimalen Kosten zurück.
Das
print
kann leicht geändert werden, um die Liste der Koordinaten für die kürzeste Route auszugeben.quelle
or
für die Bedingungen. Vielen Dank!APL (Dyalog Classic) , 33 Byte
Probieren Sie es online!
{ }
Funktion mit Argument⍵
+\+⍀⍵
Nehmen Sie Teilsummen pro Zeile und pro Spalte, um eine pessimistische Obergrenze für Pfadentfernungen festzulegen( )⍣≡
wiederhole bis zur Konvergenz:(⍉3⌊/⊣/,⊢,⊢/)⍣2
Minimale Abstände zu Nachbarn, dh zweimal (( )⍣2
): linke Spalte (⊣/,
) vor sich selbst (⊢
) stellen und rechte Spalte ( ) anhängen,⊢/
, Minima in horizontalen Tripeln finden (3⌊/
) und transponieren (⍉
)⍵+
Addieren Sie den Wert jedes Knotens zu den Mindestentfernungen zu den Nachbarn⊢⌊
versuche die aktuell besten Distanzen zu schlagen⊃⌽,
Geben Sie zum Schluss die untere rechte Zelle zurückquelle