Python 2, 236 235 227 212 bytes
def f((x,y),G,M,U=[]):
R=1-(len(M[0])-1>x>0<y<len(M)-1);H=[(u+cmp(x,u),v+cmp(y,v)*(u==x))for u,v in G];d,e=0,1
for _ in' '*4*(R<1>((x,y)in H)):J=z,w=x+d,y+e;d,e=-e,d;R|=M[w][z]>(J in U)<f(J,H,M,U+[J])
return R
-15 bytes thx to Bubbler
As input, takes a tuple (x,y)
as jimmy's initial position, a list G == [(g1x,g1y), ...]
of initial ghost positions, and a list of lists M
which is the 2-dimensional binary matrix where cells are 0
if they contain "an object" (i.e., #
) and 1
otherwise.
Returns 1
for truthy, 0
for falsey.
Loosely speaking, the idea here is that we're going to depth-first recurse over down, left, up, right to seek a border cell. To start,
R=1-(len(M[0])-1>x>0<y<len(M)-1)
R
is truthy if jimmy starts on a border cell. We could just return R
if he does, but that would add an additional return
. So in any case, we calculate where the ghosts would move to next.
H=[(u+cmp(x,u),v+cmp(y,v)*(u==x))for u,v in G]
cmp(a,b)
returns the sign of a-b
as -1,0,1
; so this updates the ghosts positions with preference for horizontal movement if possible. Next,
for _ in' '*4*(R<1>((x,y)in H)):
executes a loop 4 times (' '*4
is shorter than range(4)
),. Note that if jimmy is not on the boundary (not R<1
) and no ghosts haveor a ghost has landed on jimmy (not 1>((x,y)in H
), then we skip the for loop and so we return 1
if jimmy has escaped, or 0
if a ghost got him.
J=z,w=x+d,y+e;d,e=-e,d
d,e
is the offset to jimmy's next position, starting as 0,1
; and each time through the loop, d,e=-e,d
rotates us through the 4 possible orthogonal positions.
R|=M[w][z]>(J in U)<f(J,H,M,U+[J])
R
gets set to truthy if jimmy's next position J
is not an on "object" (M[w][z]>0
), AND we haven't visited this position before (1>(J in U)
), AND via recursion, jimmy can escape starting at position J
with ghosts at H
(0<f(J,H,M,U+[J])
).