Java 8, 421 408 403 bytes
int M[][],v[][],l,L;m->{int i=(l=m.length)*(L=m[0].length);for(M=m,v=new int[l][L];;)if(m[--i%l][i/l]==65)return f(i%l,i/l,-1>>>1,-1);};int f(int x,int y,int r,int d){if(M[x][y]>65)return r>d?d:r;d+=v[x][y]=1;r=v(x+1,y)?f(x+1,y,r,d):r;r=v(x,y+1)?f(x,y+1,r,d):r;r=v(x-1,y)?f(x-1,y,r,d):r;r=v(x,y-1)?f(x,y-1,r,d):r;v[x][y]=0;return r;}boolean v(int x,int y){return x<l&y<L&x>=0&y>=0&&M[x][y]>32&v[x][y]<1;}
-5 bytes thanks to @ceilingcat.
Input as a matrix of bytes, with A
as start and B
as finish.
Try it online.
Explanation:
int M[][], // Matrix on class-level, starting uninitialized
v[][], // Visited matrix on class-level, starting uninitialized
l,L; // x and y dimensions, starting uninitialized
m->{ // Method with integer-matrix as input and integer as return
int i=(l=m.length) // Set `l` to the amount of rows
*(L=m[0].length); // Set `L` to the amount of columns
// And set `i` to the product of the two
for(M=m, // Set `M` to the input-matrix
v=new int[l][L]; // Create the visited-matrix filled with 0s
;) // Loop indefinitely:
if(m[--i%l][i/l]==65) // If the current cell contains an 'A':
return f( // Start the recursive method with:
i%l,i/l, // The current cell as the starting x,y-coordinate
-1>>>1, // Integer.MAX_VALUE as starting minimum-distance
-1);} // And -1 as amount of steps
int f(int x,int y,int r,int d){
// Create the recursive method
if(M[x][y]>65) // If the current cell contains 'B':
return r>d?d:r; // Return the minimum of the min-distance and amount of steps
d+=v[x][y]=1; // Mark the current cell as visited
d++; // And increase the amount of steps by 1 at the same time
r=v(x+1,y)? // If we can travel south:
f(x+1,y,r,d):r; // Set the min-distance to a recursive call southwards
r=v(x,y+1)? // If we can travel east:
f(x,y+1,r,d):r; // Set the min-distance to a recursive call eastwards
r=v(x-1,y)? // If we can travel north:
f(x-1,y,r,d):r; // Set the min-distance to a recursive call northwards
r=v(x,y-1)? // If we can travel west:
f(x,y-1,r,d):r; // Set the min-distance to a recursive call westwards
v[x][y]=0; // Unmark the current cell as visited
return r;} // And return the amount of steps as result
boolean v(int x,int y){ // Method to check whether we can travel to the given cell
return x<l&y<L&x>=0&y>=0// If the x,y-coordinate is within the matrix boundaries
&&M[x][y]>32 // Check that the current cell does NOT contain a space
&v[x][y]<1;} // And we haven't visited this cell yet
Shouldn't
##
output 0? What should output for##\n++
? – tsh – 2019-10-29T08:44:23.523@tsh Assume they aren't touching – Redwolf Programs – 2019-10-29T12:33:22.837
May we use different ascii characters for start and end? – Jitse – 2019-10-29T13:12:01.447
@Jitse Sure, I guess. I'll update the rules to allow that – Redwolf Programs – 2019-10-29T13:27:55.717
Can you include a test case where the end points are not on the edges? – Jitse – 2019-10-30T10:36:00.627
@Jitse Okay. Didn't even notice I'd forgotten that (: – Redwolf Programs – 2019-10-30T12:47:23.860
Thanks! It seems that for your new example the shortest path is 2 and not 4, though. – Jitse – 2019-10-30T13:03:43.627
@Jitse facepalm I'll fix that – Redwolf Programs – 2019-10-30T18:57:31.730