/**
* function to resolve islands
* @param {Array} map - the world map we provide
* @param {Array} islands - 2D array considiting of island arrays each
* holding island coordinates. Defaults to []
* @return {Array} islands - "
**/
function resolveIslands(map, islands = []){
/**
* function to take a coordinate and split 4 neighboring coordinates into 1s and 0s
* @param {Number} r - 0 indexed row value
* @param {Number} c - 0 indexed column value
* @return {Array} - coordinates of 0s and 1s split in the form of [[0s],[1s]]
* */
function splitRoutes(r,c){
return [[r-1,c],[r,c-1],[r+1,c],[r,c+1]].reduce((p,[r,c]) => map[r] === void 0 ||
map[r][c] === void 0 ? p
: map[r][c] ? (p[1].push([r,c]),p)
: (p[0].push([r,c]),p), [[],[]]);
}
/**
* function to take a coordinate and solve the island if the coordinate is 1
* @param {Number} r - 0 index row value
* @param {Number} c - 0 index column value
* @param {Array} island - An array of arrays of coordinates representing the
currently resolved island
* @param {Number} oc - The number of 1s in da hood
* @param {Array} tz - Gradually becoming all available zeros in the map
initially []
* @return {Undefined} - Full of side effects :)
* */
function scan(r, c, island = [], oc = 0, tz = []){
var [toZeros,toOnes] = splitRoutes(r,c);
tz.push(...toZeros);
switch (map[r][c]) {
case 1: !island.length && islands.push(island);
oc += toOnes.length;
map[r][c] = void 0;
island.push([r,c]);
toOnes.forEach(([r,c]) => scan(r,c,island,--oc,tz));
!oc && tz.forEach(([r,c]) => map[r][c] === 0 && scan(r,c,island,oc,tz));
break;
case 0: map[r][c] = void 0;
toOnes.forEach(([r,c]) => map[r][c] === 1 && scan(r,c));
tz.forEach(([r,c]) => map[r][c] === 0 && scan(r,c));
break;
}
}
scan(0,0);
return islands;
}
let arr = [[1, 0, 1],
[1, 0, 0],
[1, 1, 1]
],
brr = [[1, 0, 1, 1, 1],
[0, 1, 0, 0, 1],
[1, 0, 1 ,1, 0],
[0, 0, 0, 0, 1],
[1, 1, 0, 1, 1]
];
console.log(JSON.stringify(resolveIslands(arr)));
console.log(JSON.stringify(resolveIslands(brr)));