diff --git a/utilities/javascript/binToInt.js b/utilities/javascript/binToInt.js new file mode 100644 index 00000000..c34a278d --- /dev/null +++ b/utilities/javascript/binToInt.js @@ -0,0 +1,15 @@ +// Does not handle negative binary numbers. +function binToInt(binary) { + let res = 0; + for (let i = 0; i < binary.length; i++) { + res = res * 2 + (+binary[i]); + } + return res; +} + +console.log(binToInt('0') === parseInt('0', 2) && parseInt('0', 2) === 0); +console.log(binToInt('1') === parseInt('1', 2) && parseInt('1', 2) === 1); +console.log(binToInt('10') === parseInt('10', 2) && parseInt('10', 2) === 2); +console.log(binToInt('11') === parseInt('11', 2) && parseInt('11', 2) === 3); +console.log(binToInt('101') === parseInt('101', 2) && parseInt('101', 2) === 5); +console.log(binToInt('1100011') === parseInt('1100011', 2) && parseInt('1100011', 2) === 99); diff --git a/utilities/javascript/binarySearch.js b/utilities/javascript/binarySearch.js index 8a656af0..9ce8b336 100644 --- a/utilities/javascript/binarySearch.js +++ b/utilities/javascript/binarySearch.js @@ -15,12 +15,12 @@ function binarySearch(arr, target) { return -1; } -console.log(binarySearch([1, 2, 3, 10], 1) === 0) -console.log(binarySearch([1, 2, 3, 10], 2) === 1) -console.log(binarySearch([1, 2, 3, 10], 3) === 2) -console.log(binarySearch([1, 2, 3, 10], 10) === 3) -console.log(binarySearch([1, 2, 3, 10], 9) === -1) -console.log(binarySearch([1, 2, 3, 10], 4) === -1) -console.log(binarySearch([1, 2, 3, 10], 0) === -1) -console.log(binarySearch([1, 2, 3, 10], 11) === -1) -console.log(binarySearch([5, 7, 8, 10], 3) === -1) +console.log(binarySearch([1, 2, 3, 10], 1) === 0); +console.log(binarySearch([1, 2, 3, 10], 2) === 1); +console.log(binarySearch([1, 2, 3, 10], 3) === 2); +console.log(binarySearch([1, 2, 3, 10], 10) === 3); +console.log(binarySearch([1, 2, 3, 10], 9) === -1); +console.log(binarySearch([1, 2, 3, 10], 4) === -1); +console.log(binarySearch([1, 2, 3, 10], 0) === -1); +console.log(binarySearch([1, 2, 3, 10], 11) === -1); +console.log(binarySearch([5, 7, 8, 10], 3) === -1); diff --git a/utilities/javascript/deepEqual.js b/utilities/javascript/deepEqual.js index 78eeb285..ec82255c 100644 --- a/utilities/javascript/deepEqual.js +++ b/utilities/javascript/deepEqual.js @@ -17,9 +17,8 @@ function deepEqual(val1, val2) { } // Object comparison. - if (typeof val1 === 'object' && typeof val2 === 'object') { - const keys1 = Object.keys(val1); - const keys2 = Object.keys(val2); + if (typeof val1 === 'object' && typeof val2 === 'object' && val1 !== null) { + const keys1 = Object.keys(val1), keys2 = Object.keys(val2); if (keys1.length !== keys2.length) { return false; } diff --git a/utilities/javascript/graphTopoSort.js b/utilities/javascript/graphTopoSort.js index 12a0903f..13468026 100644 --- a/utilities/javascript/graphTopoSort.js +++ b/utilities/javascript/graphTopoSort.js @@ -32,4 +32,4 @@ function graphTopoSort(numberNodes, edges) { return order.length == numberNodes ? order : []; } -console.log(graphTopoSort(3, [[0, 1], [0, 2]])) +console.log(graphTopoSort(3, [[0, 1], [0, 2]])); diff --git a/utilities/javascript/intToBin.js b/utilities/javascript/intToBin.js new file mode 100644 index 00000000..6d33e7e5 --- /dev/null +++ b/utilities/javascript/intToBin.js @@ -0,0 +1,19 @@ +// Does not handle negative numbers. +function intToBin(number) { + if (number === 0) { + return '0'; + } + let res = ''; + while (number > 0) { + res = String(number % 2) + res; + number = parseInt(number / 2, 10); + } + return res; +} + +console.log(intToBin(0) === 0..toString(2) && 0..toString(2) === '0'); +console.log(intToBin(1) === 1..toString(2) && 1..toString(2) === '1'); +console.log(intToBin(2) === 2..toString(2) && 2..toString(2) === '10'); +console.log(intToBin(3) === 3..toString(2) && 3..toString(2) === '11'); +console.log(intToBin(5) === 5..toString(2) && 5..toString(2) === '101'); +console.log(intToBin(99) === 99..toString(2) && 99..toString(2) === '1100011'); diff --git a/utilities/javascript/intervalsIntersect.js b/utilities/javascript/intervalsIntersect.js new file mode 100644 index 00000000..2c6d59a0 --- /dev/null +++ b/utilities/javascript/intervalsIntersect.js @@ -0,0 +1,17 @@ +// Interval: [start, end]. +function intervalsIntersect(a, b) { + return a[0] < b[1] && b[0] < a[1]; +} + +console.log(intervalsIntersect([1, 2], [3, 4]) === false); +console.log(intervalsIntersect([1, 2], [2, 4]) === false); +console.log(intervalsIntersect([1, 2], [1, 4]) === true); +console.log(intervalsIntersect([1, 2], [0, 4]) === true); +console.log(intervalsIntersect([1, 2], [0, 2]) === true); +console.log(intervalsIntersect([1, 2], [0, 1.5]) === true); +console.log(intervalsIntersect([3, 4], [1, 2]) === false); +console.log(intervalsIntersect([2, 4], [1, 2]) === false); +console.log(intervalsIntersect([1, 4], [1, 2]) === true); +console.log(intervalsIntersect([0, 4], [1, 2]) === true); +console.log(intervalsIntersect([0, 2], [1, 2]) === true); +console.log(intervalsIntersect([0, 1.5], [1, 2]) === true); diff --git a/utilities/javascript/intervalsMerge.js b/utilities/javascript/intervalsMerge.js new file mode 100644 index 00000000..795ca37a --- /dev/null +++ b/utilities/javascript/intervalsMerge.js @@ -0,0 +1,16 @@ +// Interval: [start, end]. +// Merges two overlapping intervals into one. +function intervalsMerge(a, b) { + return [Math.min(a[0], b[0]), Math.max(a[1], b[1])]; +} + +const deepEqual = require('./deepEqual'); + +console.log(deepEqual(intervalsMerge([1, 2], [1, 4]), [1, 4])); +console.log(deepEqual(intervalsMerge([1, 2], [0, 4]), [0, 4])); +console.log(deepEqual(intervalsMerge([1, 2], [0, 2]), [0, 2])); +console.log(deepEqual(intervalsMerge([1, 2], [0, 1.5]), [0, 2])); +console.log(deepEqual(intervalsMerge([1, 4], [1, 2]), [1, 4])); +console.log(deepEqual(intervalsMerge([0, 4], [1, 2]), [0, 4])); +console.log(deepEqual(intervalsMerge([0, 2], [1, 2]), [0, 2])); +console.log(deepEqual(intervalsMerge([0, 1.5], [1, 2]), [0, 2])); diff --git a/utilities/javascript/matrixClone.js b/utilities/javascript/matrixClone.js new file mode 100644 index 00000000..b3f3f996 --- /dev/null +++ b/utilities/javascript/matrixClone.js @@ -0,0 +1,18 @@ +function matrixClone(matrix, defaultValue) { + return matrix.map(row => { + return defaultValue === undefined ? row.slice(0) : Array(row.length).fill(defaultValue); + }); +} + +const deepEqual = require('./deepEqual'); + +// Test clone. +const a = [[1, 2], [1, 4]]; +console.log(deepEqual(matrixClone(a), [[1, 2], [1, 4]])); +a[0][0] = 4; +console.log(deepEqual(matrixClone(a), [[1, 2], [1, 4]]) === false); +console.log(deepEqual(matrixClone([[1]]), [[1]])); + +// Test clone with default value. +console.log(deepEqual(matrixClone([[1, 2], [1, 4]], 1), [[1, 1], [1, 1]])); +console.log(deepEqual(matrixClone([[1, 2], [1, 4]], null), [[null, null], [null, null]])); diff --git a/utilities/javascript/matrixTranspose.js b/utilities/javascript/matrixTranspose.js new file mode 100644 index 00000000..0418a426 --- /dev/null +++ b/utilities/javascript/matrixTranspose.js @@ -0,0 +1,11 @@ +function matrixTranspose(matrix) { + return matrix[0].map((col, i) => matrix.map(row => row[i])); +} + +const deepEqual = require('./deepEqual'); + +console.log(deepEqual(matrixTranspose([[1]]), [[1]])); +console.log(deepEqual(matrixTranspose([[1, 2]]), [[1], [2]])); +console.log(deepEqual(matrixTranspose([[1, 2], [1, 4]]), [[1, 1], [2, 4]])); +console.log(deepEqual(matrixTranspose([[1, 2, 3], [4, 5, 6]]), [[1, 4], [2, 5], [3, 6]])); + diff --git a/utilities/javascript/matrixTraverse.js b/utilities/javascript/matrixTraverse.js new file mode 100644 index 00000000..331a24e4 --- /dev/null +++ b/utilities/javascript/matrixTraverse.js @@ -0,0 +1,28 @@ +function traverse(matrix) { + const DIRECTIONS = [[0, 1], [0, -1], [1, 0], [-1, 0]]; + const rows = matrix.length, cols = matrix[0].length; + const visited = matrix.map(row => Array(row.length).fill(false)); + function dfs(i, j) { + if (visited[i][j]) { + return; + } + visited[i][j] = true; + DIRECTIONS.forEach(dir => { + const row = i + dir[0], col = j + dir[1]; + // Boundary check. + if (row < 0 || row >= rows || col < 0 || col >= cols) { + return; + } + // Valid neighbor check. + if (matrix[row][col] !== 1) { + return; + } + dfs(row, col); + }); + } + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + dfs(i, j); + } + } +}