| Bytes | Lang | Time | Link |
|---|---|---|---|
| 042 | Charcoal | 250703T065743Z | Neil |
| 234 | Maple | 250703T011340Z | dharr |
| 174 | Python 3 | 250703T081448Z | Jitse |
| 113 | JavaScript Node.js | 250702T092340Z | l4m2 |
| 052 | 05AB1E | 250702T080926Z | Kevin Cr |
Charcoal, 47 42 bytes
WS⊞υιP⪫υ¶→↓_Wⅉ«_W⁼KK#«↷²¶_»↶»≔I↨⌕KA Lθυ⎚→υ
Try it online! Link is to verbose version of code. Outputs y and x 0-indexed. Explanation:
WS⊞υιP⪫υ¶
Input the maze and write it to the canvas without moving the cursor.
→↓_
The robot starts at the entrance and moves down as its first step, but still implicitly faces right.
Wⅉ«
Repeat until the robot returns to the entrance.
_
Assume the robot can move.
W⁼KK#«
While the robot moved into a wall...
↷²¶_
... turn it right, sidestep it to its previous position, then try to move it in the new direction.
»↶
Turn the robot left.
»≔I↨⌕KA Lθυ
Find the co-ordinates of a safe hiding space.
⎚→υ
Remove the maze and output the co-ordinates. (Sadly resetting the canvas doesn't reset the output direction.)
Maple, 234 bytes
proc(M)c:=1,2;d:=1,0;L:=0,1;do M[c]++;if M[c+L]<>0 then c+=L;d:=L;L:=(Re,Im)(Complex(d)*I)elif M[c+d]<>0 then c+=d elif M[c-L]<>0 then c-=L;s:=d;d:=-L;L:=s else c-=d;d:=-d;L:=-L fi until c=(1,2);lhs(select(x->rhs(x)=1,op(2,M))[1])end;
Input is a Matrix with 0 for walls, 1 for spaces. x increases down, y increases to the right; output is x,y (1-relative). Maintains forward (d) and "left from here" (L) directions, e.g., 0,1 for right; -1,0 for up.
proc(M)
c:=1,2;d:=1,0;L:=0,1; # initial coords; direction facing; direction to left
do
M[c]++; # mark this space as visited
if M[c+L]<>0 then # space to left?
c+=L; # go left
d:=L; # update direction
L:=(Re,Im)(Complex(d)*I) # update L (90 deg ccw from d)
elif M[c+d]<>0 then # space ahead?
c+=d # go forward
elif M[c-L]<>0 then # space to right?
c-=L; # go right
s:=d;
d:=-L; # new direction
L:=s # new left
else
c-=d; # go backwards
d:=-d; # new direction
L:=-L # new left
fi
until c=(1,2); # back to start
lhs(select(x->rhs(x)=1,op(2,M))[1]) # coords of first 1
end;
Python 3, 174 bytes
def f(k,d=0,*s):w=k.find('\n')+1;*q,x=-w,-1,w,1,-w,-1,w,*s;return x<2and{i for i,c in enumerate(k)if' '==c}-{*s}or next(f(k,~-q.index(a)%4,*s,x+a)for a in q[d:]if' '==k[x+a])
Port of my answer to Find the shortest route on an ASCII road.
Takes a newline-separated string as input and returns all valid results as a single 0-indexed location in this string.
JavaScript (Node.js), 113 bytes
A=>(g=(q,p=x=y=1)=>y?+A[y-q][x+p]?g(-p,q):g(p,-q,A[y-=q][x+=p]=g):A.some((r,y)=>r.some((c,x)=>P=!c&&[y,x])))``&&P
Do the scan and find unscanned position
05AB1E, 52 bytes
˜ƶIgäΔ"4F¬ašøí}2Fø€ü3}*€€à"©.V}D®'*K.VZÊI_*εNUεiNX‚,
Now that I've finished this, I feel like it's the wrong/longer approach after all, but whatever.. 05AB1E isn't too suitable for most matrix challenges anyway.
Input as a matrix of bits with 1=wall and 0=space; outputs all safe 0-based \$[x,y]\$ index-pairs on separated newlines.
Try it online or verify all test cases.
Explanation:
Step 1: Flood-fill the input-matrix:
˜ # Flatten the (implicit) input-matrix to a list
ƶ # Multiply each value to its 1-based index
Ig # Push the amount of rows of the input-matrix
ä # Split the list into that many parts again
Δ # Loop until the matrix no longer changes to flood-fill:
"4F¬ašøí}2Fø€ü3}*€€à"
# Push this string
© # Store it in variable `®` (without popping)
.V # Pop and execute it as 05AB1E code:
4F¬ašøí} # Surround the matrix with a border of 0s:
4F } # Loop 4 times:
¬ # Push the first row (without popping the matrix)
a # Transform all its values to 0s with an is_letter check
š # Prepend that list of 0s to the matrix
øí # Rotate the matrix once clockwise:
ø # Zip/transpose; swapping rows/columns
í # Then reverse each inner row
2Fø€ü3} # Convert it into overlapping 3x3 blocks:
2F } # Loop 2 times:
ø # Zip/transpose; swapping rows/columns
€ # Map over each inner row
ü3 # Transform it into overlapping triplets
* # Multiply the 3x3 blocks to the values at the same positions of the
# (implicit) input-matrix, to correct all positions of the 0s
€€ # Nested map over each 3x3 block:
à # Pop and push the maximum
} # Close the until_changes-loop
Step 2: Do the same flood-fill step one more time, but without the * to correct the 0s:
D # Duplicate the flood-filled matrix
® # Push string `®`
'*K '# Remove the "*"
.V # Pop and execute it as 05AB1E code again
Try just steps 1 and 2 online.
Step 3: Mark all safe spots as 1s and everything else as 0s:
Step 3a: Remove the outer island of the matrix, which is the path the robot has walked including the outer walls itself:
Z # Push the maximum of the matrix (without popping)
# which is the value of the surrounding 'island' of the matrix
Ê # Check for each value in the matrix that it's not equal to this max
# (this will mark all inner islands and safe spots as 1s,
# and the surrounding island as 0)
Try just steps 1, 2, and 3a online.
Step 3b: Also remove all inner islands:
I # Push the input-matrix again
_ # Invert all bits
* # Multiply the values at the same positions
Try just steps 1, 2 and 3 online.
Step 4: Get all index-pairs of the remaining safe spots, and output those as result:
ε # Foreach over the rows:
NU # Store the current 0-based row-index in variable `X`
ε # Inner foreach over its cells:
i # If the current value is 1 (aka a safe spot):
NX‚ # Pair the 0-based cell-index with row-index `X`
, # Pop and output that pair with trailing newline