Skip to content

Commit 815e883

Browse files
committed
update
1 parent c844c03 commit 815e883

12 files changed

+1523
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
!.gitignore

binary-heap.js

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
class BinaryHeap {
2+
constructor(comparator = (a, b) => {
3+
return (a < b) ? -1 : (a === b ? 0 : 1);
4+
}) {
5+
this.heap = [];
6+
this.comparator = comparator;
7+
}
8+
getLeftIndex(index) {
9+
return 2 * index + 1;
10+
}
11+
getRightIndex(index) {
12+
return 2 * index + 2;
13+
}
14+
getParentIndex(index) {
15+
return Math.floor((index - 1) / 2);
16+
}
17+
insert(data) {
18+
if (data === undefined || data === null) {
19+
return false;
20+
}
21+
this.heap.push(data);
22+
this.bubbleUp(this.heap.length - 1);
23+
return true;
24+
}
25+
bubbleUp(index) {
26+
while (index > 0) {
27+
let curr = this.heap[index];
28+
let parentIndex = this.getParentIndex(index);
29+
let parent = this.heap[parentIndex];
30+
31+
let compare = this.comparator(parent, curr);
32+
if (compare < 0 || compare === 0) {
33+
break;
34+
}
35+
36+
this.swap(index, parentIndex);
37+
index = parentIndex;
38+
}
39+
}
40+
extract() {
41+
if (this.size() === 0) {
42+
return undefined;
43+
}
44+
45+
if (this.size() === 1) {
46+
return this.heap.shift();
47+
}
48+
49+
const value = this.heap[0];
50+
this.heap[0] = this.heap.pop();
51+
this.sinkDown(0);
52+
return value;
53+
}
54+
sinkDown(currIndex) {
55+
let left = this.getLeftIndex(currIndex);
56+
let right = this.getRightIndex(currIndex);
57+
let parentIndex = currIndex;
58+
59+
if (this.comparator(this.heap[left], this.heap[parentIndex]) < 0) {
60+
parentIndex = left;
61+
}
62+
63+
if (this.comparator(this.heap[right], this.heap[parentIndex]) < 0) {
64+
parentIndex = right;
65+
}
66+
67+
if (parentIndex !== currIndex) {
68+
this.swap(parentIndex, currIndex);
69+
this.sinkDown(parentIndex);
70+
}
71+
}
72+
peak() {
73+
return this.size() > 0 ? this.heap[0] : undefined;
74+
}
75+
swap(a, b) {
76+
[this.heap[a], this.heap[b]] = [this.heap[b], this.heap[a]];
77+
}
78+
size() {
79+
return this.heap.length;
80+
}
81+
}
82+
83+
const assert = require('chai').assert;
84+
85+
describe('BinaryHeap', () => {
86+
let minHeap;
87+
beforeEach(() => {
88+
minHeap = new BinaryHeap();
89+
});
90+
it('should defined', () => {
91+
assert.equal(typeof BinaryHeap, 'function');
92+
});
93+
describe('#insert', () => {
94+
it('should defined', () => {
95+
assert.equal(typeof minHeap.insert, 'function');
96+
});
97+
it('should insert value to the heap', () => {
98+
minHeap.insert(2);
99+
minHeap.insert(5);
100+
assert.deepEqual(minHeap.heap, [2, 5]);
101+
});
102+
});
103+
describe('#size', () => {
104+
it('should defined', () => {
105+
assert.equal(typeof minHeap.size, 'function');
106+
});
107+
it('should return the length of the heap', () => {
108+
assert.equal(minHeap.size(), 0);
109+
minHeap.insert(2);
110+
assert.equal(minHeap.size(), 1);
111+
});
112+
});
113+
describe('#peak', () => {
114+
it('should defined', () => {
115+
assert.equal(typeof minHeap.peak, 'function');
116+
});
117+
it('should return the minimum value', () => {
118+
minHeap.insert(4);
119+
minHeap.insert(7);
120+
minHeap.insert(1);
121+
minHeap.insert(9);
122+
assert.equal(minHeap.peak(), 1);
123+
});
124+
it('should return the minimum value without deleting', () => {
125+
minHeap.insert(4);
126+
minHeap.insert(7);
127+
minHeap.insert(1);
128+
minHeap.insert(9);
129+
assert.equal(minHeap.size(), 4);
130+
minHeap.peak();
131+
assert.equal(minHeap.size(), 4);
132+
});
133+
});
134+
describe('#extract', () => {
135+
it('should defined', () => {
136+
assert.equal(typeof minHeap.extract, 'function');
137+
});
138+
it('should return the minimum value', () => {
139+
minHeap.insert(4);
140+
minHeap.insert(7);
141+
minHeap.insert(1);
142+
minHeap.insert(9);
143+
assert.equal(minHeap.extract(), 1);
144+
});
145+
it('should remove from the heap', () => {
146+
minHeap.insert(4);
147+
minHeap.insert(7);
148+
minHeap.insert(1);
149+
minHeap.insert(9);
150+
assert.equal(minHeap.size(), 4);
151+
minHeap.extract();
152+
assert.equal(minHeap.size(), 3);
153+
});
154+
it('should rearrange the heap', () => {
155+
minHeap.insert(4);
156+
minHeap.insert(7);
157+
minHeap.insert(1);
158+
minHeap.insert(9);
159+
assert.deepEqual(minHeap.heap, [1, 7, 4, 9]);
160+
minHeap.extract();
161+
assert.deepEqual(minHeap.heap, [4, 7, 9]);
162+
});
163+
});
164+
165+
describe('MaxHeap', () => {
166+
it('should customize to max heap', () => {
167+
const max = (a, b) => b - a;
168+
const heap = new BinaryHeap(max);
169+
heap.insert(9);
170+
heap.insert(5);
171+
heap.insert(10);
172+
heap.insert(20);
173+
heap.insert(7);
174+
heap.insert(30);
175+
heap.insert(90);
176+
heap.insert(49);
177+
178+
const sorted = [90, 49, 30, 20, 10, 9, 7, 5];
179+
const output = [];
180+
181+
while (heap.size()) {
182+
output.push(heap.extract());
183+
}
184+
assert.deepEqual(output, sorted);
185+
});
186+
});
187+
});
188+

