Ścieżki i marnowanie czasu


22

Przesłanka

Ostatnio byłem około pół godziny wcześniej na spotkanie i postanowiłem zaczekać na zewnątrz. Stwierdziłem również, że wyglądałoby dziwnie, gdybym stał bez ruchu przed domem. Dlatego postanowiłem wybrać się na szybki spacer po ograniczonym obszarze. Doszedłem również do wniosku, że jeśli zacznę chodzić w kółko, będzie to oczywiste, że chodzę po okolicy. Zainspirowałem się więc do stworzenia pierwszego wyzwania Code Golf.

Specyfikacja

Otrzymasz listę, mapę obszaru, która będzie zawierać albo, " "albo "#"które reprezentują wolne przestrzenie i przeszkody. Wolne miejsca można przekroczyć tylko raz, a przejście zajmuje 1 minutę. Twoja początkowa pozycja będzie oznaczona "@"tradycją roguelike, a cel będzie reprezentowany przez, "$"ponieważ to właśnie tam stracisz. Otrzymasz również liczbę całkowitą, która będzie oznaczać, ile minut musisz marnować, zanim nie będziesz wyglądać, jakbyś się wtrącał. Kiedy wylądujesz na"$" , będzie to musiała być dokładna ilość minut (więc jeśli odliczałeś, będzie to 1 na sąsiedniej płytce, i być 0 na kafelku). Zawsze będzie możliwe dotarcie do celu. Twój program lub funkcja będzie musiała zwrócić listę pokazującą najkrótszą ścieżkę za pomocą <,>, ^ i v, aby przedstawić cztery możliwe kierunki.

Przykłady

Wkład:

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

i

5

Ouput:

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

Wkład:

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

i

7

Wydajność:

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

Wkład:

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

i

17

Wydajność:

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

Zasady

  • Obowiązują standardowe luki
  • Każdy kafelek można przesunąć tylko raz
  • Dokładna ilość czasu musi zostać spędzona na planszy
  • W przypadku wielu ścieżek musi być wyświetlana tylko jedna ścieżka
  • To jest pytanie do golfa, więc wygrywa najkrótsza odpowiedź
  • Zgodnie z pytaniem user202729 w komentarzach, możesz założyć prawidłowe dane wejściowe.

Dodaj komentarz, jeśli wymagane są dalsze wyjaśnienia


1
Czy jest zagwarantowane, że „zawsze będzie możliwe dotarcie do celu w określonym czasie ”?
user202729,

Tak, zawsze będzie sposób, nawet jeśli będzie zawiłe
LForchini 10.04.18

5
Witamy w PPCG! :) Ładne pierwsze wyzwanie.
Giuseppe,

Co się stało z pół minuty na każdym końcu ?! (nie trzeba nic zmieniać, jeśli nie jest to oczywiste)
Jonathan Allan

Odpowiedzi:


6

JavaScript (ES6), 171 bajtów

Pobiera dane wejściowe w składni curry (a)(n). Wyjścia poprzez modyfikację macierzy wejściowej.

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

Wypróbuj online!

Skomentował

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 bajtów

Dzięki @cairdcoinheringaahing za except:0-3 bajty
Dzięki @Mnemonic za -8 bajtów
Dzięki @JonathanAllan za -3
bajki Dzięki @ovs za -5 bajtów

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]

Wypróbuj online!

Niektóre wyjaśnienia:

try-exceptsłuży do zapewnienia, że ​​zarówno współrzędne , jak xi ywspółrzędne znajdują się w granicach. Wyjątek zostanie podniesiony po uzyskaniu dostępu do G[y][x]. Python jest zbyt dobry, a ujemne wskaźniki są dopuszczalne, więc x>-1<ydodaje się czek .

T=[r[:]for r in G]służy do tworzenia kopii Gwedług wartości

~-i/2i ~-(i^2)/2służą do generowania par (-1, 0), (0, 1), (0, -1), (1, 0), które poruszały się w siatce (droga powinna być krótsza!)

R+=[G]*(0==c<'$'==G[y][x])sprawdź, czy '$'osiągnięto wymaganą liczbę kroków. Rsłuży do uzyskania tego wyniku z rekurencyjnych wywołań funkcji.

for i,y in enumerate(G):"@"in y>S(y.index("@"),i,G,L,R)Znaleziony xi ystanowi '@'w funkcji wejścia i połączeń S.

print R[0] R może zawierać więcej niż jedno rozwiązanie, więc najpierw wypisz dane wyjściowe



1
Możesz zapisać bajt, zastępując if G[y][x]=='$':go if'$'==G[y][x]:.

1
W rzeczywistości cały ten warunek można zastąpić R+=(G[y][x]=='$')*(c==0)*[G]innym bajtem.

1
Nie jestem pewien, co widziałem. Możesz zapisać kilka bajtów w pierwszym stanie za pomocąif(x>-1<y)*(G[y][x]in' @'):

1
Krótsza droga dla ciebie y+cmp(i%2,i/2)byłaby y+~-(i^2)/2; może być jeszcze krótszy.
Jonathan Allan,

2

Python 2 , 264 261 251 249 bajtów

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

Wypróbuj online!


1
@Arnauld: Ups! Mam trochę za dużo fantazji. Naprawiony.
Chas Brown
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.