Skip to content

Commit

Permalink
--wip-- [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
amejiarosario committed Apr 4, 2020
1 parent 6da8c62 commit 88441c2
Show file tree
Hide file tree
Showing 13 changed files with 10,802 additions and 5,954 deletions.
74 changes: 74 additions & 0 deletions lab/exercises/10-mixed/critical-connections-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* @param {number} n
* @param {number[][]} connections
* @return {number[][]}
*/
function criticalConnections(n, connections) {
const critical = [];
const graph = buildGraph(n, connections);
// console.log({graph})

for (let i = 0; i < connections.length; i++) { // O(|E| * [|V|^3 + |V|^2|E|]) = O(|V|^3|E| + |V|^2|E|^2)
const link = connections[i];
if (isLinkCritical(link, graph)) {
critical.push(link);
}
}

return critical;
}

function buildGraph(n, connections) {
const graph = [...Array(n).keys()].reduce((map, i) => {
map.set(i, new Set());
return map;
}, new Map());

connections.forEach(([i, j]) => {
const iAdj = graph.get(i);
iAdj.add(j);
const jAdj = graph.get(j);
jAdj.add(i);
});

return graph;
}

function isLinkCritical(link, graph) { // DFS: O(|V|^2 * |E|+|V|) = O(|V|^3 + |V|^2|E|)
for (let i = 0; i < graph.size; i++) {
for (let j = 0; j < graph.size; j++) {
if (hasLink([i, j], link)) continue;
if (!isConnected(i, j, link, graph)) { // DFS: O(|E|+|V|)
// console.log({i, j, link});
return true;
}
}
}

return false;
}

function hasLink(a, b) {
return (a[0] === b[0] && a[1] === b[1]) || (a[0] === b[1] && a[1] === b[0]);
}

// DFS: O(|E|+|V|)
function isConnected(i, j, ignoreLink, graph, seen = new Set()) {
if (i === j) return true;
if (graph.get(i).has(j)) return true;

for (const adj of graph.get(i)) {
if (hasLink([i, adj], ignoreLink)) continue;

if (seen.has(adj)) continue;
seen.add(adj);

if (isConnected(adj, j, ignoreLink, graph, seen)) {
return true;
}
}

return false;
}

module.exports = criticalConnections;
6 changes: 6 additions & 0 deletions lab/exercises/10-mixed/critical-connections.data.js

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions lab/exercises/10-mixed/critical-connections.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @param {number} n
* @param {number[][]} connections
* @return {number[][]}
*/
function criticalConnections(n, connections) {
const graph = buildGraph(n, connections);
// console.log({graph})

return dfs(graph, 0);
}


function buildGraph(n, connections) {
const graph = [...Array(n).keys()].reduce((map, i) => {
map.set(i, new Set());
return map;
}, new Map());

connections.forEach(([i, j]) => {
const iAdj = graph.get(i);
iAdj.add(j);
const jAdj = graph.get(j);
jAdj.add(i);
});

return graph;
}

function dfs(graph, current, previous = null, rank = 1, group = []) {
let criticalLinks = [];
group[current] = rank;

for (const adj of graph.get(current)) {
if (adj === previous) continue;

if (!group[adj]) { // if not visited (and not in a group yet)
const links = dfs(graph, adj, current, rank + 1, group);
if (links.length) {
criticalLinks = criticalLinks.concat(links);
}
}

group[current] = Math.min(group[current], group[adj]);

if (group[adj] >= rank + 1) {
criticalLinks.push([current, adj]);
}
}

return criticalLinks;
}

module.exports = criticalConnections;
17 changes: 17 additions & 0 deletions lab/exercises/10-mixed/critical-connections.runner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const assert = require('assert');

// const criticalConnections = require('./critical-connections');
const criticalConnections = require('./critical-connections');
const data = require('./critical-connections.data');

assert.deepEqual(criticalConnections(4, [
[0, 1],
[1, 2],
[2, 0],
[1, 3],
]), [[1, 3]]);

const { n, connections } = data.test1000;
assert.deepEqual(criticalConnections(n, connections), []);

console.log('All tests passed!');
42 changes: 42 additions & 0 deletions lab/exercises/10-mixed/critical-connections.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// npx jest lab/exercises/10-mixed/critical-connections.spec.js --watch
const criticalConnections = require('./critical-connections');

describe('Critical Connections', () => {
it('should work with 4 nodes', () => {
const n = 4;
const connections = [
[0, 1],
[1, 2],
[2, 0],
[1, 3],
];
expect(criticalConnections(n, connections)).toEqual([
[1, 3],
]);
});

it('should work with nodes in line (all critical)', () => {
const n = 4;
const connections = [
[0, 1],
[1, 2],
[2, 3],
];
expect(criticalConnections(n, connections)).toEqual(expect.arrayContaining([
[0, 1],
[1, 2],
[2, 3],
]));
});

it('should work with nodes in daisy chain (no critical)', () => {
const n = 4;
const connections = [
[0, 1],
[1, 2],
[2, 3],
[3, 0],
];
expect(criticalConnections(n, connections)).toEqual(expect.arrayContaining([]));
});
});
89 changes: 89 additions & 0 deletions lab/exercises/10-mixed/integer-to-words.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// npx jest lab/exercises/10-mixed/integer-to-words.spec.js --watch

const map = {
0: 'Zero',
1: 'One',
2: 'Two',
3: 'Three',
4: 'Four',
5: 'Five',
6: 'Six',
7: 'Seven',
8: 'Eight',
9: 'Nine',
10: 'Ten',
11: 'Eleven',
12: 'Twelve',
13: 'Thirteen',
14: 'Fourteen',
15: 'Fifteen',
16: 'Sixteen',
17: 'Seventeen',
18: 'Eighteen',
19: 'Nineteen',
20: 'Twenty', // Twenty One

30: 'Thirty', // Thirty Four
40: 'Forty',
50: 'Fifty',
60: 'Sixty', // Sixty Seven
70: 'Seventy',
80: 'Eighty',
90: 'Ninety',
100: 'Hundred', // One Hundred, Two Hundred

1_000: 'Thousand', // Four Thousand

1_000_000: 'Million', // One Million

1_000_000_000: 'Billion', // One Billion
};

const keys = [
// 1_000_000_000,
// 1_000_000,
// 1_000,
// 100,
10,
];

/**
* @param {number} num
* @return {string}
* @pomodoro II
*/
function numberToWords(num) {
if (num < 21) return map[num];

let ans = [];
// let i = 0;

// while (num && i < keys.length) {
// // const div = keys[i++]; // 10
// const div = 10;
// const reminder = num % div; // 1
// const left = num - reminder; // 20

// if (left && map[left] !== undefined) {
// ans.push(map[left]);
// num -= left;
// }

// num = reminder;
// }
ans = ans.concat(numberToWords(Math.floor(num/10) * 10));
ans = ans.concat(numberToWords(Math.floor(num % 10)))

return ans.join(' ');
};

// convert a number into its English representation

// 21
// Twenty One

// 1_234_567_891

console.log(process.version);

module.exports = numberToWords;
12 changes: 12 additions & 0 deletions lab/exercises/10-mixed/integer-to-words.spec-assert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*eslint-disable */
const assert = require('assert');

const numberToWords = require('./integer-to-words');

assert.equal(numberToWords(0), 'Zero');
assert.equal(numberToWords(1), 'One');
assert.equal(numberToWords(20), 'Twenty');
assert.equal(numberToWords(21), 'Twenty One');
assert.equal(numberToWords(99), 'Ninety Nine');

console.log('All tests passed!');
7 changes: 7 additions & 0 deletions lab/exercises/10-mixed/integer-to-words.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const numberToWords = require('./integer-to-words');

describe('Integer to English Words', () => {
it('should convert 0', () => {
expect(numberToWords(0)).toEqual('Zero');
});
});
28 changes: 28 additions & 0 deletions lab/exercises/10-mixed/trapping-rain-water-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Compute how much water it is able to trap after raining.
* @param {number[]} height Non-negative integers representing
* an elevation map where the width of each bar is 1.
*
* @runtime O(n^2) - Brute force
* @space O(1)
*/
function trap(height) {
let ans = 0;

for (let i = 0; i < height.length; i++) {
let leftMax = 0;
let rightMax = 0;
for (let j = i; j >= 0; j--) {
leftMax = Math.max(leftMax, height[j]);
}
for (let j = i; j < height.length; j++) {
rightMax = Math.max(rightMax, height[j]);
}

ans += Math.min(leftMax, rightMax) - height[i];
}

return ans;
}

module.exports = trap;
28 changes: 28 additions & 0 deletions lab/exercises/10-mixed/trapping-rain-water.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Compute how much water it is able to trap after raining.
* @param {number[]} height Non-negative integers representing
* an elevation map where the width of each bar is 1.
*
* @runtime O(n) - using DP
* @space O(n)
*/
function trap(height) {
let ans = 0;
const leftMax = [];
const rightMax = [];

for (let j = height.length - 1; j >= 0; j--) {
leftMax[j] = Math.max((leftMax[j + 1] || 0), height[j]);
}
for (let j = 0; j < height.length; j++) {
rightMax[j] = Math.max((rightMax[j - 1] || 0), height[j]);
}

for (let i = 0; i < height.length; i++) {
ans += Math.min(leftMax[i], rightMax[i]) - height[i];
}

return ans;
}

module.exports = trap;
19 changes: 19 additions & 0 deletions lab/exercises/10-mixed/trapping-rain-water.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const trap = require('./trapping-rain-water');

describe('Trapping Rain Water', () => {
it('should trap', () => {
expect(trap([1, 0, 1])).toEqual(1);
});

it('should not trap', () => {
expect(trap([1, 1, 1])).toEqual(0);
});

it('should not trap', () => {
expect(trap([0, 0, 0])).toEqual(0);
});

it('should trap', () => {
expect(trap([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1])).toEqual(6);
});
});
Loading

0 comments on commit 88441c2

Please sign in to comment.