Skip to content

Instantly share code, notes, and snippets.

@daftAnorak
Last active February 2, 2023 03:51
Show Gist options
  • Save daftAnorak/2554c2e50817347652fc10cfeea567dd to your computer and use it in GitHub Desktop.
Save daftAnorak/2554c2e50817347652fc10cfeea567dd to your computer and use it in GitHub Desktop.
Code Exercise for JS Role - Remove islands from an image matrix
/**
* creates key from coordinates (for mapping)
* @param {number} r - row number
* @param {number} c - column number
*
* @returns {string} string key
*/
const toKey = (r, c) => `${r}|${c}`;
/**
* converts string key back to rows/column
*
* @param {string} str - string key
*
* @returns {[number, number]} - row and column
*/
const toCoord = (str) => str.split('|').map(Number);
/**
* Determinitate for point being on the border of a given matrix
*
* @param {number[][]} matrix
* @param {number} row
* @param {number} col
*
* @returns {boolean} is row/col combo a border point in matrix
*/
function isBorderPoint(matrix, row, col) {
return !row ||
!col ||
row === matrix.length - 1 ||
col === matrix[0].length - 1;
}
/**
* Recursive connector lookup which determines if given point (rows/cols) is
* NOT an island connection.
*
* @param {number[][]} matrix
* @param {number} row
* @param {number} col
* @param {object} current
*
* @returns {void} updates 'current' map
*/
function getConnections(matrix, row, col, current) {
// add key
current[toKey(row, col)] = true;
const connections = [
// top
[row - 1, col],
// right
[row, col + 1],
// bottom
[row + 1, col],
// left
[row, col - 1],
];
connections
.filter(([r, c]) => matrix[r] && matrix[r][c] && !current[toKey(r, c)])
.forEach(([r, c]) => {
getConnections(matrix, r, c, current);
});
}
/**
* Recreates image matrix (1 and 0), removing 1s which are islands; 1s not
* connected continually via other 1s to the border
*
* @example
* 0 0 0 1 0
* 0 0 0 1 0
* 1 1 0 0 0
* 1 0 1 1 0
* 1 0 0 0 0
*
* becomes:
*
* 0 0 0 1 0
* 0 0 0 1 0
* 1 1 0 0 0
* 1 0 0 0 0
* 1 0 0 0 0
*
* @param {number[][]} imageMatrix - original image matrix
*
* @returns {number[][]} new image matrix without isolated 1s (islands)
*/
function removeIslands(imageMatrix) {
const oneCoords = {};
const newMatrix = [];
let rows = imageMatrix.length;
// loop through image matrix, creating new matrix (all zeroes)
while (rows--) {
let cols = imageMatrix[rows].length;
newMatrix[rows] = [];
while (cols--) {
newMatrix[rows][cols] = 0;
if (imageMatrix[rows][cols] && isBorderPoint(imageMatrix, rows, cols)) {
// pass oneCoords to determine which coords should remain 1
getConnections(imageMatrix, rows, cols, oneCoords);
}
}
}
// loop through oneCoords to reimplement 1s we wish to keep
Object.keys(oneCoords).forEach((key) => {
const [r, c] = toCoord(key);
newMatrix[r][c] = 1;
});
return newMatrix;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment