# JavaScript (ES6), ~~154~~ 134 bytes

```
m=>m.map((r,Y)=>r.map(g=(_,x,y,r=m[y=1/y?y:Y])=>r&&r[x]&&[-1,0,1,2].map(d=>r[r[x]=0,/1/.test(m)?g(_,x+d%2,y+~-d%2):++n,x]=1)),n=0)|n/4
```

Try it online!

## How?

### Method

Starting from each possible cell, we flood-fill the matrix, clearing all cells on our way. Whenever the matrix contains no more **1**'s, we increment the number **n** of possible paths.

Each valid path is counted 4 times because of the direction chosen on the last cell, which actually doesn't matter. Therefore, the final result is **n / 4**.

### Recursive function

Instead of calling the recursive function **g()** from the callback of the second **map()** like this...

```
m=>m.map((r,y)=>r.map((_,x)=>(g=(x,y,r=m[y])=>...g(x+dx,y+dy)...)(x,y)))
```

...we define the recursive function **g()** *directly as the callback* of **map()**:

```
m=>m.map((r,Y)=>r.map(g=(_,x,y,r=m[y=1/y?y:Y])=>...g(_,x+dx,y+dy)...))
```

Despite the rather long formula `y=1/y?y:Y`

which is needed to set the initial value of **y**, this saves 2 bytes overall.

### Commented code

```
m => // given the input matrix m[][]
m.map((r, Y) => // for each row r[] at position Y in m[][]:
r.map(g = ( // for each entry in r[], use g() taking:
_, // - the value of the cell (ignored)
x, // - the x coord. of this cell
y, // - either the y coord. or an array (1st iteration),
// in which case we'll set y to Y instead
r = m[y = 1 / y ? y : Y] // - r = the row we're currently located in
) => // (and update y if necessary)
r && r[x] && // do nothing if this cell doesn't exist or is 0
[-1, 0, 1, 2].map(d => // otherwise, for each direction d,
r[ // with -1 = West, 0 = North, 1 = East, 2 = South:
r[x] = 0, // clear the current cell
/1/.test(m) ? // if the matrix still contains at least one '1':
g( // do a recursive call to g() with:
_, // a dummy first parameter (ignored)
x + d % 2, // the new value of x
y + ~-d % 2 // the new value of y
) // end of recursive call
: // else (we've found a valid path):
++n, // increment n
x // \_ either way,
] = 1 // / do r[x] = 1 to restore the current cell to 1
) // end of map() over directions
), // end of map() over the cells of the current row
n = 0 // start with n = 0
) | n / 4 // end of map() over the rows; return n / 4
```

13Welcome to PPCG! Nice first challenge. – Laikoni – 2018-05-18T08:14:55.027

5Minor note: "There will always be at least one row and one column" is redundant, given that the snake will always have at least 2 blocks. – Stewie Griffin – 2018-05-18T09:17:45.683

1What's the correct output for a 3-by-3 square of 1's? One solution return 28, one returns 40. The last one times out, so I'm not sure what that would give... – Stewie Griffin – 2018-05-18T10:53:35.427

1Can the input have no possible answer and require a 0? – l4m2 – 2018-05-18T10:55:30.007

2Suggested test cases: the one given by @StewieGriffin and

`[[0,0,1,1],[0,0,1,1],[0,0,1,1]]`

. Most answers give 16, but one gives 15. – Kevin Cruijssen – 2018-05-18T11:01:21.5631

What's the expected output for this?

– Arnauld – 2018-05-18T12:54:13.1102It seems like everybody so far (including me) has made the assumption that 2 paths ending at different positions but otherwise looking exactly the same are

notthe same path. I think this needs to be explicitly specified. – Arnauld – 2018-05-18T13:16:46.3732@Arnauld - that’s right. Two paths ending at different positions but otherwise looking exactly the same

are not the same path, it’ll add up to the total. In your example the total should be 16 if I’m not mistaken - I can’t accuratelly calculate right now but you get the point – Adelin – 2018-05-18T13:42:19.133The last condition is equivalent to "paths are directed". – user202729 – 2018-05-18T15:19:46.663

Is it possible that the result is 0? (for example: input

`[[0,1,0],[1,1,1],[0,1,0]]`

) – user202729 – 2018-05-19T03:22:35.353@user202729 no, it’s not possible. You should always expect a valid snake. Actually all those notes I’ve written was so that you don’t need to validate the input yourself – Adelin – 2018-05-19T04:02:12.977

I edited the post to add that (because it's not deducible from the other facts) and also remove some redundant rules. – user202729 – 2018-05-19T04:09:10.283

@user202729 ok thanks but just so you know, with the minimum 2 blocks snake we can already have 2 paths (minimum) – Adelin – 2018-05-19T04:23:04.367

Are cycles counted multiple times? E.g. should [[1,1],[1,1]] return 2 or 8? – MooseBoys – 2018-05-19T05:14:43.423

@MooseBoys yes, multiple times, as they are unique paths nonetheless. That would be an 8 indeed – Adelin – 2018-05-19T05:15:47.620