Skip to content

Instantly share code, notes, and snippets.

@messerc
Created December 22, 2017 07:30
Show Gist options
  • Save messerc/90f1dcf13cac776dd36b74f677c83a22 to your computer and use it in GitHub Desktop.
Save messerc/90f1dcf13cac776dd36b74f677c83a22 to your computer and use it in GitHub Desktop.
/*
* Return an array with the power set of a given string.
* Definition of power set: The set of all possible subsets including the empty set.
*
* Example:
*
* powerSet("abc")
* -> [ '' , 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc' ]
*
* Note:
* 1. All characters in a subset should be sorted.
* 2. Sets of the same characters are considered duplicates regardless of order and count only once, e.g. 'ab' and 'ba' are the same.
*
* Example 2 :
*
* powerSet("jump")
* -> ["", "j", "ju", "jm", "jp", "jmu", "jmp", "jpu", "jmpu", "u", "m", "p", "mu", "mp", "pu", "mpu"]
*/
var powerSet = function(str) {
var set = [];
var hash = {};
if (!str) { str = ''; }
str = str.split('').sort();
// remove duplicates
for (var i = 1; i < str.length; i++) {
if (str[i - 1] === str[i]) {
str.splice(i, 1);
i--;
}
}
// recursive through the sub sets
var recurse = function(strSet) {
var joined = strSet.join('');
// check if we have visited this combo
if (hash[joined]) { return; }
hash[joined] = true;
set.push(joined);
// don't recurse to empty set - add it once at the end
if (strSet.length === 1) { return; }
// recurse all subsets
for (var i = 0; i < strSet.length; i++) {
var subSet = strSet.slice(0, i).concat(strSet.slice(i + 1));
recurse(subSet);
}
};
recurse(str);
set.push(''); // the power set, by definition, includes the empty set
return set;
};
@EvanWard97
Copy link

The hash object caught my eye as this is solvable without conditionals.

const powerSet = <T = any>(arr: readonly T[]): T[][] => arr.reduce(
        (subsetsSoFar: T[][], elem: T) =>
            subsetsSoFar.concat(subsetsSoFar.map((subset) => subset.concat(elem))),
        [[]]
    )

const stringPowerSet = (str: string): string[] =>
    powerSet([...str])
        .map((subset) => subset.sort().join(''))
        .sort() // optional sorting for aesthetics
        .sort((a, b) => a.length - b.length)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment