Can the cursor reach the bottom?
APL (Dyalog Unicode), 60 bytesSBCS
Full program. Prompts for character matrix from stdin. Prints 1 or 0 to stdout. Requires zero-indexing (⎕IO←0
) which is default on many systems.
P←{' '0∊⍨s←(×⍨≢⍺)⊃,⍵:1∊⍵⋄s}
1∊⊢⌿{P⌺3 3⊢(⍴⍵)⍴1@0P⌺3,⍵}⍣≡3/3⌿⎕
Try it online! (space characters replaced by ░
for clarity)
The method here is basically to seed fill from the top left corner, but alternating between 1D and 2D seed fill to account for line wrapping and vertical/diagonal motion. Diagonal motion is simple horizontal motion followed by vertical motion, since the cursor sits in between adjacent characters.
The first line defines a helper function P
(rocess) which will be called on each neighbourhood.
P←{
…}
"dfn"; ⍵
is the neighborhood, ⍺
is the number of padded elements for each dimension:
,⍵
ravel (flatten) the neighbourhood into a list
(
…)⊃
pick the following element from that:
⍺
the paddings per dimension (so a 1 or 2 element list, depending on ⍵
being 1D or 2D)
≢
the tally of that (1 or 2)
×⍨
the square of that (lit. multiplication selfie; 1 or 4)
s←
assign to s
(elf; i.e. the centre of the neighbourhood)
' '0∊⍨
is that a member of [" ",0]
?
:
if so:
1∊⍵
return whether the neighbourhood has a one
⋄
else:
s
return s
(elf unmodified, i.e. leave as-is for now)
The second line is the main part of the program:
⎕
prompt for evaluated input via the console (stdin)
3⌿
triplicate each row (ensures we have at least 3 — makes no difference to connectivity)
3/
triplicate each column (ensures we have at least 3 — makes no difference to connectivity)
{
…}⍣≡
apply this function repeatedly until two successive results are identical (i.e. until stable):
,⍵
ravel (flatten) the matrix into a list
P⌺3
apply P
to each neighbourhood of 3 elements
1@0
replace the current value at position 0
with a 1
(this seeds the top left corner)
(
…)⍴
reshape that into the following shape:
⍴⍵
the original shape of the matrix
⊢⌿
get the bottom row (lit. vertical right-reduction)
1∊
is there any 1
there?
Jelly, 47 43 bytes
p®§Qæ%L}>Ƈ0ịƇ
=⁶oŻ$€µZL;1;N$©ṛF1çƬFṀ’:®Ḣ‘=L
Try it online!
A full program that takes a list of strings as its argument and returns 1 if the bottom line is reachable and 0 if not.
Explanation
Helper link
Test moves up, down left and right and extend reachable position list. Left argument: most recently added reachable position list; right argument: boolean list of whether each possible position is valid
p® | Cartesian product with each of the values stored in the register (the width of the position list, 1 and the negation of each)
§ | Sum each of these
F | Flatten
Q | Uniquify
æ%L} | Symmetric mod using the length of the valid position list: this will mean any positions that move off the top or bottom will be negative
>Ƈ0 | Filter out those reachable positions which are negative
ịƇ | Filter out those which are invalid
Main link
Takes a single argument, a list of Jelly strings representing the grid
=⁶ | Check of equal to space
oŻ$€ | Logical or each row with itself prepended with zero; this yields rows 1 longer, and will indicate whether each cursor position is valid
µ | Start a new monadic chain
ZL | Zip and get the length (will be the length of each row)
;1 | Concatenate 1
;N$© | Concatenate the negations and store in the register (i.e. width, 1, -width, -1)
ṛF | Replace with the flattened grid of position validity
1çƬ | Call the helper link, starting with 1 as left argument and using the flattened position validities as right. Repeat until unchanged. Return all collected values.
F | Flatten, getting all reachable positions (may include duplicates)
Ṁ | Maximum position reached
’ | Decrease by 1 (because of 1-indexing)
:® | Integer divide by the register
Ḣ | Head (will effectively be max position integer divided by width)
‘ | Increase by 1
=L | Check if equal to length (i.e. height) of position grid