[Question]
  [
## Background
One kind of river-crossing problems involves two kinds of animals. One such problem reads like this: (all wordings, including animal species, are arbitrary)
> 
> A farmer has to cross a river with three chickens and three dogs. There's a boat which can only fit the farmer and at most two animals. On either side of the river, if both kinds of animals are present and the dogs outnumber the chickens at any moment, the dogs will kill the chickens. Also, for some reason, the farmer can't cross the river alone. Can the farmer safely cross the river with all his animals? (For the sake of the puzzle, assume that all animals land on the destination side before the next turn.)
> 
> 
> Bonus: What if the farmer had four of each kind of animals?
> 
> 
> 
whose answer is
> 
> Yes:
> 
> 
> ```
> üêîüêîüêîüêïüêïüêï |          |
>                 üêïüêï->
> üêîüêîüêîüêï     |          | üêïüêï
>                 <-üêï
> üêîüêîüêîüêïüêï   |          | üêï
>                 üêïüêï->
> üêîüêîüêî       |          | üêïüêïüêï
>                 <-üêï
> üêîüêîüêîüêï     |          | üêïüêï
>                 üêîüêî->
> üêîüêï         |          | üêîüêîüêïüêï
>                 <-üêîüêï
> üêîüêîüêïüêï     |          | üêîüêï
>                 üêîüêî->
> üêïüêï         |          | üêîüêîüêîüêï
>                 <-üêï
> üêïüêïüêï       |          | üêîüêîüêî
>                 üêïüêï->
> üêï           |          | üêîüêîüêî üêïüêï
>                 <-üêï
> üêïüêï         |          | üêîüêîüêî üêï
>                 üêïüêï->
>              |          | üêîüêîüêî üêïüêïüêï
> ```
> Bonus: No.
> 
> 
> 
> 
> 
One way to solve this puzzle is to construct a grid like this: `O` indicates that the dog-chicken combination is allowed on the initial side (and the rest on the opposite side); `X` means not allowed.
```
üêï\üêî| 0 1 2 3
-----+---------
  0  | O X X O
  1  | O O X O
  2  | O X O O
  3  | O X X O
```
Then the problem is about going from (3,3) to (0,0) with alternating forward-backward moves (using NSEW for one step in each cardinal direction):
* Forward: one of N, W, NN, WW, or NW
* Backward: one of S, E, SS, EE, or SE
The solution in the spoiler box follows the path below:
```
(3,3) NN -> (1,3)
      S  -> (2,3)
      NN -> (0,3)
      S  -> (1,3)
      WW -> (1,1)
      SE -> (2,2)
      WW -> (2,0)
      S  -> (3,0)
      NN -> (1,0)
      S  -> (2,0)
      NN -> (0,0)
```
## Challenge
Given a rectangular grid of valid states as shown above, determine whether the river-crossing puzzle has a solution or not, i.e. a forward-backward alternating path exists between the top left corner and the bottom right corner.
The input has at least two rows and columns, but it may or may not be a square. The O's and X's in the input may be represented using any two distinct constant values (e.g. booleans, numbers, strings). You may assume the start and end corners are both O's.
For output, you can choose to
* output truthy/falsy using your language's convention (swapping is allowed), or
* use two distinct, fixed values to represent true (affirmative) or false (negative) respectively.
Standard [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") rules apply. The shortest code in bytes wins.
## Test cases
The test cases use 1 and 0 for O and X respectively.
### Truthy
```
[[1, 0],
 [0, 1]]
[[1, 1, 1],
 [1, 1, 1],
 [1, 1, 1]]
[[1, 1, 0],
 [0, 1, 1]]
[[1, 0, 1, 1, 1, 0, 1],
 [1, 1, 1, 0, 1, 1, 1]]
[[1, 1, 1],
 [0, 0, 1],
 [0, 0, 1]]
[[1, 0, 1, 1, 1],
 [1, 0, 0, 0, 1],
 [1, 1, 1, 0, 1]]
[[1, 0, 0, 1],
 [1, 1, 0, 1],
 [1, 0, 1, 1],
 [1, 0, 0, 1]]
```
### Falsy
```
[[1, 0, 0],
 [0, 0, 1]]
[[1, 0, 1],
 [1, 0, 1]]
[[1, 1, 0],
 [1, 0, 1]]
[[1, 0, 0, 0, 1],
 [1, 1, 0, 0, 1],
 [1, 0, 1, 0, 1],
 [1, 0, 0, 1, 1],
 [1, 0, 0, 0, 1]]
```
Related: [Wolves and Chickens](https://codegolf.stackexchange.com/q/96861/78410) (bonus: can you exploit the strategy to golf the linked challenge further?)
  
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 97 bytes
Saved 6 bytes thanks to [@att](https://codegolf.stackexchange.com/users/81203/att).
```
FindPath[Pick[e@@#<->#2,0<=Min[d=#2-#]<Tr@d<3]&@@@#~Tuples~2,1~e~1,Last@#]~FreeQ~{}&@*Position[1]
```
[Try it online!](https://tio.run/##dVCxCsIwFPyVB4EOkmJS17ZkclKo4BYylDbFoFZp4xSSX68Wraakwhsul7t7l1xLfZLXUquqHBrIhq1q6@LF8UJVZy4ZQ2mcowSTNNurltcZSmIk0mPH6nQjIvYSuOPjfpG9SzB10lG8K3vNkHDbTsqDMzZiq@LWK61uLadiKDrVao4gzqHhSAiIYM3AGEMxEIvBEAzUjmBkxhnxAvQkX5/Pf85vwdzrXwaryE8@wTDyE0amCdN901xAZv4gbe78V8MLCH5iuUFQIuhBgiqLL7V2eAI "Wolfram Language (Mathematica) ‚Äì Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 88 bytes
```
‚äûœÖ‚äñ‚ü¶‚Å∞Ôº¨Œ∏Ôº¨¬ßŒ∏‚Å∞‚üßÔº¶Œ∏Ôº¶¬≤‚äûŒπ‚Å∞Ôº¶¬≤‚äûŒ∏Ôº•¬ßŒ∏‚Å∞¬¶‚Å∞Ôº¶œÖÔº¶¬≥Ôº¶¬≥¬´‚âîÔº•Œπ‚éáŒΩ‚Å∫Œº√ó¬ßŒπ‚Å∞‚éá‚äñŒΩŒªŒ∫¬±ŒºŒ∑¬ø‚àß‚à®Œ∫Œª‚àß‚Ä∫¬≥‚Å∫Œ∫Œª‚Ä∫¬ß¬ßŒ∏¬ßŒ∑¬π¬ßŒ∑¬≤‚ÑñœÖŒ∑¬´‚äûœÖŒ∑¬¨‚åàŒ¶Œ∑ŒΩ
```
[Try it online!](https://tio.run/##VVFNb4MwDD3Dr/DRkTKpH8ed0KZOk7aOw26IA6IpiUrCGsjUaepvZ04gLUOWYj8/P@eFWla27qp2HHPXS3QcnkVthRZmEAcsVhzehGkGiWd2S7Ph1RzEBc8cVoyVjD2mx84CUSCcGwZBTPn@3IsYzbxXX/8lgszMc7PG9n7@pknW96ox6CdJ9FNYU9kfNBzy1vWoCVJa9DdVNalG3tKRIbzlcGKMkr1oqkGgDoWkKyTqCJiZA35YPBGRYF@9WEE8i9t5YWhRL@Jx78JVTCWHtacu6o2vnzpnBv/ckvnPm0ziHwg3SXKriLHvBrJ9Udpp3KnWbyMJ42eIdE2v41gUxZoM06IpSp4CzNAUd2iKAJXl@PDd/gE "Charcoal ‚Äì Try It Online") Link is to verbose version of code. Outputs `-` if a solution exists, nothing if not. Explanation:
```
‚äûœÖ‚äñ‚ü¶‚Å∞Ôº¨Œ∏Ôº¨¬ßŒ∏‚Å∞‚üß
```
Start a breadth-first search with the initial position of the next move from the bottom right corner being a "forward" move.
```
Ôº¶Œ∏Ôº¶¬≤‚äûŒπ‚Å∞Ôº¶¬≤‚äûŒ∏Ôº•¬ßŒ∏‚Å∞¬¶‚Å∞
```
Pad the input with two rows and columns of zeros.
```
Ôº¶œÖÔº¶¬≥Ôº¶¬≥¬´
```
Consider all moves from all positions plus some illegal moves at this point.
```
‚âîÔº•Œπ‚éáŒΩ‚Å∫Œº√ó¬ßŒπ‚Å∞‚éá‚äñŒΩŒªŒ∫¬±ŒºŒ∑
```
Calculate the resulting position from this move, adjusted for "forward" and "reverse".
```
¬ø‚àß‚à®Œ∫Œª‚àß‚Ä∫¬≥‚Å∫Œ∫Œª‚Ä∫¬ß¬ßŒ∏¬ßŒ∑¬π¬ßŒ∑¬≤‚ÑñœÖŒ∑¬´
```
If the move is legal (i.e. one of NN, NW, N, WW or W for "forward" and equivalently for "reverse"), and the resulting position is legal and as yet unknown, then:
```
‚äûœÖŒ∑
```
Add the position to the list of known positions.
```
¬¨‚åàŒ¶Œ∑ŒΩ
```
Output a `-` if this position is in fact the top left.
[Answer]
# JavaScript (ES6), 112 bytes
Expects a matrix of 0's and 2's, for `'X'` and `'O'` respectively. Returns 0 or 2.
```
f=(m,x=0,y=0,i=1,r=m[y]||0)=>(r[x]--&&[1,2,4,5,8].some(d=>r[x+1]+1||m[y+1]?f(m,x+i*d%4,y+i*(d>>2),-i):1))*++r[x]
```
[Try it online!](https://tio.run/##dVDLboMwELzzFdtIBTsYZFCqVqlMTs0PpDfHBwQmccUjNSQKKv12Cm2jkkCltbze2Zmd9Vt4CstIq0Pl5EUs2zZhKCNnRkndHcU8olnGa9E0FLMAaX4WjmOa3CM@WZAH8iTcssgkilnQYbYnbK9pOkKXrZJeyVbz@H5B6u5GcRD4mDgKLz2M57bdq7Vavh@VlshKSgu7WobxWqVyU@cRotitik2lVb5D2C0PqarQbJtv8xl2k0K/hNEeoZKAwsAC@DAAUllBBgzkKUxRiZ@7kgLG4BFWEBV5WaTSTYsdsrY5X4dpWQsLwxLuFJjmdQN/1cdq3@O9yBDq1sJd8RO3nPsEqCAGcErAF8Iwvkt9fFen8kHTH3UI/L5/Om7YQ3Q8jg4Il3ysetGjl5iYMKTddNBribHiNflfM0ON8adM@xhbGbuhY0PTS4sv "JavaScript (Node.js) ‚Äì Try It Online")
### Commented
```
f = (                     // f is a recursive function taking:
  m,                      //   m[]    = input matrix
  x = 0, y = 0,           //   (x, y) = current position
  i = 1,                  //   i      = direction (1 for S/E, -1 for N/W)
  r = m[y] || 0           //   r[]    = current row
) => (                    //
  r[x]--                  // decrement r[x]
  &&                      // abort if it was 0 or undefined
  [1, 2, 4, 5, 8]         // otherwise, for each value d
  .some(d =>              // in [1, 2, 4, 5, 8]:
    r[x + 1] + 1 ||       //   if there's either a cell on our right
    m[y + 1] ?            //   or below us:
      f(                  //     do a recursive call:
        m,                //       pass m[]
        x + i * d % 4,    //       update x to x + i * (d mod 4)
        y + i * (d >> 2), //       update y to y + i * (d >> 2)
        -i                //       invert the direction
      )                   //     end of recursive call
    :                     //   else (we've reached the bottom-right corner):
      1                   //     success
  )                       // end of some()
) * ++r[x]                // restore r[x]
```
]