Percorsi e tempo perso


22

Premessa

Di recente, ero in ritardo di circa mezz'ora per un appuntamento e ho deciso di aspettare fuori. Decisi anche che sarebbe stato strano se fossi rimasto immobile davanti alla casa. Pertanto, ho deciso di fare una breve passeggiata, in un'area limitata. Ho anche concluso che se avessi iniziato a camminare in cerchio sarebbe ovvio che stavo bighellonando. Quindi sono stato ispirato a creare la mia prima sfida di Code Golf.

specificazione

Ti verrà dato un elenco, una mappa dell'area, che conterrà uno " "o "#", che rappresentano spazi liberi e ostacoli di qualche tipo. Gli spazi liberi possono essere attraversati una sola volta e ci vuole 1 minuto per attraversarlo. La tua posizione iniziale sarà indicata con una "@"tradizione per roguelike e l'obiettivo sarà rappresentato con un "$"perché è quello che perderai lì. Ti verrà anche dato un numero intero che rappresenterà quanti minuti devi perdere prima di non sembrare che ti stia intromettendo. Quando atterri sul"$", dovrà essere stato l'esatto numero di minuti (quindi se si effettua il conto alla rovescia, dovrà essere 1 su una tessera adiacente ed essere 0 sulla tessera). Sarà sempre possibile raggiungere la destinazione. Il programma o la funzione dovrà restituire un elenco che mostra il percorso più breve con <,>, ^ e v per rappresentare le quattro direzioni possibili.

Esempi

Ingresso:

[[" ", " ", " ", " "],
 ["@", " ", " ", "$"],
 [" ", " ", " ", " "],
 [" ", " ", " ", " "]]

e

5

ouput:

[[">", ">", ">", "v"],
 ["^", " ", " ", "$"],
 [" ", " ", " ", " "],
 [" ", " ", " ", " "]]

Ingresso:

