### LeetCode 335. Self Crossing（貪吃蛇）

You are given an array x of `n` positive numbers. You start at point `(0,0)` and moves `x[0]` metres to the north, then `x[1]` metres to the west, `x[2]` metres to the south,`x[3]` metres to the east and so on. In other words, after each move your direction changes counter-clockwise.

Write a one-pass algorithm with `O(1)` extra space to determine, if your path crosses itself, or not.

Example 1:

```Given x = `[2, 1, 1, 2]`,
┌───┐
│   │
└───┼──>
│

Return true (self crossing)
```

Example 2:

```Given x = `[1, 2, 3, 4]`,
┌──────┐
│      │
│
│
└────────────>

Return false (not self crossing)
```

Example 3:

```Given x = `[1, 1, 1, 1]`,
┌───┐
│   │
└───┼>

Return true (self crossing)```

```public class Solution {
public boolean isSelfCrossing(int[] x) {
if (x == null || x.length < 4) return false;
int[] rows = new int[6];
int[] cols = new int[6];
for(int i=0; i<x.length; i++) {
int nrow = rows[5], ncol = cols[5];
switch (i%4) {
case 0: nrow -= x[i]; break;
case 1: ncol -= x[i]; break;
case 2: nrow += x[i]; break;
case 3: ncol += x[i]; break;
}

if (i >= 5) {
switch (i%4) {
case 0:
if (cols[0] <= ncol && ncol <= cols[1] && rows[5] >= rows[1] && rows[1] >= nrow) return true;
else break;
case 1:
if (rows[1] <= nrow && nrow <= rows[0] && cols[5] >= cols[1] && cols[1] >= ncol) return true;
else break;
case 2:
if (cols[1] <= ncol && ncol <= cols[0] && rows[5] <= rows[1] && rows[1] <= nrow) return true;
else break;
case 3:
if (rows[0] <= nrow && nrow <= rows[1] && cols[5] <= cols[1] && cols[1] <= ncol) return true;
else break;
}
}
if (i >= 3) {
switch (i%4) {
case 0:
if (cols[3] <= ncol && ncol <= cols[2] && rows[5] <= rows[3] && rows[3] <= nrow) return true;
else break;
case 1:
if (rows[2] <= nrow && nrow <= rows[3] && cols[5] >= cols[3] && cols[3] >= ncol) return true;
else break;
case 2:
if (cols[2] <= ncol && ncol <= cols[3] && rows[5] <= rows[2] && rows[2] <= nrow) return true;
else break;
case 3:
if (rows[3] <= nrow && nrow <= rows[2] && cols[5] <= cols[2] && cols[2] <= ncol) return true;
else break;
}
}
if (i==4 && ncol == 0 && rows[5] > 0 && nrow <= 0) return true;
rows[0] = rows[1];
rows[1] = rows[2];
rows[2] = rows[3];
rows[3] = rows[4];
rows[4] = rows[5];
rows[5] = nrow;
cols[0] = cols[1];
cols[1] = cols[2];
cols[2] = cols[3];
cols[3] = cols[4];
cols[4] = cols[5];
cols[5] = ncol;
}
return false;
}
}```

```public class Solution {
public boolean isSelfCrossing(int[] x) {
int[] row = new int[7];
int[] col = new int[7];
for(int i=0; i<x.length; i++) {
for(int j=0; j<6; j++) {
row[j]=row[j+1];
col[j]=col[j+1];
}
switch (i % 4) {
case 0:
row[6] = row[5] - x[i];
col[6] = col[5];
if (i >= 8 && col[0] <= col[5] && col[5] <= col[1] && row[6] <= row[0] && row[0] <= row[5]) return true;
if (i >= 4 && col[3] <= col[5] && col[5] <= col[2] && row[6] <= row[2] && row[2] <= row[5]) return true;
if (i == 4 && col[6] == 0 && row[6] <= 0) return true;
break;
case 1:
row[6] = row[5];
col[6] = col[5] - x[i];
if (i >= 5 && col[6] <= col[0] && col[0] <= col[5] && row[1] <= row[5] && row[5] <= row[0]) return true;
if (i >= 5 && col[6] <= col[2] && col[2] <= col[5] && row[2] <= row[5] && row[5] <= row[3]) return true;
break;
case 2:
row[6] = row[5] + x[i];
col[6] = col[5];
if (i >= 6 && col[1] <= col[5] && col[5] <= col[0] && row[5] <= row[0] && row[0] <= row[6]) return true;
if (i >= 6 && col[2] <= col[5] && col[5] <= col[3] && row[5] <= row[2] && row[2] <= row[6]) return true;
break;
case 3:
row[6] = row[5];
col[6] = col[5] + x[i];
if (i >= 7 && col[5] <= col[0] && col[0] <= col[6] && row[0] <= row[5] && row[5] <= row[1]) return true;
if (i >= 3 && col[5] <= col[2] && col[2] <= col[6] && row[3] <= row[5] && row[5] <= row[2]) return true;
break;
}
}
return false;
}
}```

```public class Solution {
public boolean isSelfCrossing(int[] x) {
int[] px = new int[6];
int[] py = new int[6];
int ny = 0;
int nx = 0;
for(int i = 0; i < x.length; i++) {
switch (i % 4) {
case 0:
ny -= x[i];
break;
case 1:
nx -= x[i];
break;
case 2:
ny += x[i];
break;
case 3:
nx += x[i];
break;
}
if (i == 3) {
if (px[3] <= px[0] && px[0] <= nx && py[1] <= ny && ny <= py[0]) return true;
} else if (i == 4) {
if (px[2] <= nx && nx <= px[1] && ny <= py[2] && py[2] <= py[4]) return true;
if (nx == px[1] && ny <= py[0] && py[0] <= py[4]) return true;
} else if (i > 4) {
switch (i % 4) {
case 0:
if (px[0] <= nx && nx <= px[1] && ny <= py[1] && py[1] <= py[5]) return true;
if (px[3] <= nx && nx <= px[2] && ny <= py[3] && py[3] <= py[5]) return true;
break;
case 1:
if (nx <= px[1] && px[1] <= px[5] && py[1] <= ny && ny <= py[0]) return true;
if (nx <= px[3] && px[3] <= px[5] && py[2] <= ny && ny <= py[3]) return true;
break;
case 2:
if (px[1] <= nx && nx <= px[0] && py[5] <= py[1] && py[1] <= ny) return true;
if (px[2] <= nx && nx <= px[3] && py[5] <= py[3] && py[3] <= ny) return true;
break;
case 3:
if (px[5] <= px[1] && px[1] <= nx && py[0] <= ny && ny <= py[1]) return true;
if (px[5] <= px[3] && px[3] <= nx && py[3] <= ny && ny <= py[2]) return true;
break;
}
}
if (i < 5) {
px[i + 1] = nx;
py[i + 1] = ny;
} else {
for(int j = 0; j < 5; j++) {
px[j] = px[j + 1];
py[j] = py[j + 1];
}
px[5] = nx;
py[5] = ny;
}
}
return false;
}
}```