Skip to content

Commit 4b4c559

Browse files
committed
Factored out generic combination generation
1 parent c33b26e commit 4b4c559

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

medium/histogram_area.js

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,59 @@
2020
function histogramArea(arr) {
2121
const histogram = arr;
2222

23-
// Generate combos
24-
const combos = [];
25-
for (let max = Math.pow(2, histogram.length), i = 0; i < max; i++) {
26-
let combo = i.toString(2);
27-
// Pad left
28-
while (combo.length < histogram.length) {
29-
combo = '0' + combo;
30-
}
23+
// 1s must be adjacent with no 0s in between
24+
const comboFilter = combo => /^[0]*[1]+[0]*$/.test(combo);
3125

32-
// 1s must be adjacent with no 0s in between
33-
const goodComboRegEx = /^[0]*[1]+[0]*$/;
34-
const goodCombo = goodComboRegEx.test(combo);
35-
if (goodCombo) {
36-
combos.push(combo);
37-
}
38-
}
26+
const combos = ComboGenerator.generate(histogram.length, comboFilter);
3927

4028
let maxArea = 0;
41-
combos.forEach(combo => {
29+
30+
for (const combo of combos) {
4231
const area = histogramAreaOfCombo(histogram, combo);
4332
if (area > maxArea) {
4433
maxArea = area;
4534
}
46-
});
35+
}
4736

4837
return maxArea;
4938
}
5039

40+
class ComboGenerator {
41+
/**
42+
* Function is a predicate to test each combination generated. Return true
43+
* to keep the element, false otherwise.
44+
* @callback filterCallback
45+
* @param {string} combo String represented. '0001', '0010', '0011', etc.
46+
*/
47+
48+
/**
49+
* Returns generator of combinations as strings, '1' is on and '0' is off.
50+
*
51+
* `maxLength` is the number of binary digits to generate. Examples:
52+
*
53+
* 4: 0000 ... 1111
54+
* 5: 00000 ... 11111
55+
* 6: 000000 ... 111111
56+
* @param {number} maxLength
57+
* @param {filterCallback} [filterCallback = () => true]
58+
* @return {Generator}
59+
*/
60+
static *generate(maxLength, filterCallback = () => true) {
61+
const max = Math.pow(2, maxLength);
62+
for (let i = 0; i < max; i++) {
63+
let combo = i.toString(2);
64+
// Pad left
65+
while (combo.length < maxLength) {
66+
combo = '0' + combo;
67+
}
68+
69+
if (filterCallback(combo)) {
70+
yield combo;
71+
}
72+
}
73+
}
74+
}
75+
5176
function histogramAreaOfCombo(histogram, combo) {
5277
const hist = histogram.filter((element, index) => combo[index] === '1');
5378
const maxHeight = Math.min(...hist);

0 commit comments

Comments
 (0)