Add power set algorithm.

This commit is contained in:
Oleksii Trekhleb 2018-04-02 12:27:20 +03:00
parent 91011c18f4
commit 00e40a0eca
5 changed files with 61 additions and 0 deletions

View File

@ -4,5 +4,8 @@
"plugins": ["jest"],
"env": {
"jest/globals": true
},
"rules": {
"no-bitwise": "off"
}
}

View File

@ -16,6 +16,7 @@
* Math
* [Fibonacci Number](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/fibonacci)
* [Cartesian Product](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/cartesian-product)
* [Power Set](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/math/power-set)
## Running Tests

View File

@ -0,0 +1,5 @@
# Power Set
Power set of a set A is the set of all of the subsets of A.
Eg. for `{x, y, z}`, the subsets are : `{{}, {x}, {y}, {z}, {x, y}, {x, z}, {y, z}, {x, y, z}}`

View File

@ -0,0 +1,24 @@
import powerSet from '../powerSet';
describe('powerSet', () => {
it('should calculate power set of given set', () => {
const powerSets1 = powerSet([1]);
const powerSets2 = powerSet([1, 2, 3]);
expect(powerSets1).toEqual([
[],
[1],
]);
expect(powerSets2).toEqual([
[],
[1],
[2],
[1, 2],
[3],
[1, 3],
[2, 3],
[1, 2, 3],
]);
});
});

View File

@ -0,0 +1,28 @@
export default function powerSet(originalSet) {
const subSets = [];
// We will have 2^n possible combinations (where n is a length of original set).
// It is because for every element of original set we will decide whether to include
// it or not (2 options for each set element).
const numberOfCombinations = 2 ** originalSet.length;
// Each number in binary representation in a range from 0 to 2^n does exactly what we need:
// it shoes by its bits (0 or 1) whether to include related element from the set or not.
// For example, for the set {1, 2, 3} the binary number of 010 would mean that we need to
// include only "2" to the current set.
for (let combinationIndex = 0; combinationIndex < numberOfCombinations; combinationIndex += 1) {
const subSet = [];
for (let setElementIndex = 0; setElementIndex < originalSet.length; setElementIndex += 1) {
// Decide whether we need to include current element into the subset or not.
if (combinationIndex & (1 << setElementIndex)) {
subSet.push(originalSet[setElementIndex]);
}
}
// Add current subset to the list of all subsets.
subSets.push(subSet);
}
return subSets;
}