cash-register.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* JavaScript Algorithms and Data Structures Projects: Cash Register
3+
*
4+
* Design a cash register drawer function checkCashRegister() that accepts purchase price as the first argument (price), payment as the second argument (cash), and cash-in-drawer (cid) as the third argument.
5+
*
6+
* cid is a 2D array listing available currency.
7+
*
8+
* The checkCashRegister() function should always return an object with a status key and a change key.
9+
*
10+
* Return {status: "INSUFFICIENT_FUNDS", change: []} if cash-in-drawer is less than the change due, or if you cannot return the exact change.
11+
*
12+
* Return {status: "CLOSED", change: [...]} with cash-in-drawer as the value for the key change if it is equal to the change due.
13+
*
14+
* Otherwise, return {status: "OPEN", change: [...]}, with the change due in coins and bills, sorted in highest to lowest order, as the value of the change key.
15+
*/
16+
17+
function checkCashRegister(price, cash, cid) {
18+
const drawer = {};
19+
const money = [
20+
['ONE HUNDRED', 100],
21+
['TWENTY', 20],
22+
['TEN', 10],
23+
['FIVE', 5],
24+
['ONE', 1],
25+
['QUARTER', 0.25],
26+
['DIME', 0.1],
27+
['NICKEL', 0.5],
28+
['PENNY', 0.01]
29+
];
30+
31+
let remain = cash - price;
32+
let ans = [];
33+
34+
for (let i = 0; i < cid.length; i++) {
35+
drawer[cid[i][0]] = cid[i][1];
36+
}
37+
38+
for (let i = 0; i < money.length && remain > 0; i++) {
39+
const key = money[i][0];
40+
const val = money[i][1];
41+
let change = 0;
42+
43+
while (remain >= val && drawer[key] >= val) {
44+
remain = parseFloat((remain - val).toFixed(2));
45+
change = parseFloat((change + val).toFixed(2));
46+
drawer[key] = parseFloat((drawer[key] - val).toFixed(2));
47+
}
48+
49+
if (change > 0) {
50+
ans.push([key, change]);
51+
}
52+
}
53+
54+
if (remain > 0) {
55+
return {
56+
status: "INSUFFICIENT_FUNDS",
57+
change: []
58+
};
59+
}
60+
61+
let status = 'CLOSED';
62+
63+
for (let k in drawer) {
64+
if (drawer[k] > 0) {
65+
status = 'OPEN';
66+
}
67+
}
68+
69+
return {
70+
status: status,
71+
change: (status === 'OPEN' ? ans : cid)
72+
}
73+
}
74+
75+
// Example cash-in-drawer array:
76+
// [["PENNY", 1.01],
77+
// ["NICKEL", 2.05],
78+
// ["DIME", 3.1],
79+
// ["QUARTER", 4.25],
80+
// ["ONE", 90],
81+
// ["FIVE", 55],
82+
// ["TEN", 20],
83+
// ["TWENTY", 60],
84+
// ["ONE HUNDRED", 100]]
85+
86+
console.log(checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]));
87+
console.log(checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]));

convert-html-entities.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Intermediate Algorithm Scripting: Convert HTML Entities
3+
*
4+
* Convert the characters &, <, >, " (double quote), and ' (apostrophe), in a string to their corresponding HTML entities.
5+
*/
6+
7+
function convertHTML(str) {
8+
const entities = {
9+
'&': '&amp;',
10+
'<': '&lt;',
11+
'>': '&gt;',
12+
'"': '&quot;',
13+
'\'': '&apos;'
14+
};
15+
return str.split('').map(s => entities[s] || s).join('');
16+
}
17+
18+
convertHTML("Dolce & Gabbana");

difference-two-arrays.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Intermediate Algorithm Scripting: Diff Two Arrays
3+
*
4+
* Compare two arrays and return a new array with any items only found in one of the two given arrays, but not both. In other words, return the symmetric difference of the two arrays.
5+
*
6+
* Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code.
7+
*
8+
* Note
9+
* You can return the array with its elements in any order.
10+
*/
11+
12+
function diffArray(arr1, arr2) {
13+
const unique = new Set();
14+
15+
for (let i = 0; i < arr1.length; i++) {
16+
unique.add(arr1[i]);
17+
}
18+
19+
for (let i = 0; i < arr2.length; i++) {
20+
if (unique.has(arr2[i])) {
21+
unique.delete(arr2[i]);
22+
} else {
23+
unique.add(arr2[i]);
24+
}
25+
}
26+
27+
return Array.from(unique.values());
28+
}
29+
30+
console.log(diffArray([1, "calf", 3, "piglet"], [1, "calf", 3, 4]));

flatten-array.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function flatten_array(arr) {
2+
let flatten = [];
3+
for (let val of arr) {
4+
if (Array.isArray(val)) {
5+
flatten = flatten.concat(flatten_array(val));
6+
} else {
7+
flatten.push(val);
8+
}
9+
}
10+
return flatten;
11+
}
12+
13+
console.log(flatten_array([1, [2], [3, [[4]]]]));

0 commit comments

Comments
 (0)