| Bytes | Lang | Time | Link |
|---|---|---|---|
| 348 | Python3 | 250331T172844Z | Ajax1234 |
| 256 | Python 2 | 180410T125158Z | Dead Pos |
| 249 | Python 2 | 180410T170143Z | Chas Bro |
| 171 | JavaScript ES6 | 180410T131110Z | Arnauld |
Python3, 348 bytes
E=enumerate
def f(b,n):
d={(x,y):v for x,r in E(b)for y,v in E(r)}
q=[(*i,[i],n,b)for i in d if'@'==d[i]]
for x,y,p,n,B in q:
if'$'==d[(x,y)]:
if 0==n:return B
continue
for X,Y,K in[(1,0,'v'),(0,1,'>'),(-1,0,'^'),(0,-1,'<')]:
if d.get(N:=(x+X,y+Y))in['$',' ']and n and N not in p:U=eval(str(B));U[N[0]][N[1]]=K;q+=[(*N,p+[N],n-1,U)]
Python 2, 310 256 bytes
Thanks @cairdcoinheringaahing for except:0 -3 bytes
Thanks @Mnemonic for -8 bytes
Thanks @JonathanAllan for -3 bytes
Thanks @ovs for -5 bytes
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]
Some explanation:
try-except is used to ensure, that both x and y coordinates are in boundaries. Exception will be raised upon access to G[y][x]. Python is too good and negative indices are acceptable, so check x>-1<y is added.
T=[r[:]for r in G] used to create copy of G by values
~-i/2 and ~-(i^2)/2 are used to generate pairs (-1, 0), (0, 1), (0, -1), (1, 0), that used to move in grid (there still should be shorter way!)
R+=[G]*(0==c<'$'==G[y][x]) check, that '$' is reached in required number of steps. R is used to get this result from recursive function calls.
for i,y in enumerate(G):"@"in y>S(y.index("@"),i,G,L,R) Found x and y of '@' in input and call function S.
print R[0] R might contain more that one solution, so output just first
Python 2, 264 261 251 249 bytes
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
JavaScript (ES6), 171 bytes
Takes input in currying syntax (a)(n). Outputs by modifying the input matrix.
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]=' '))
Commented
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()