Sentiers et perte de temps

22

Prémisse

Donc, récemment, j'avais environ une demi-heure d'avance pour un rendez-vous et j'ai décidé d'attendre dehors. J'ai également déterminé qu'il serait étrange que je me tienne immobile devant la maison. Par conséquent, j'ai décidé de faire une promenade rapide, dans une zone limitée. J'ai également conclu que si je commençais à tourner en rond, cela rendrait évident que je flânais. J'ai donc été inspiré pour créer mon premier défi Code Golf.

spécification

Vous recevrez une liste, une carte de la zone, qui contiendra soit " "ou "#", qui représentent des espaces libres et des obstacles en quelque sorte. Les espaces libres ne peuvent être traversés qu'une seule fois et il faut 1 minute pour le traverser. Votre position initiale sera signifiée par une "@"tradition par roguelike, et la cible sera représentée par un "$"car c'est ce que vous allez perdre là-bas. Vous recevrez également un entier qui représentera le nombre de minutes que vous devez perdre avant de ne pas avoir l'air de vous emparer. Lorsque vous atterrissez sur le"$", il devra s'agir du nombre exact de minutes (donc si vous comptez à rebours, il devra être 1 sur une tuile adjacente et 0 sur la tuile). Il sera toujours possible d'atteindre la destination. Votre programme ou fonction devra renvoyer une liste indiquant le chemin le plus court avec <,>, ^ et v pour représenter les quatre directions possibles.

Exemples

Contribution:

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

et

5

Sortie:

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

Contribution:

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

et

7

Sortie:

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

Contribution:

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

et

17

Sortie:

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

Règles

  • Des échappatoires standard s'appliquent
  • Chaque tuile ne doit être déplacée qu'une seule fois
  • Le temps exact doit être passé sur le tableau
  • Un seul chemin doit être affiché dans le cas de plusieurs chemins
  • Ceci est une question de code de golf, donc la réponse la plus courte gagne
  • Selon la question de user202729 dans les commentaires, vous pouvez supposer une entrée valide.

Ajoutez un commentaire si des précisions supplémentaires sont nécessaires

LForchini
la source
1
Est-il garanti que "Il sera toujours possible d'atteindre la destination dans le délai spécifié "?
user202729
Oui, ce sera le cas, il y aura toujours un moyen, même alambiqué
LForchini
5
Bienvenue chez PPCG! :) Beau premier défi.
Giuseppe
Qu'est-il arrivé à la demi-minute à chaque extrémité?! (pas besoin de changer quoi que ce soit si ce n'est pas évident)
Jonathan Allan

Réponses:

6

JavaScript (ES6), 171 octets

Prend une entrée dans la syntaxe de curry (a)(n). Sorties en modifiant la matrice d'entrée.

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]=' '))

Essayez-le en ligne!

Commenté

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()
Arnauld
la source
5

Python 2 , 310 256 octets

Merci @cairdcoinheringaahing pour except:0-3 octets
Merci @Mnemonic pour -8 octets
Merci @JonathanAllan pour -3 octets
Merci @ovs pour -5 octets

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]

Essayez-le en ligne!

Quelques explications:

try-exceptest utilisé pour s'assurer que les deux xet les ycoordonnées sont dans les limites. Une exception sera levée lors de l'accès à G[y][x]. Python est trop bon et les indices négatifs sont acceptables, donc une vérification x>-1<yest ajoutée.

T=[r[:]for r in G]utilisé pour créer une copie des Gvaleurs par

~-i/2et ~-(i^2)/2sont utilisés pour générer des paires (-1, 0), (0, 1), (0, -1), (1, 0), qui se déplaçaient dans la grille (il devrait toujours y avoir un chemin plus court!)

R+=[G]*(0==c<'$'==G[y][x])vérifier, qui '$'est atteint en nombre d'étapes requis. Rest utilisé pour obtenir ce résultat à partir d'appels de fonction récursifs.

for i,y in enumerate(G):"@"in y>S(y.index("@"),i,G,L,R)Trouvé xet yd' '@'en entrée et la fonction appel S.

print R[0] R peut contenir plus d'une solution, donc sortez juste en premier

Possum mort
la source
-4 octets
caird coinheringaahing
1
Vous pouvez enregistrer un octet en le remplaçant if G[y][x]=='$':par if'$'==G[y][x]:.
1
En fait, cette condition entière peut être remplacée par R+=(G[y][x]=='$')*(c==0)*[G]un autre octet.
1
Huh, je ne sais pas ce que je voyais. Vous pouvez enregistrer quelques octets dans la première condition avecif(x>-1<y)*(G[y][x]in' @'):
1
Un moyen plus court pour vous y+cmp(i%2,i/2)serait y+~-(i^2)/2; il pourrait bien être encore plus court.
Jonathan Allan
2

Python 2 , 264 261 251 249 octets

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

Essayez-le en ligne!

Chas Brown
la source
1
@Arnauld: Oups! J'ai un peu trop de fantaisie. Fixé.
Chas Brown