Il problema del pedone perduto


14

Il problema del pedone perduto

Dopo che la partita a scacchi terminò, una pedina sopravvissuta fu lasciata dietro le linee nemiche. aiutiamolo a trovare la via più breve per tornare a casa.

Il problema originale descrive una scacchiera "scacchi" nXn e una funzione f: {1,..,n-1}X{1,..,n}X{-1,0,1} => R+di pesi. l'obiettivo è quello di trovare il percorso migliore da un quadrato nella linea di fondo, verso qualche altro quadrato nella linea superiore, dove le mosse possibili sono: sinistra-su, su, destra-su, e non puoi uscire dal tabellone.

Il problema è relativamente facile da risolvere in O (n ^ 2) usando la programmazione dinamica, ma questo è codegolf e non ci interessa cose inutili come la complessità del tempo di esecuzione ...

Il problema

input: un array tridimensionale (o qualche altra raccolta a scelta, ricevuta tramite stdin o come argomento di funzione), corrispondente a una normale scacchiera, esattamente nelle dimensioni: 7X8X3 (#linePasses X #rowSize X #movesPerPass) contenente numeri interi non negativi. i costi di spostamento da una posizione in (i,j)cui si itrova l'indice di riga e jl'indice di colonna sono:

  • a[i][j][0]per il costo di viaggiare fino a sinistra di piazza (i+1,j-1), o graficamente: \.
  • a[i][j][1]per il costo di viaggiare fino a piazza (i+1,j), o graficamente: |.
  • a[i][j][2]per il costo di viaggiare in alto a destra di piazza (i+1,j+1), o graficamente: /.

si può presumere che non conterrà un percorso che è maggiore di MAX_INT.

output: un output ASCII 8X8 che mostra il percorso migliore (il più breve, ovvero la somma minima dei pesi) (se esiste più di 1 risultato ottimale, è possibile mostrare un percorso arbitrario a scelta). il tracciato viene tracciato dal basso verso l'alto, dove in ogni riga, il carattere corrispondente alla posizione del pedone nel tracciato è quello che sta per creare. ad es. se il pedone sta per spostarsi verso l'alto-a sinistra dalla colonna 3 (alla colonna 2), dovresti disegnare:

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

dove ?dovrebbe essere sostituito con la prossima mossa. la posizione finale deve essere disegnata come X.

Esempi

ingresso:

[
  [[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]]
]

produzione:

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

ingresso:

[
  [[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]]
]

produzione:

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

questo è , quindi vince il codice più corto.

giocare pulito. nessuna scappatoia ...

MODIFICARE:

Iv'e ha scritto una soluzione semplice senza golf in scala che puoi vedere. C'è anche un sito su cui puoi giocare con lo scala code online: scalakata (basta copiare e incollare l'essenza in scalakata e premere il pulsante play)

Risposte:


5

Q: 199 byte

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]]);}

APPUNTI

  • Q interpreter (kx.com) gratuito per uso non commerciale (versioni per Windows, Linux, Mac)
  • Questa soluzione utilizza il nucleo interno di Q (internamente chiamato k4), quindi abbiamo bisogno di un file di scripting con estensione k o di un interprete interattivo in modalità k (\ comando al primo prompt). Al contrario, la versione 'verbosa' (leggibile) della lingua richiede uno script con estensione q ed è la modalità predefinita dell'interprete interattivo.

TEST

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#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

SPIEGAZIONE

A scopo illustrativo, assumiamo il secondo test (matrice ((41 27 38; 12 83 32; ....)

Trasformiamo la matrice originale (m a livello di codice): anziché la matrice originale con una tripletta per ciascuna coordinata, definiamo la matrice per gli spostamenti a sinistra, su e destra. La matrice sinistra contiene 7x7 valori (eliminiamo la prima colonna), la matrice Up 7x8 e la matrice destra 7x7 (spostiamo l'ultima colonna).

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

Per calcolare la posizione finale dobbiamo valutare il percorso di costo minimo. Supponiamo che il costo iniziale sia 0 0 0 0 0 0 0 0 (costo per arrivare a ciascuna colonna della prima riga) e itererà con ogni riga successiva. Ad ogni colonna i calcoliamo tre valori:

  • costo del precedente valore i + 1 più sinistra [i + 1]. Rilasciamo il primo componente del costo (turni e colonne alineates da aggiungere) e sommiamo il componente al componente

  • costo del precedente valore i plus up [i]. Sommiamo un componente all'altro

  • costo del precedente valore i-1 più diritto [i-1]. Rilasciamo l'ultimo componente del costo (sposta e alineatra le colonne da aggiungere) e sommiamo il componente al componente

Per calcolare il minimo completiamo il costo sinistro anteponendo l'infinito e il costo giusto aggiungendo infinito: con 3 vettori di otto componenti, calcola il componente minimo a componente. Il valore risultante è il costo base per la nuova iterazione

Per la prima iterazione otteniamo valori (0W è infinito 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

e calcola il minimo di ogni colonna

27 12 35 26 55 30 2 8

Dopo tutte le iterazioni, abbiamo il costo minimo per arrivare a ciascun quadrato (supponendo che la riga 0 in alto, 7 in fondo). Siamo interessati solo all'ultima colonna, ma traggo tutti i risultati intermedi per scopi ilustrativi

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

Ora abbiamo trovato il valore minimo nell'ultima riga (128, nella colonna 6). Questa è la fine del percorso (carattere X in uscita).

Ripetiamo nuovamente il calcolo dei costi, ma ora annotiamo la direzione da cui otteniamo ogni minimo (quale dei 3 valori utilizzati per calcolare il minimo è il valore selezionato).

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

Invertiamo le righe, mettiamo 'X' in pos 6 e preserviamo solo il percorso che termina nella colonna 6 (gli altri sono sostituiti da #)

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

Iv'e non ha mai sentito parlare di Q, ma grazie per una risposta così dettagliata :)
Gilad Hoch,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.