Das verlorene Bauernproblem

14

Das verlorene Bauernproblem

Nach dem Ende der Schachpartie blieb ein überlebender Bauer hinter den feindlichen Linien zurück. Hilf ihm, den kürzesten Weg nach Hause zu finden.

Das ursprüngliche Problem beschreibt ein nXn-Schachbrett und eine Funktion f: {1,..,n-1}X{1,..,n}X{-1,0,1} => R+der Gewichte. Das Ziel ist es, den besten Weg von einem Feld in der unteren Linie zu einem anderen Feld in der oberen Linie zu finden, wo die möglichen Bewegungen sind: links nach oben, oben, rechts nach oben, und Sie dürfen das Spielfeld nicht verlassen.

Das Problem ist in O (n ^ 2) mit dynamischer Programmierung relativ einfach zu lösen, aber das ist Codegolf, und es interessiert uns nicht, ob es sich um unnötige Dinge wie die Komplexität der Laufzeit handelt ...

Das Problem

Eingabe: Ein 3-dimensionales Array (oder eine andere Sammlung Ihrer Wahl, die über stdin oder als Funktionsargument empfangen wird), das einem regulären Schachbrett entspricht und genau die Größe 7X8X3 (#linePasses X #rowSize X #movesPerPass) enthält nicht negative ganze Zahlen. Die Verschiebungskosten von einer Position, (i,j)an der isich der Zeilenindex und jder Spaltenindex befinden, sind:

  • a[i][j][0]für die Kosten zum Quadrat reisen links (i+1,j-1)oder grafisch: \.
  • a[i][j][1]für die Kosten zum Quadrat zu reisen (i+1,j), oder grafisch: |.
  • a[i][j][2]für die Kosten zum Quadrat reisen oben rechts (i+1,j+1)oder grafisch: /.

Sie können davon ausgehen, dass es keinen Pfad enthält, der größer als ist MAX_INT.

Ausgabe: Eine 8x8 ASCII-Ausgabe, die den besten Pfad (kürzeste, dh minimale Summe der Gewichte) anzeigt (wenn es mehr als ein optimales Ergebnis gibt, können Sie einen beliebigen Pfad Ihrer Wahl anzeigen). Der Pfad wird von unten nach oben gezeichnet, wobei in jeder Zeile das Zeichen, das der Position des Bauern im Pfad entspricht, dasjenige ist, das es machen soll. ZB wenn der Bauer von Spalte 3 nach links oben geht (zu Spalte 2), solltest du ziehen:

#?######
##\#####

wo ?sollte mit dem nächsten Zug ersetzt werden. Endposition muss gezogen werden als X.

Beispiele

Eingang:

[
  [[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]]
]

Ausgabe:

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

Eingang:

[
  [[41,27,38],[12,83,32],[50,53,35],[46,32,26],[55,89,82],[75,30,87],[2,11,64],[8,55,22]],
  [[56,21,0],[83,25,38],[43,75,63],[56,60,77],[68,55,89],[99,48,67],[94,30,9],[62,62,58]],
  [[23,18,40],[24,47,61],[96,45,72],[71,6,48],[75,63,98],[93,56,51],[23,31,30],[49,34,99]],
  [[20,47,42],[62,79,72],[32,28,44],[68,61,55],[62,39,57],[4,17,49],[97,85,6],[91,18,12]],
  [[51,50,11],[32,39,56],[12,82,23],[33,88,87],[60,55,22],[29,78,14],[70,11,42],[63,94,67]],
  [[75,64,60],[27,79,86],[70,72,56],[55,45,32],[95,67,12],[87,93,98],[81,36,53],[38,22,93]],
  [[31,80,50],[77,71,22],[59,46,86],[64,71,53],[41,19,95],[62,71,22],[92,80,41],[26,74,29]]
]

Ausgabe:

######X#
#####/##
####/###
#####\##
#####|##
######\#
######|#
#######\

Das ist , also gewinnt der kürzeste Code.

Fair spielen. keine Lücken ...

BEARBEITEN:

Ich habe eine unkomplizierte Lösung in Scala geschrieben, die Sie sich ansehen können. Es gibt auch eine Seite, auf der Sie online mit Scala-Code spielen können: Scalakata (kopieren Sie einfach den Inhalt von Scalakata und fügen Sie ihn ein. Klicken Sie dann auf die Wiedergabetaste.)

Gilad hoch
quelle

Antworten:

5

F: 199 Bytes

f:{m::x;n::{@/[+/-1 0 1_\:/:(x;m[y;;|!3]);0 2;(0W,),{x,0W}]};i:*<*|r:{&/n[x;y]}\[8#0;!7];  s:{-1+{*<x}'+n[y;z]}\[();(,8#0),-1_r;!7];j:i,{x+y x}\[i;|s];-1(@[8#"#";;:;]'[j;"X","/|\\"1+s'[|!7;-1_j]]);}

ANMERKUNGEN

  • Q-Interpreter (kx.com) kostenlos für den nicht kommerziellen Gebrauch (Versionen für Windows, Linux, Mac)
  • Diese Lösung verwendet den inneren Kern von Q (intern mit k4 bezeichnet), daher benötigen wir eine Skriptdatei mit der Erweiterung k oder einen interaktiven Interpreter im Modus k (\ Befehl an der ersten Eingabeaufforderung). Im Gegensatz dazu erfordert die ausführliche (leserliche) Version der Sprache ein Skript mit der Erweiterung q und ist der Standardmodus beim interaktiven Interpreter.

PRÜFUNG

f ((1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1))

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

f ((41 27 38; 12 83 32; 50 53 35; 46 32 26; 55 89 82; 75 30 87;  2 11 64;  8 55 22)
   (56 21  0; 83 25 38; 43 75 63; 56 60 77; 68 55 89; 99 48 67; 94 30  9; 62 62 58)
   (23 18 40; 24 47 61; 96 45 72; 71  6 48; 75 63 98; 93 56 51; 23 31 30; 49 34 99)
   (20 47 42; 62 79 72; 32 28 44; 68 61 55; 62 39 57;  4 17 49; 97 85  6; 91 18 12)
   (51 50 11; 32 39 56; 12 82 23; 33 88 87; 60 55 22; 29 78 14; 70 11 42; 63 94 67)
   (75 64 60; 27 79 86; 70 72 56; 55 45 32; 95 67 12; 87 93 98; 81 36 53; 38 22 93)
   (31 80 50; 77 71 22; 59 46 86; 64 71 53; 41 19 95; 62 71 22; 92 80 41; 26 74 29))

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

ERLÄUTERUNG

Zur Veranschaulichung nehmen wir einen zweiten Test an (Matrix ((41 27 38; 12 83 32; ....)

Wir transformieren die ursprüngliche Matrix (m auf Codeebene): Anstelle der ursprünglichen Matrix mit einem Triplett für jede Koordinate definieren wir eine Matrix für die Verschiebungen nach links, oben und rechts. Die linke Matrix enthält 7x7-Werte (die erste Spalte wird gelöscht), die obere Matrix 7x8 und die rechte Matrix 7x7 (die letzte Spalte wird gelöscht).

left                           up                         right
12 50 46 55 75 2  8       27 83 53 32 89 30 11 55     38 32 35 26 82 87 64
83 43 56 68 99 94 62      21 25 75 60 55 48 30 62     0  38 63 77 89 67 9 
24 96 71 75 93 23 49      18 47 45 6  63 56 31 34     40 61 72 48 98 51 30
62 32 68 62 4  97 91      47 79 28 61 39 17 85 18     42 72 44 55 57 49 6 
32 12 33 60 29 70 63      50 39 82 88 55 78 11 94     11 56 23 87 22 14 42
27 70 55 95 87 81 38      64 79 72 45 67 93 36 22     60 86 56 32 12 98 53
77 59 64 41 62 92 26      80 71 46 71 19 71 80 74     50 22 86 53 95 22 41

Um die endgültige Position zu berechnen, müssen wir den Pfad mit den geringsten Kosten bewerten. Wir gehen von Anfangskosten 0 0 0 0 0 0 0 0 aus (Kosten für die Ankunft in jeder Spalte der ersten Zeile) und iterieren mit jeder nächsten Zeile. In jeder Spalte i berechnen wir drei Werte:

  • Kosten des vorherigen i + 1-Werts plus links [i + 1]. Wir lassen die erste Komponente der Kosten fallen (verschiebt und fügt Spalten hinzu) und addieren Komponente zu Komponente

  • Kosten des vorherigen i-Werts plus [i]. Wir summieren Komponente zu Komponente

  • Kosten des vorherigen i-1-Werts plus Recht [i-1]. Wir lassen die letzte Komponente der Kosten fallen (verschiebt und fügt Spalten hinzu) und addieren Komponente zu Komponente

Um das Minimum zu berechnen, vervollständigen wir die linken Kosten vor unendlich und die rechten Kosten nach unendlich: Berechnen Sie mit 3 Vektoren von acht Komponenten das Minimum von Komponente zu Komponente. Der resultierende Wert sind die Grundkosten für eine neue Iteration

Für die erste Iteration erhalten wir Werte (0W ist unendlich in Q)

0W 12 50 46 55 75 2  8
27 83 53 32 89 30 11 55
38 32 35 26 82 87 64 0W

und berechnet das Minimum jeder Spalte

27 12 35 26 55 30 2 8

Nach allen Iterationen haben wir die minimalen Kosten, um zu jedem Quadrat zu gelangen (vorausgesetzt, Zeile 0 oben, 7 unten). Wir sind nur an der letzten Spalte interessiert, aber ich zeichne alle Zwischenergebnisse zu illustrativen Zwecken

0   0   0   0   0   0   0   0
27  12  35  26  55  30  2   8
27  37  78  82  110 78  11  70
45  61  123 88  173 129 34  104
87  123 151 143 212 133 40  122
98  155 163 176 234 147 51  185
158 182 219 208 246 234 87  207
208 204 265 261 265 256 128 233

Jetzt haben wir in der letzten Zeile (128, in Spalte 6) den Mindestwert gefunden. Das ist das Ende des Pfades (X-Zeichen in Ausgabe).

Wir wiederholen die Kostenberechnung erneut, geben aber jetzt die Richtung an, aus der wir jedes Minimum erhalten (der ausgewählte Wert ist derjenige der 3 zur Berechnung des Minimums verwendeten Werte).

\|/|\///
\\\\\/|/
\\\|//|/
\\|\//|/
\\|//|\/
\\//|\|/
\|/|/|\/

Wir vertauschen Zeilen, setzen 'X' an Position 6 und behalten nur den Pfad bei, der an Spalte 6 endet (die anderen werden durch # ersetzt).

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\
J. Sendra
quelle
Ich habe noch nie von Q gehört, aber danke für diese ausführliche Antwort :)
Gilad Hoch