[[" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 ["@", "#", " ", "$", " "],
 [" ", " ", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "]]

e

7

Produzione:

[[" ", "#", " ", " ", " "],
 [" ", "#", ">", "v", " "],
 ["v", "#", "^", "$", " "],
 [">", ">", "^", " ", " "],
 [" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "]]

Ingresso:

[[" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 ["@", "#", " ", "$", " "],
 [" ", " ", " ", " ", " "],
 [" ", "#", " ", " ", " "],
 [" ", "#", " ", " ", " "]]

e

17

Produzione:

[[" ", "#", " ", "v", "<"],
 [" ", "#", " ", "v", "^"],
 ["v", "#", " ", "$", "^"],
 [">", ">", "v", ">", "^"],
 [" ", "#", "v", "^", "<"],
 [" ", "#", ">", ">", "^"]]

Regole

  • Si applicano scappatoie standard
  • Ogni tessera deve essere spostata una sola volta
  • Il tempo esatto deve essere speso sul tabellone
  • Solo un percorso deve essere visualizzato nel caso di più percorsi
  • Questa è una domanda di golf del codice, quindi vince la risposta più breve
  • Come da domanda di user202729 nei commenti, puoi assumere un input valido.

Aggiungi un commento se sono necessari ulteriori chiarimenti


1
È garantito che "Sarà sempre possibile raggiungere la destinazione nel tempo specificato "?
user202729

Sì, ci sarà sempre un modo, anche se contorto
LForchini,

5
Benvenuti in PPCG! :) Bella prima sfida.
Giuseppe,

Che cosa è successo al mezzo minuto ad ogni estremità ?! (non è necessario cambiare nulla se non è ovvio)
Jonathan Allan,

Risposte:


6

JavaScript (ES6), 171 byte

Accetta input nella sintassi del curry (a)(n). Emette modificando la matrice di input.

a=>g=(n,y=a[F='findIndex'](r=>~(i=r[F](v=>v>'?'))),x=i,R=a[y])=>!n--|[-1,0,1,2].every(d=>(R[x]='<^>v'[d+1],(c=(a[Y=y+~-d%2]||0)[X=x+d%2])<1?g(n,Y,X):n|c!='$')&&(R[x]=' '))

Provalo online!

Commentate

a =>                           // a[] = input matrix
g = (                          // g = recursive function taking:
  n,                           //   n = number of remaining moves
                               //   (x, y) = current coordinates, initialized as follows:
  y = a[F = 'findIndex'](r =>  //     y = index of the row containing the starting point,
    ~(i = r[F](v => v > '?'))  //         found by iterating over all rows r until we
  ),                           //         find some i such that r[i] > '?'
  x = i,                       //     x = index of the column of the starting point
  R = a[y]                     //   R[] = current row
) =>                           //
  !n-- |                       // decrement n; force failure if we're out of moves
  [-1, 0, 1, 2].every(d =>     // for each direction d, where -1 = left, 0 = up,
    (                          // 1 = right and 2 = down:
      R[x] = '<^>v'[d + 1], (  //   update the current cell with the direction symbol
        c = (                  //   c = content of the new cell at (X, Y) with:
          a[Y = y + ~-d % 2]   //     Y = y + dy
          || 0                 //     (use a dummy value if this row does not exist)
        )[X = x + d % 2]       //     X = x + dx
      ) < 1 ?                  //   if c is a space:
        g(n, Y, X)             //     we can go on with a recursive call
      :                        //   else:
        n | c != '$'           //     return false if n = 0 and we've reached the target
    ) &&                       //   unless the above result is falsy,
    (R[x] = ' ')               //   restore the current cell to a space
  )                            // end of every()

5

Python 2 , 310 256 byte

Grazie @cairdcoinheringaahing per except:0-3 byte
Grazie @Mnemonic per -8 byte
Grazie @JonathanAllan per -3 byte
Grazie @ovs per -5 byte

G,L=input()
R=[]
def S(x,y,G,c,R):
 try:
	if x>-1<y<G[y][x]in' @':i=0;exec"T=[r[:]for r in G];T[y][x]='<v^>'[i];S(x+~-i/2,y+~-(i^2)/2,T,c-1,R);i+=1;"*4
	R+=[G]*(0==c<'$'==G[y][x])
 except:0
for i,y in enumerate(G):"@"in y>S(y.index("@"),i,G,L,R)
print R[0]

Provalo online!

Qualche spiegazione:

try-exceptviene utilizzato per garantire che sia xe ycoordinate sono in confini. Eccezione verrà sollevata all'accesso a G[y][x]. Python è troppo buono e gli indici negativi sono accettabili, quindi x>-1<yviene aggiunto un segno di spunta .

T=[r[:]for r in G]usato per creare una copia di Gby valori

~-i/2e ~-(i^2)/2sono usati per generare coppie (-1, 0), (0, 1), (0, -1), (1, 0), che si muovevano in griglia (dovrebbe esserci ancora un modo più breve!)

R+=[G]*(0==c<'$'==G[y][x])controllare, che '$'si raggiunge nel numero richiesto di passaggi. Rviene utilizzato per ottenere questo risultato da chiamate di funzione ricorsive.

for i,y in enumerate(G):"@"in y>S(y.index("@"),i,G,L,R)Trovato xe ydi '@'in ingresso e funzione di chiamata S.

print R[0] R potrebbe contenere più di una soluzione, quindi solo l'output



1
È possibile salvare un byte sostituendolo if G[y][x]=='$':con if'$'==G[y][x]:.

1
In realtà, l'intera condizione può essere sostituita con R+=(G[y][x]=='$')*(c==0)*[G]un altro byte.

1
Eh, non sono sicuro di quello che stavo vedendo. È possibile salvare un paio di byte nella prima condizione conif(x>-1<y)*(G[y][x]in' @'):

1
Un modo più breve per il tuo y+cmp(i%2,i/2)sarebbe y+~-(i^2)/2; ci potrebbe essere ancora più breve.
Jonathan Allan,

2

Pitone 2 , 264 261 251 249 byte

def f(a,n,r=-1,s=0):
 j=len(a[0]);x=1;z=y=0
 if r<0:s,r=divmod(sum(a,[]).index('@'),j)
 for c in'>v<^':
	u=r+x;v=s+y;x,y=-y,x
	if j>u>-1<v<len(a):b=[e[:]for e in a];b[s][r]=c;w=a[v][u];z=n*(w<'!')and f(b,n-1,u,v)or n==1and w=='$'and b
	if z:return z

Provalo online!


1
@Arnauld: Oops! È un po 'troppo elaborato. Fisso.
Chas Brown,
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.