Power set
A set is a collection (container) of certain values, without any particular order, and no repeated values. It corresponds with a finite set in mathematics. A set can be implemented as an associative array (partial mapping) in which the value of each key-value pair is ignored.
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Given a set S, the power set (or powerset) of S, written P(S), or 2S, is the set of all subsets of S.
Task : By using a library or built-in set type, or by defining a set type with necessary operations, write a function with a set S as input that yields the power set 2S of S.
For example, the power set of {1,2,3,4} is {{}, {1}, {2}, {1,2}, {3}, {1,3}, {2,3}, {1,2,3}, {4}, {1,4}, {2,4}, {1,2,4}, {3,4}, {1,3,4}, {2,3,4}, {1,2,3,4}}.
Ada
<lang ada>with Ada.Text_IO; use Ada.Text_IO;
procedure Power_Set is
type Universe is (A,B,C,D,E); -- The type Set are subsets of Universe type Set is array (Universe) of Boolean; Empty : constant Set := (others => False); function Cardinality (X : Set) return Natural is N : Natural := 0; begin for I in X'Range loop if X (I) then N := N + 1; end if; end loop; return N; end Cardinality; function Element (X : Set; Position : Positive) return Universe is N : Natural := 0; begin for I in X'Range loop if X (I) then N := N + 1; if N = Position then return I; end if; end if; end loop; raise Constraint_Error; end Element; procedure Put (X : Set) is Empty : Boolean := True; begin for I in X'Range loop if X (I) then if Empty then Empty := False; Put (Universe'Image (I)); else Put ("," & Universe'Image (I)); end if; end if; end loop; if Empty then Put ("empty"); end if; end Put; -- Set_Of_Set are sets of subsets of Universe type Set_Of_Sets is array (Positive range <>) of Set; function Power (X : Set) return Set_Of_Sets is Length : constant Natural := Cardinality (X); Index : array (1..Length) of Integer := (others => 0); Result : Set_Of_Sets (1..2**Length) := (others => Empty); begin for N in Result'Range loop for I in 1..Length loop -- Index determines the sample N exit when Index (I) = 0; Result (N) (Element (X, Index (I))) := True; end loop; Next : for I in 1..Length loop -- Computing the index of the following sample if Index (I) < Length then Index (I) := Index (I) + 1; if I = 1 or else Index (I - 1) > Index (I) then for J in reverse 2..I loop Index (J - 1) := Index (J) + 1; end loop; exit Next; end if; end if; end loop Next; end loop; return Result; end Power; P : Set_Of_Sets := Power ((A|C|E => True, others => False));
begin
for I in P'Range loop New_Line; Put (P (I)); end loop;
end Power_Set;</lang> This example computes the power set of {A,C,E}. Sample output:
empty A C E A,C A,E C,E A,C,E
ALGOL 68
Requires: ALGOL 68g mk14.1+
<lang algol68>MODE MEMBER = INT;
PROC power set = ([]MEMBER s)[][]MEMBER:(
[2**UPB s]FLEX[1:0]MEMBER r; INT upb r := 0; r[upb r +:= 1] := []MEMBER(()); FOR i TO UPB s DO MEMBER e = s[i]; FOR j TO upb r DO [UPB r[j] + 1]MEMBER x; x[:UPB x-1] := r[j]; x[UPB x] := e; # append to the end of x # r[upb r +:= 1] := x # append to end of r # OD OD; r[upb r] := s; r
);
- Example: #
test:(
[][]MEMBER set = power set((1, 2, 4)); FOR member TO UPB set DO INT upb = UPB set[member]; FORMAT repr set = $"("f( upb=0 | $$ | $n(upb-1)(d", ")d$ )");"$; printf(($"set["d"] = "$,member, repr set, set[member],$l$)) OD
)</lang> Output:
set[1] = (); set[2] = (1); set[3] = (2); set[4] = (1, 2); set[5] = (4); set[6] = (1, 4); set[7] = (2, 4); set[8] = (1, 2, 4);
AutoHotkey
ahk discussion <lang autohotkey>a = 1,a,-- ; elements separated by commas StringSplit a, a, `, ; a0 = #elements, a1,a2,... = elements of the set
t = { Loop % (1<<a0) { ; generate all 0-1 sequences
x := A_Index-1 Loop % a0 t .= (x>>A_Index-1) & 1 ? a%A_Index% "," : "" t .= "}`n{" ; new subsets in new lines
} MsgBox % RegExReplace(SubStr(t,1,StrLen(t)-1),",}","}")</lang>
BBC BASIC
The elements of a set are represented as the bits in an integer (hence the maximum size of set is 32). <lang bbcbasic> DIM list$(3) : list$() = "1", "2", "3", "4"
PRINT FNpowerset(list$()) END DEF FNpowerset(list$()) IF DIM(list$(),1) > 31 ERROR 100, "Set too large to represent as integer" LOCAL i%, j%, s$ s$ = "{" FOR i% = 0 TO (2 << DIM(list$(),1)) - 1 s$ += "{" FOR j% = 0 TO DIM(list$(),1) IF i% AND (1 << j%) s$ += list$(j%) + "," NEXT IF RIGHT$(s$) = "," s$ = LEFT$(s$) s$ += "}," NEXT i% = LEFT$(s$) + "}"</lang>
Output:
{{},{1},{2},{1,2},{3},{1,3},{2,3},{1,2,3},{4},{1,4},{2,4},{1,2,4},{3,4},{1,3,4},{2,3,4},{1,2,3,4}}
Bracmat
<lang bracmat>( ( powerset
= done todo first . !arg:(?done.?todo) & ( !todo:%?first ?todo & (powerset$(!done !first.!todo),powerset$(!done.!todo)) | !done ) )
& out$(powerset$(.1 2 3 4)) );</lang> Output:
1 2 3 4 , 1 2 3 , 1 2 4 , 1 2 , 1 3 4 , 1 3 , 1 4 , 1 , 2 3 4 , 2 3 , 2 4 , 2 , 3 4 , 3 , 4 ,
Burlesque
<lang burlesque> blsq ) {1 2 3 4}R@ {{} {1} {2} {1 2} {3} {1 3} {2 3} {1 2 3} {4} {1 4} {2 4} {1 2 4} {3 4} {1 3 4} {2 3 4} {1 2 3 4}} </lang>
C
<lang c>#include <limits.h>
- include <stdio.h>
- include <stdlib.h>
static void powerset(int argc, char** argv) {
unsigned int i, j, bits, i_max = 1U << argc;
if (argc >= sizeof(i) * CHAR_BIT) { fprintf(stderr, "Error: set too large\n"); exit(1); }
for (i = 0; i < i_max ; ++i) { printf("{"); for (bits = i, j = 0; bits; bits >>= 1, ++j) { if (bits & 1) printf(bits > 1 ? "%s, " : "%s", argv[j]); } printf("}\n"); }
}
int main(int argc, char* argv[]) {
powerset(argc - 1, argv + 1); return 0;
}</lang>output<lang>% ./a.out 1 2 3 4 {} {1} {2} {1, 2} {3} {1, 3} {2, 3} {1, 2, 3} {4} {1, 4} {2, 4} {1, 2, 4} {3, 4} {1, 3, 4} {2, 3, 4} {1, 2, 3, 4}</lang>
C++
Non-recursive version
<lang cpp>#include <iostream>
- include <set>
- include <vector>
- include <iterator>
- include <algorithm>
typedef std::set<int> set_type; typedef std::set<set_type> powerset_type;
powerset_type powerset(set_type const& set) {
typedef set_type::const_iterator set_iter; typedef std::vector<set_iter> vec; typedef vec::iterator vec_iter;
struct local { static int dereference(set_iter v) { return *v; } };
powerset_type result;
vec elements; do { set_type tmp; std::transform(elements.begin(), elements.end(), std::inserter(tmp, tmp.end()), local::dereference); result.insert(tmp); if (!elements.empty() && ++elements.back() == set.end()) { elements.pop_back(); } else { set_iter iter; if (elements.empty()) { iter = set.begin(); } else { iter = elements.back(); ++iter; } for (; iter != set.end(); ++iter) { elements.push_back(iter); } } } while (!elements.empty());
return result;
}
int main() {
int values[4] = { 2, 3, 5, 7 }; set_type test_set(values, values+4);
powerset_type test_powerset = powerset(test_set);
for (powerset_type::iterator iter = test_powerset.begin(); iter != test_powerset.end(); ++iter) { std::cout << "{ "; char const* prefix = ""; for (set_type::iterator iter2 = iter->begin(); iter2 != iter->end(); ++iter2) { std::cout << prefix << *iter2; prefix = ", "; } std::cout << " }\n"; }
}</lang>
Output:
{ } { 2 } { 2, 3 } { 2, 3, 5 } { 2, 3, 5, 7 } { 2, 3, 7 } { 2, 5 } { 2, 5, 7 } { 2, 7 } { 3 } { 3, 5 } { 3, 5, 7 } { 3, 7 } { 5 } { 5, 7 } { 7 }
Recursive version
<lang cpp>#include <iostream>
- include <set>
template<typename Set> std::set<Set> powerset(const Set& s, size_t n) {
typedef typename Set::const_iterator SetCIt; typedef typename std::set<Set>::const_iterator PowerSetCIt; std::set<Set> res; if(n > 0) { std::set<Set> ps = powerset(s, n-1); for(PowerSetCIt ss = ps.begin(); ss != ps.end(); ss++) for(SetCIt el = s.begin(); el != s.end(); el++) { Set subset(*ss); subset.insert(*el); res.insert(subset); } res.insert(ps.begin(), ps.end()); } else res.insert(Set()); return res;
} template<typename Set> std::set<Set> powerset(const Set& s) {
return powerset(s, s.size());
} </lang>
C#
<lang csharp> public IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list) {
return from m in Enumerable.Range(0, 1 << list.Count) select from i in Enumerable.Range(0, list.Count) where (m & (1 << i)) != 0 select list[i];
}
public void PowerSetofColors() {
var colors = new List<KnownColor> { KnownColor.Red, KnownColor.Green, KnownColor.Blue, KnownColor.Yellow }; var result = GetPowerSet(colors); Console.Write( string.Join( Environment.NewLine, result.Select(subset => string.Join(",", subset.Select(clr => clr.ToString()).ToArray())).ToArray()));
}
</lang>
Output:
<lang>
Red Green Red,Green Blue Red,Blue Green,Blue Red,Green,Blue Yellow Red,Yellow Green,Yellow Red,Green,Yellow Blue,Yellow Red,Blue,Yellow Green,Blue,Yellow Red,Green,Blue,Yellow
</lang>
An alternative implementation for an arbitrary number of elements:
<lang csharp>
public IEnumerable<IEnumerable<T>> GetPowerSet<T>(IEnumerable<T> input) { var seed = new List<IEnumerable<T>>() { Enumerable.Empty<T>() } as IEnumerable<IEnumerable<T>>;
return input.Aggregate(seed, (a, b) => a.Concat(a.Select(x => x.Concat(new List<T>() { b })))); }
</lang>
Clojure
<lang Clojure>(use '[clojure.contrib.combinatorics :only [subsets] ])
(def S #{1 2 3 4})
user> (subsets S) (() (1) (2) (3) (4) (1 2) (1 3) (1 4) (2 3) (2 4) (3 4) (1 2 3) (1 2 4) (1 3 4) (2 3 4) (1 2 3 4))</lang>
CoffeeScript
<lang coffeescript> print_power_set = (arr) ->
console.log "POWER SET of #{arr}" for subset in power_set(arr) console.log subset
power_set = (arr) ->
result = [] binary = (false for elem in arr) n = arr.length while binary.length <= n result.push bin_to_arr binary, arr i = 0 while true if binary[i] binary[i] = false i += 1 else binary[i] = true break binary[i] = true result
bin_to_arr = (binary, arr) ->
(arr[i] for i of binary when binary[arr.length - i - 1])
print_power_set [] print_power_set [4, 2, 1] print_power_set ['dog', 'c', 'b', 'a'] </lang> output <lang> > coffee power_set.coffee POWER SET of [] POWER SET of 4,2,1 [] [ 1 ] [ 2 ] [ 2, 1 ] [ 4 ] [ 4, 1 ] [ 4, 2 ] [ 4, 2, 1 ] POWER SET of dog,c,b,a [] [ 'a' ] [ 'b' ] [ 'b', 'a' ] [ 'c' ] [ 'c', 'a' ] [ 'c', 'b' ] [ 'c', 'b', 'a' ] [ 'dog' ] [ 'dog', 'a' ] [ 'dog', 'b' ] [ 'dog', 'b', 'a' ] [ 'dog', 'c' ] [ 'dog', 'c', 'a' ] [ 'dog', 'c', 'b' ] [ 'dog', 'c', 'b', 'a' ] </lang>
ColdFusion
Port from the JavaScript version, compatible with ColdFusion 8+ or Railo 3+ <lang javascript>public array function powerset(required array data) {
var ps = [""]; var d = arguments.data; var lenData = arrayLen(d); var lenPS = 0; for (var i=1; i LTE lenData; i++) { lenPS = arrayLen(ps); for (var j = 1; j LTE lenPS; j++) { arrayAppend(ps, listAppend(ps[j], d[i])); } } return ps;
}
var res = powerset([1,2,3,4]);</lang>
Outputs:
["","1","2","1,2","3","1,3","2,3","1,2,3","4","1,4","2,4","1,2,4","3,4","1,3,4","2,3,4","1,2,3,4"]
Common Lisp
<lang lisp>(defun power-set (s)
(reduce #'(lambda (item ps) (append (mapcar #'(lambda (e) (cons item e)) ps) ps)) s :from-end t :initial-value '(())))</lang>
Output:
>(power-set '(1 2 3)) ((1 2 3) (1 2) (1 3) (1) (2 3) (2) (3) NIL)
Alternate, more recursive (same output):
<lang lisp>(defun powerset (l)
(if (null l) (list nil) (let ((prev (powerset (cdr l))))
(append (mapcar #'(lambda (elt) (cons (car l) elt)) prev) prev))))</lang>
Imperative-style using LOOP:
<lang lisp>(defun powerset (xs)
(loop for i below (expt 2 (length xs)) collect (loop for j below i for x in xs if (logbitp j i) collect x)))</lang>
Output:
>(powerset '(1 2 3) (NIL (1) (2) (1 2) (3) (1 3) (2 3) (1 2 3))
Yet another imperative solution, this time with dolist. <lang lisp>(defun power-set (list)
(let ((pow-set (list nil))) (dolist (element (reverse list) pow-set) (dolist (set pow-set) (push (cons element set) pow-set)))))</lang>
Output:
>(power-set '(1 2 3)) ((1) (1 3) (1 2 3) (1 2) (2) (2 3) (3) NIL)
D
Version using just arrays (it assumes the input to contain distinct items): <lang d>T[][] powerSet(T)(in T[] s) pure nothrow {
auto r = new typeof(return)(1, 0); foreach (e; s) { typeof(return) rs; foreach (x; r) rs ~= x ~ [e]; r ~= rs; } return r;
}
void main() {
import std.stdio; [1, 2, 3].powerSet.writeln;
}</lang>
- Output:
[[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
Lazy Version
Compile with -version=power_set2_main to run the main. <lang d>auto powerSet(T)(T[] xs) {
auto output = new T[xs.length]; immutable size_t len = 1U << xs.length;
struct Result { size_t bits; @property empty() const pure nothrow { return bits == len; } void popFront() pure nothrow { bits++; } @property save() pure nothrow { return this; }
T[] front() nothrow { size_t pos = 0; foreach (immutable size_t i; 0 .. xs.length) if (bits & (1 << i)) output[pos++] = xs[i]; return output[0 .. pos]; } }
return Result();
}
version (power_set2_main) {
void main() { import std.stdio; [1, 2, 3].powerSet.writeln; }
}</lang> Same output.
A set implementation and its power set function.
Déjà Vu
In Déjà Vu, sets are dictionaries with all values true
and the default set to false
.
<lang dejavu>powerset s: local :out [ set{ } ] for value in keys s: for subset in copy out: local :subset+1 copy subset set-to subset+1 value true push-to out subset+1 out
!. powerset set{ 1 2 3 4 }</lang>
- Output:
[ set{ } set{ 4 } set{ 3 4 } set{ 3 } set{ 2 3 } set{ 2 3 4 } set{ 2 4 } set{ 2 } set{ 1 2 } set{ 1 2 4 } set{ 1 2 3 4 } set{ 1 2 3 } set{ 1 3 } set{ 1 3 4 } set{ 1 4 } set{ 1 } ]
E
<lang e>pragma.enable("accumulator")
def powerset(s) {
return accum [].asSet() for k in 0..!2**s.size() { _.with(accum [].asSet() for i ? ((2**i & k) > 0) => elem in s { _.with(elem) }) }
}</lang>
It would also be possible to define an object which is the powerset of a provided set without actually instantiating all of its members immediately.
Erlang
Generates all subsets of a list with the help of binary:
For [1 2 3]: [ ] | 0 0 0 | 0 [ 3] | 0 0 1 | 1 [ 2 ] | 0 1 0 | 2 [ 2 3] | 0 1 1 | 3 [1 ] | 1 0 0 | 4 [1 3] | 1 0 1 | 5 [1 2 ] | 1 1 0 | 6 [1 2 3] | 1 1 1 | 7 ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
<lang erlang>powerset(Lst) ->
N = length(Lst), Max = trunc(math:pow(2,N)), [[lists:nth(Pos+1,Lst) || Pos <- lists:seq(0,N-1), I band (1 bsl Pos) =/= 0] || I <- lists:seq(0,Max-1)].</lang>
Which outputs:
[[], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3], [4], [1,4], [2,4], [1,2,4], [3,4], [1,3,4], [2,3,4], [1,2,3,4]]
Alternate shorter and more efficient version: <lang erlang>powerset([]) -> [[]]; powerset([H|T]) -> PT = powerset(T),
[ [H|X] || X <- PT ] ++ PT.</lang>
or even more efficient version: <lang erlang>powerset([]) -> [[]]; powerset([H|T]) -> PT = powerset(T),
powerset(H, PT, PT).
powerset(_, [], Acc) -> Acc; powerset(X, [H|T], Acc) -> powerset(X, T, [[X|H]|Acc]).</lang>
F#
almost exact copy of OCaml version <lang fsharp> let subsets xs = List.foldBack (fun x rest -> rest @ List.map (fun ys -> x::ys) rest) xs [[]] </lang>
Factor
We use hash sets, denoted by HS{ }
brackets, for our sets. members
converts from a set to a sequence, and <hash-set>
converts back.
<lang factor>USING: kernel prettyprint sequences arrays sets hash-sets ;
IN: powerset
- add ( set elt -- newset ) 1array <hash-set> union ;
- powerset ( set -- newset ) members { HS{ } } [ dupd [ add ] curry map append ] reduce <hash-set> ;</lang>
Usage: <lang factor>( scratchpad ) HS{ 1 2 3 4 } powerset . HS{
HS{ 1 2 3 4 } HS{ 1 2 } HS{ 1 3 } HS{ 2 3 } HS{ 1 2 3 } HS{ 1 4 } HS{ 2 4 } HS{ } HS{ 1 } HS{ 2 } HS{ 3 } HS{ 4 } HS{ 1 2 4 } HS{ 3 4 } HS{ 1 3 4 } HS{ 2 3 4 }
}</lang>
Forth
.
<lang forth>: ?print dup 1 and if over args type space then ;
- .set begin dup while ?print >r 1+ r> 1 rshift repeat drop drop ;
- .powerset 0 do ." ( " 1 i .set ." )" cr loop ;
- check-none dup 2 < abort" Usage: powerset [val] .. [val]" ;
- check-size dup /cell 8 [*] >= abort" Set too large" ;
- powerset 1 argn check-none check-size 1- lshift .powerset ;
powerset</lang> Output:
$ 4th cxq powerset.4th 1 2 3 4 ( ) ( 1 ) ( 2 ) ( 1 2 ) ( 3 ) ( 1 3 ) ( 2 3 ) ( 1 2 3 ) ( 4 ) ( 1 4 ) ( 2 4 ) ( 1 2 4 ) ( 3 4 ) ( 1 3 4 ) ( 2 3 4 ) ( 1 2 3 4 )
Frink
Frink's set and array classes have built-in subsets[] methods that return all subsets. If called with an array, the results are arrays. If called with a set, the results are sets. <lang frink> a = new set[1,2,3,4] a.subsets[] </lang>
GAP
<lang gap># Built-in Combinations([1, 2, 3]);
- [ [ ], [ 1 ], [ 1, 2 ], [ 1, 2, 3 ], [ 1, 3 ], [ 2 ], [ 2, 3 ], [ 3 ] ]
- Note that it handles duplicates
Combinations([1, 2, 3, 1]);
- [ [ ], [ 1 ], [ 1, 1 ], [ 1, 1, 2 ], [ 1, 1, 2, 3 ], [ 1, 1, 3 ], [ 1, 2 ], [ 1, 2, 3 ], [ 1, 3 ],
- [ 2 ], [ 2, 3 ], [ 3 ] ]</lang>
Go
No native set type in Go. While the associative array trick mentioned in the task description works well in Go in most situations, it does not work here because we need sets of sets, and converting a general set to a hashable value for a map key is non-trivial.
Instead, this solution uses a simple (non-associative) slice as a set representation. To ensure uniqueness, the element interface requires an equality method, which is used by the set add method. Adding elements with the add method ensures the uniqueness property.
The power set method implemented here does not need the add method though. The algorithm ensures that the result will be a valid set as long as the input is a valid set. This allows the more efficient append function to be used. <lang go>package main
import (
"fmt" "strconv"
)
// types needed to implement general purpose sets are element and set
// element is an interface, allowing different kinds of elements to be // implemented and stored in sets. type element interface {
// an element must be distinguishable from other elements to satisfy // the mathematical definition of a set. a.eq(b) must give the same // result as b.eq(a). eq(element) bool // String result is used only for printable output. Given a, b where // a.eq(b), it is not required that a.String() == b.String(). String() string
}
// integer type satisfying element interface type intEle int
func (i intEle) eq(e element) bool {
if j, ok := e.(intEle); ok { return i == j } return false
}
func (i intEle) String() string {
return strconv.Itoa(int(i))
}
// set type implemented as a simple list. methods will be added to // make it satisfy the element interface, allowing sets of sets. type set []element
// uniqueness of elements can be ensured by using add method func (s *set) addEle(e element) {
if !s.hasEle(e) { *s = append(*s, e) }
}
func (s *set) hasEle(e element) bool {
for _, ex := range *s { if e.eq(ex) { return true } } return false
}
// method to satify element interface func (s set) eq(e element) bool {
t, ok := e.(set) if !ok { return false } if len(s) != len(t) { return false } for _, se := range s { if !t.hasEle(se) { return false } } return true
}
// method to satify element interface func (s set) String() string {
r := "{" for _, e := range s { if len(r) > 1 { r += " " } r += fmt.Sprint(e) } return r + "}"
}
// method required for task func (s set) powerSet() set {
r := set{set{}} for _, es := range s { var u set for _, er := range r { u = append(u, append(er.(set), es)) } r = append(r, u...) } return r
}
func main() {
var s set for _, i := range []intEle{1, 2, 2, 3, 4, 4, 4} { s.addEle(i) } fmt.Println(s) fmt.Println("length =", len(s)) ps := s.powerSet() fmt.Println(ps) fmt.Println("length =", len(ps))
}</lang>
- Output:
{1 2 3 4} length = 4 {{} {1} {2} {1 2} {3} {1 3} {2 3} {1 2 3} {4} {1 4} {2 4} {1 2 4} {3 4} {1 3 4} {2 3 4} {1 2 3 4}} length = 16
Groovy
Builds on the Combinations solution. Sets are not a "natural" collection type in Groovy. Lists are much more richly supported. Thus, this solution is liberally sprinkled with coercion from Set to List and from List to Set. <lang groovy>def comb comb = { m, List list ->
def n = list.size() m == 0 ? [[]] : (0..(n-m)).inject([]) { newlist, k -> def sublist = (k+1 == n) ? [] : list[(k+1)..<n] newlist += comb(m-1, sublist).collect { [list[k]] + it } }
}
def powerSet = { set ->
(0..(set.size())).inject([]){ list, i -> list + comb(i,set as List)}.collect { it as LinkedHashSet } as LinkedHashSet
}</lang>
Test program: <lang groovy>def vocalists = [ "C", "S", "N", "Y" ] as LinkedHashSet println "${vocalists}" println powerSet(vocalists)</lang>
Output:
[C, S, N, Y] [[], [C], [S], [N], [Y], [C, S], [C, N], [C, Y], [S, N], [S, Y], [N, Y], [C, S, N], [C, S, Y], [C, N, Y], [S, N, Y], [C, S, N, Y]]
Note: In this example, LinkedHashSet was used throughout for Set coercion. This is because LinkedHashSet preserves the order of input, like a List. However, if order does not matter you could replace all references to LinkedHashSet with Set.
Haskell
<lang Haskell>import Data.Set import Control.Monad
powerset :: Ord a => Set a -> Set (Set a) powerset = fromList . fmap fromList . listPowerset . toList
listPowerset :: [a] -> a listPowerset = filterM (const [True, False])</lang> listPowerset describes the result as all possible (using the list monad) filterings (using filterM) of the input list, regardless (using const) of each item's value. powerset simply converts the input and output from lists to sets.
Alternate Solution <lang Haskell>powerset [] = [[]] powerset (head:tail) = acc ++ map (head:) acc where acc = powerset tail</lang> or <lang Haskell>powerset = foldr (\x acc -> acc ++ map (x:) acc) [[]]</lang> Examples:
*Main> listPowerset [1,2,3] [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]] *Main> powerset (Data.Set.fromList [1,2,3]) {{},{1},{1,2},{1,2,3},{1,3},{2},{2,3},{3}}
Prelude> import Data.List Prelude Data.List> subsequences [1,2,3] [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
Alternate solution
A method using only set operations and set mapping is also possible. Ideally, Set
would be defined as a Monad, but that's impossible given the constraint that the type of inputs to Set.map (and a few other functions) be ordered.
<lang Haskell>import qualified Data.Set as Set
type Set=Set.Set
unionAll :: (Ord a) => Set (Set a) -> Set a
unionAll = Set.fold Set.union Set.empty
--slift is the analogue of liftA2 for sets. slift :: (Ord a, Ord b, Ord c) => (a->b->c) -> Set a -> Set b -> Set c slift f s0 s1 = unionAll (Set.map (\e->Set.map (f e) s1) s0)
--a -> {{},{a}} makeSet :: (Ord a) => a -> Set (Set a) makeSet = (Set.insert Set.empty) . Set.singleton.Set.singleton
powerSet :: (Ord a) => Set a -> Set (Set a) powerSet = (Set.fold (slift Set.union) (Set.singleton Set.empty)) . Set.map makeSet</lang> Usage: <lang Haskell> Prelude Data.Set> powerSet fromList [1,2,3] fromList [fromList [], fromList [1], fromList [1,2], fromList [1,2,3], fromList [1,3], fromList [2], fromList [2,3], fromList [3]]</lang>
Icon and Unicon
The two examples below show the similarities and differences between constructing an explicit representation of the solution, i.e. a set containing the powerset, and one using generators. The basic recursive algorithm is the same in each case, but wherever the first stores part of the result away, the second uses 'suspend' to immediately pass the result back to the caller. The caller may then decide to store the results in a set, a list, or dispose of each one as it appears.
Set building
The following version returns a set containing the powerset:
<lang Icon> procedure power_set (s)
result := set () if *s = 0 then insert (result, set ()) # empty set else { head := set(?s) # take a random element # and find powerset of remaining part of set tail_pset := power_set (x -- head) result ++:= tail_pset # add powerset of remainder to results every ps := !tail_pset do # and add head to each powerset from the remainder insert (result, ps ++ head) } return result
end </lang>
To test the above procedure:
<lang Icon> procedure main ()
every s := !power_set (set(1,2,3,4)) do { # requires '!' to generate items in the result set writes ("[ ") every writes (!s || " ") write ("]") }
end </lang>
Output:
[ 3 ] [ 4 3 ] [ 2 4 ] [ 2 3 ] [ 1 3 ] [ 4 ] [ 2 ] [ 2 1 3 ] [ 2 4 1 ] [ 4 1 3 ] [ 2 4 1 3 ] [ ] [ 2 4 3 ] [ 1 ] [ 4 1 ] [ 2 1 ]
Generator
An alternative version, which generates each item in the power set in turn:
<lang Icon> procedure power_set (s)
if *s = 0 then suspend set () else { head := set(?s) every ps := power_set (s -- head) do { suspend ps suspend ps ++ head } }
end
procedure main ()
every s := power_set (set(1,2,3,4)) do { # power_set's values are generated by 'every' writes ("[ ") every writes (!s || " ") write ("]") }
end </lang>
J
There are a number of ways to generate a power set in J. Here's one: <lang j>ps =: #~ 2 #:@i.@^ #</lang> For example: <lang j> ps 'ACE'
E C CE A AE AC ACE</lang>
In the typical use, this operation makes sense on collections of unique elements.
<lang J> ~.1 2 3 2 1 1 2 3
#ps 1 2 3 2 1
32
#ps ~.1 2 3 2 1
8</lang>
In other words, the power set of a 5 element set has 32 sets where the power set of a 3 element set has 8 sets. Thus if elements of the original "set" were not unique then sets of the power "set" will also not be unique sets.
Java
Recursion
This implementation sorts each subset, but not the whole list of subsets (which would require a custom comparator). It also destroys the original set. <lang java5>public static ArrayList<String> getpowerset(int a[],int n,ArrayList<String> ps)
{ if(n<0) { return null; } if(n==0) { if(ps==null) ps=new ArrayList<String>(); ps.add(" "); return ps; } ps=getpowerset(a, n-1, ps); ArrayList<String> tmp=new ArrayList<String>(); for(String s:ps) { if(s.equals(" ")) tmp.add(""+a[n-1]); else tmp.add(s+a[n-1]); } ps.addAll(tmp); return ps; }</lang>
Iterative
The iterative implementation of the above idea. Each subset is in the order that the element appears in the input list. This implementation preserves the input. <lang java5> public static <T> List<List<T>> powerset(Collection<T> list) {
List<List<T>> ps = new ArrayList<List<T>>(); ps.add(new ArrayList<T>()); // add the empty set
// for every item in the original list for (T item : list) { List<List<T>> newPs = new ArrayList<List<T>>();
for (List<T> subset : ps) { // copy all of the current powerset's subsets newPs.add(subset);
// plus the subsets appended with the current item List<T> newSubset = new ArrayList<T>(subset); newSubset.add(item); newPs.add(newSubset); }
// powerset is now powerset of list.subList(0, list.indexOf(item)+1) ps = newPs; } return ps;
} </lang>
Binary String
This implementation works on idea that each element in the original set can either be in the power set or not in it. With n elements in the original set, each combination can be represented by a binary string of length n. To get all possible combinations, all you need is a counter from 0 to 2n - 1. If the kth bit in the binary string is 1, the kth element of the original set is in this combination. <lang java5>public static <T extends Comparable<? super T>> LinkedList<LinkedList<T>> BinPowSet( LinkedList<T> A){ LinkedList<LinkedList<T>> ans= new LinkedList<LinkedList<T>>(); int ansSize = (int)Math.pow(2, A.size()); for(Integer i= 0;i< ansSize;++i){ String bin= Integer.toString(i, 2); //convert to binary while(bin.length() < A.size())bin = "0" + bin; //pad with 0's LinkedList<T> thisComb = new LinkedList<T>(); //place to put one combination for(int j= 0;j< A.size();++j){ if(bin.charAt(j) == '1')thisComb.add(A.get(j)); } Collections.sort(thisComb); //sort it for easy checking ans.add(thisComb); //put this set in the answer list } return ans; }</lang>
JavaScript
Uses a JSON stringifier from http://www.json.org/js.html
<lang javascript>function powerset(ary) {
var ps = [[]]; for (var i=0; i < ary.length; i++) { for (var j = 0, len = ps.length; j < len; j++) { ps.push(ps[j].concat(ary[i])); } } return ps;
}
var res = powerset([1,2,3,4]);
load('json2.js'); print(JSON.stringify(res));</lang>
Outputs:
[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3],[4],[1,4],[2,4],[1,2,4],[3,4],[1,3,4],[2,3,4],[1,2,3,4]]
Julia
<lang julia>function powerset (x)
result = {{}} for i in x, j = 1:length(result) push!(result, [result[j],i]) end result
end</lang>
- Output:
julia> show(powerset({1,2,3})) {{},{1},{2},{1,2},{3},{1,3},{2,3},{1,2,3}}
K
<lang K>
ps:{x@&:'+2_vs!_2^#x}
</lang> Usage: <lang K>
ps "ABC"
(""
,"C" ,"B" "BC" ,"A" "AC" "AB" "ABC")
</lang>
Logo
<lang logo>to powerset :set
if empty? :set [output [[]]] localmake "rest powerset butfirst :set output sentence map [sentence first :set ?] :rest :rest
end
show powerset [1 2 3] [[1 2 3] [1 2] [1 3] [1] [2 3] [2] [3] []]</lang>
Logtalk
<lang logtalk>:- object(set).
:- public(powerset/2).
powerset(Set, PowerSet) :- reverse(Set, RSet), powerset_1(RSet, [[]], PowerSet).
powerset_1([], PowerSet, PowerSet). powerset_1([X| Xs], Yss0, Yss) :- powerset_2(Yss0, X, Yss1), powerset_1(Xs, Yss1, Yss).
powerset_2([], _, []). powerset_2([Zs| Zss], X, [Zs, [X| Zs]| Yss]) :- powerset_2(Zss, X, Yss).
reverse(List, Reversed) :- reverse(List, [], Reversed).
reverse([], Reversed, Reversed). reverse([Head| Tail], List, Reversed) :- reverse(Tail, [Head| List], Reversed).
- - end_object.</lang>
Usage example: <lang logtalk>| ?- set::powerset([1, 2, 3, 4], PowerSet).
PowerSet = [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3],[4],[1,4],[2,4],[1,2,4],[3,4],[1,3,4],[2,3,4],[1,2,3,4]] yes</lang>
Lua
<lang lua> --returns the powerset of s, out of order. function powerset(s, start)
start = start or 1 if(start > #s) then return {{}} end local ret = powerset(s, start + 1) for i = 1, #ret do ret[#ret + 1] = {s[start], unpack(ret[i])} end return ret
end
--non-recurse implementation function powerset(s)
local t = {{}} for i = 1, #s do for j = 1, #t do t[#t+1] = {s[i],unpack(t[j])} end end return t
end
--alternative, copied from the Python implementation function powerset2(s)
local ret = {{}} for i = 1, #s do local k = #ret for j = 1, k do ret[k + j] = {s[i], unpack(ret[j])} end end return ret
end </lang>
M4
<lang M4>define(`for',
`ifelse($#, 0, ``$0, eval($2 <= $3), 1, `pushdef(`$1', `$2')$4`'popdef( `$1')$0(`$1', incr($2), $3, `$4')')')dnl
define(`nth',
`ifelse($1, 1, $2, `nth(decr($1), shift(shift($@)))')')dnl
define(`range',
`for(`x', eval($1 + 2), eval($2 + 2), `nth(x, $@)`'ifelse(x, eval($2+2), `', `,')')')dnl
define(`powerpart',
`{range(2, incr($1), $@)}`'ifelse(incr($1), $#, `', `for(`x', eval($1+2), $#, `,powerpart(incr($1), ifelse( eval(2 <= ($1 + 1)), 1, `range(2,incr($1), $@), ')`'nth(x, $@)`'ifelse( eval((x + 1) <= $#),1,`,range(incr(x), $#, $@)'))')')')dnl
define(`powerset',
`{powerpart(0, substr(`$1', 1, eval(len(`$1') - 2)))}')dnl
dnl powerset(`{a,b,c}')</lang>
Output:
{{},{a},{a,b},{a,b,c},{a,c},{b},{b,c},{c}}
Mathematica
Built-in function that either gives all possible subsets, subsets with at most n elements, subsets with exactly n elements or subsets containing between n and m elements. Example of all subsets: <lang Mathematica>Subsets[{a, b, c}]</lang> gives: <lang Mathematica>{{}, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}}</lang> Subsets[list, {n, Infinity}] gives all the subsets that have n elements or more.
Subsets[list, n] gives all the subsets that have at most n elements.
Subsets[list, {n}] gives all the subsets that have exactly n elements.
Subsets[list, {m,n}] gives all the subsets that have between m and n elements.
MATLAB
Sets are not an explicit data type in MATLAB, but cell arrays can be used for the same purpose. In fact, cell arrays have the benefit of containing any kind of data structure. So, this powerset function will work on a set of any type of data structure, without the need to overload any operators.
<lang MATLAB>function pset = powerset(theSet)
pset = cell(size(theSet)); %Preallocate memory
%Generate all numbers from 0 to 2^(num elements of the set)-1 for i = ( 0:(2^numel(theSet))-1 ) %Convert i into binary, convert each digit in binary to a boolean %and store that array of booleans indicies = logical(bitget( i,(1:numel(theSet)) )); %Use the array of booleans to extract the members of the original %set, and store the set containing these members in the powerset pset(i+1) = {theSet(indicies)}; end
end</lang>
Sample Usage: Powerset of the set of the empty set. <lang MATLAB>powerset({{}})
ans =
{} {1x1 cell} %This is the same as { {},{{}} }</lang>
Powerset of { {1,2},3 }. <lang MATLAB>powerset({{1,2},3})
ans =
{1x0 cell} {1x1 cell} {1x1 cell} {1x2 cell} %This is the same as { {},Template:1,2,{3},{{1,2},3} }</lang>
Maxima
<lang maxima>powerset({1, 2, 3, 4}); /* {{}, {1}, {1, 2}, {1, 2, 3}, {1, 2, 3, 4}, {1, 2, 4}, {1, 3}, {1, 3, 4},
{1, 4}, {2}, {2, 3}, {2, 3, 4}, {2, 4}, {3}, {3, 4}, {4}} */</lang>
Objective-C
<lang objc>#import <Foundation/Foundation.h>
+ (NSArray *)powerSetForArray:(NSArray *)array { UInt32 subsetCount = 1 << array.count; NSMutableArray *subsets = [NSMutableArray arrayWithCapacity:subsetCount]; for(int subsetIndex = 0; subsetIndex < subsetCount; subsetIndex++) { NSMutableArray *subset = [[NSMutableArray alloc] init]; for (int itemIndex = 0; itemIndex < array.count; itemIndex++) { if((subsetIndex >> itemIndex) & 0x1) { [subset addObject:[array objectAtIndex:itemIndex]]; } } [subsets addObject:subset]; [subset release]; } return subsets; }</lang>
OCaml
The standard library already implements a proper Set datatype. As the base type is unspecified, the powerset must be parameterized as a module. Also, the library is lacking a map operation, which we have to implement first.
<lang ocaml>module PowerSet(S: Set.S) = struct
include Set.Make (S)
let map f s = let work x r = add (f x) r in fold work s empty ;;
let powerset s = let base = singleton (S.empty) in let work x r = union r (map (S.add x) r) in S.fold work s base ;;
end;; (* PowerSet *)</lang>
version for lists: <lang ocaml>let subsets xs = List.fold_right (fun x rest -> rest @ List.map (fun ys -> x::ys) rest) xs [[]]</lang>
OPL
<lang OPL> {string} s={"A","B","C","D"}; range r=1.. ftoi(pow(2,card(s))); {string} s2 [k in r] = {i | i in s: ((k div (ftoi(pow(2,(ord(s,i))))) mod 2) == 1)};
execute {
writeln(s2);
} </lang>
which gives
<lang result>
[{} {"A"} {"B"} {"A" "B"} {"C"} {"A" "C"} {"B" "C"} {"A" "B" "C"} {"D"} {"A"
"D"} {"B" "D"} {"A" "B" "D"} {"C" "D"} {"A" "C" "D"} {"B" "C" "D"} {"A" "B" "C" "D"}]
</lang>
Oz
Oz has a library for finite set constraints. Creating a power set is a trivial application of that: <lang oz>declare
%% Given a set as a list, returns its powerset (again as a list) fun {Powerset Set} proc {Describe Root} %% Describe sets by lower bound (nil) and upper bound (Set) Root = {FS.var.bounds nil Set} %% enumerate all possible sets {FS.distribute naive [Root]} end AllSets = {SearchAll Describe} in %% convert to list representation {Map AllSets FS.reflect.lowerBoundList} end
in
{Inspect {Powerset [1 2 3 4]}}</lang>
A more convential implementation without finite set constaints: <lang oz>fun {Powerset2 Set}
case Set of nil then [nil] [] H|T thens Acc = {Powerset2 T} in {Append Acc {Map Acc fun {$ A} H|A end}} end
end</lang>
PARI/GP
<lang parigp>vector(1<<#S,i,vecextract(S,i-1))</lang>
Perl
<lang perl>sub p{@_?map{$_,[$_[0],@$_]}p(@_[1..$#_]):[]}</lang> or <lang perl>use List::Util qw(reduce); sub powerset {
@{ (reduce { [@$a, map([@$_, $b], @$a)] } [[]], @_) }
}</lang>
Perl 6
<lang perl6>sub powerset ( *@list ) {
reduce( -> @L, $n { [ @L, @L.map({[ $_.list, $n ]}) ] }, [[]], @list );
}</lang>
PHP
<lang PHP> <?php function get_subset($binary, $arr) {
// based on true/false values in $binary array, include/exclude // values from $arr $subset = array(); foreach (range(0, count($arr)-1) as $i) { if ($binary[$i]) { $subset[] = $arr[count($arr) - $i - 1]; } } return $subset;
}
function print_array($arr) {
if (count($arr) > 0) { echo join(" ", $arr); } else { echo "(empty)"; } echo '
';
}
function print_power_sets($arr) {
echo "POWER SET of [" . join(", ", $arr) . "]
"; foreach (power_set($arr) as $subset) { print_array($subset); }
}
function power_set($arr) {
$binary = array(); foreach (range(1, count($arr)) as $i) { $binary[] = false; } $n = count($arr); $powerset = array(); while (count($binary) <= count($arr)) { $powerset[] = get_subset($binary, $arr); $i = 0; while (true) { if ($binary[$i]) { $binary[$i] = false; $i += 1; } else { $binary[$i] = true; break; } } $binary[$i] = true; } return $powerset;
}
print_power_sets(array()); print_power_sets(array('singleton')); print_power_sets(array('dog', 'c', 'b', 'a')); ?> </lang> Output in browser: <lang> POWER SET of [] POWER SET of [singleton] (empty) singleton POWER SET of [dog, c, b, a] (empty) a b a b c a c b c a b c dog a dog b dog a b dog c dog a c dog b c dog a b c dog </lang>
PicoLisp
<lang PicoLisp>(de powerset (Lst)
(ifn Lst (cons) (let L (powerset (cdr Lst)) (conc (mapcar '((X) (cons (car Lst) X)) L) L ) ) ) )</lang>
PL/I
<lang pli>*process source attributes xref or(!);
/*-------------------------------------------------------------------- * 06.01.2014 Walter Pachl translated from REXX *-------------------------------------------------------------------*/ powerset: Proc Options(main); Dcl (hbound,index,left,substr) Builtin; Dcl sysprint Print; Dcl s(4) Char(5) Var Init('one','two','three','four'); Dcl ps Char(1000) Var; Dcl (n,chunk,p) Bin Fixed(31); n=hbound(s); /* number of items in the list. */ ps='{} '; /* start with a null power set. */ Do chunk=1 To n; /* loop through the ... . */ ps=ps!!combn(chunk); /* a CHUNK at a time. */ End; Do While(ps>); p=index(ps,' '); Put Edit(left(ps,p-1))(Skip,a); ps=substr(ps,p+1); End;
combn: Proc(y) Returns(Char(1000) Var); /*-------------------------------------------------------------------- * returns the list of subsets with y elements of set s *-------------------------------------------------------------------*/ Dcl (y,base,bbase,ym,p,j,d,u) Bin Fixed(31); Dcl (z,l) Char(1000) Var Init(); Dcl a(20) Bin Fixed(31) Init((20)0); Dcl i Bin Fixed(31); base=hbound(s)+1; bbase=base-y; ym=y-1; Do p=1 To y; a(p)=p; End; Do j=1 By 1; l=; Do d=1 To y; u=a(d); l=l!!','!!s(u); End; z=z!!'{'!!substr(l,2)!!'} '; a(y)=a(y)+1; If a(y)=base Then If combu(ym) Then Leave; End; /* Put Edit('combn',y,z)(Skip,a,f(2),x(1),a); */ Return(z);
combu: Proc(d) Recursive Returns(Bin Fixed(31)); Dcl (d,u) Bin Fixed(31); If d=0 Then Return(1); p=a(d); Do u=d To y; a(u)=p+1; If a(u)=bbase+u Then Return(combu(u-1)); p=a(u); End; Return(0); End; End;
End;</lang>
output
{} {one} {two} {three} {four} {one,two} {one,three} {one,four} {two,three} {two,four} {three,four} {one,two,three} {one,two,four} {one,three,four} {two,three,four} {one,two,three,four}
Prolog
Logical (cut-free) Definition
The predicate powerset(X,Y) defined here can be read as "Y is the powerset of X", it being understood that lists are used to represent sets.
The predicate subseq(X,Y) is true if and only if the list X is a subsequence of the list Y.
The definitions here are elementary, logical (cut-free), and efficient (within the class of comparably generic implementations). <lang Prolog>powerset(X,Y) :- bagof( S, subseq(S,X), Y).
subseq( [], []). subseq( [], [_|_]). subseq( [X|Xs], [X|Ys] ) :- subseq(Xs, Ys). subseq( [X|Xs], [_|Ys] ) :- append(_, [X|Zs], Ys), subseq(Xs, Zs). </lang> Output :
?- powerset([1,2,3], X). X = [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]].
Single-Functor Definition
<lang Prolog>power_set(T, PS) :- bagof(PS1, power_set(T, [], PS1), PS).
power_set(T, PS, PS1) :- select(E, T, T1), !, append(PS, [E], PST), ( PST = PS1; power_set(T1, PS, PS1); power_set(T1, PST, PS1)).
power_set([], [], []). </lang> Output :
?- power_set([1,2,3,4], L). L = [[1],[2],[3],[4],[],[3,4],[2,3],[2,4],[2,3,4],[1,2],[1,3],[1,4],[1,3,4],[1,2,3],[1,2,4],[1,2,3,4]].
Constraint Handling Rules
CHR is a programming language created by Professor Thom Frühwirth.
Works with SWI-Prolog and module chr written by Tom Schrijvers and Jan Wielemaker.
<lang Prolog>:- use_module(library(chr)).
- - chr_constraint chr_power_set/2, chr_power_set/1, clean/0.
clean @ clean \ chr_power_set(_) <=> true. clean @ clean <=> true.
only_one @ chr_power_set(A) \ chr_power_set(A) <=> true.
creation @ chr_power_set([H | T], A) <=>
append(A, [H], B),
chr_power_set(T, A),
chr_power_set(T, B),
chr_power_set(B).
empty_element @ chr_power_set([], _) <=> chr_power_set([]).
</lang>
Example of output :
?- chr_power_set([1,2,3,4], []), findall(L, find_chr_constraint(chr_power_set(L)), LL), clean. LL = [[1],[1,2],[1,2,3],[1,2,3,4],[1,2,4],[1,3],[1,3,4],[1,4],[2],[2,3],[2,3,4],[2,4],[3],[3,4],[4],[]] .
PureBasic
This code is for console mode. <lang PureBasic>If OpenConsole()
Define argc=CountProgramParameters() If argc>=(SizeOf(Integer)*8) Or argc<1 PrintN("Set out of range.") End 1 Else Define i, j, text$ Define.q bset=1<<argc Print("{") For i=0 To bset-1 ; check all binary combinations If Not i: text$= "{" Else : text$=", {" EndIf k=0 For j=0 To argc-1 ; step through each bit If i&(1<<j) If k: text$+", ": EndIf ; pad the output text$+ProgramParameter(j): k+1 ; append each matching bit EndIf Next j Print(text$+"}") Next i PrintN("}") EndIf
EndIf</lang> Sample output
C:\Users\PureBasic_User\Desktop>"Power Set.exe" 1 2 3 4 {{}, {1}, {2}, {1, 2}, {3}, {1, 3}, {2, 3}, {1, 2, 3}, {4}, {1, 4}, {2, 4}, {1, 2, 4}, {3, 4}, {1, 3, 4}, {2, 3, 4}, {1, 2, 3, 4}}
Python
<lang python>def list_powerset(lst):
# the power set of the empty set has one element, the empty set result = [[]] for x in lst: # for every additional element in our set # the power set consists of the subsets that don't # contain this element (just take the previous power set) # plus the subsets that do contain the element (use list # comprehension to add [x] onto everything in the # previous power set) result.extend([subset + [x] for subset in result]) return result
- the above function in one statement
def list_powerset2(lst):
return reduce(lambda result, x: result + [subset + [x] for subset in result], lst, [[]])
def powerset(s):
return frozenset(map(frozenset, list_powerset(list(s))))</lang>
list_powerset computes the power set of a list of distinct elements. powerset simply converts the input and output from lists to sets. We use the frozenset type here for immutable sets, because unlike mutable sets, it can be put into other sets.
Example:
>>> list_powerset([1,2,3]) [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] >>> powerset(frozenset([1,2,3])) frozenset([frozenset([3]), frozenset([1, 2]), frozenset([]), frozenset([2, 3]), frozenset([1]), frozenset([1, 3]), frozenset([1, 2, 3]), frozenset([2])])
Further Explanation
If you take out the requirement to produce sets and produce list versions of each powerset element, then add a print to trace the execution, you get this simplified version of the program above where it is easier to trace the inner workings <lang python>def powersetlist(s):
r = [[]] for e in s: print "r: %-55r e: %r" % (r,e) r += [x+[e] for x in r] return r
s= [0,1,2,3] print "\npowersetlist(%r) =\n %r" % (s, powersetlist(s))</lang>
Sample output:
r: [[]] e: 0 r: [[], [0]] e: 1 r: [[], [0], [1], [0, 1]] e: 2 r: [[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2]] e: 3 powersetlist([0, 1, 2, 3]) = [[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2], [3], [0, 3], [1, 3], [0, 1, 3], [2, 3], [0, 2, 3], [1, 2, 3], [0, 1, 2, 3]]
Binary Count method
If you list the members of the set and include them according to if the corresponding bit position of a binary count is true then you generate the powerset. (Note that only frozensets can be members of a set in the second function) <lang python>def powersequence(val):
Generate a 'powerset' for sequence types that are indexable by integers. Uses a binary count to enumerate the members and returns a list
Examples: >>> powersequence('STR') # String [, 'S', 'T', 'ST', 'R', 'SR', 'TR', 'STR'] >>> powersequence([0,1,2]) # List [[], [0], [1], [0, 1], [2], [0, 2], [1, 2], [0, 1, 2]] >>> powersequence((3,4,5)) # Tuple [(), (3,), (4,), (3, 4), (5,), (3, 5), (4, 5), (3, 4, 5)] >>> vtype = type(val); vlen = len(val); vrange = range(vlen) return [ reduce( lambda x,y: x+y, (val[i:i+1] for i in vrange if 2**i & n), vtype()) for n in range(2**vlen) ]
def powerset(s):
Generate the powerset of s
Example: >>> powerset(set([6,7,8])) set([frozenset([7]), frozenset([8, 6, 7]), frozenset([6]), frozenset([6, 7]), frozenset([]), frozenset([8]), frozenset([8, 7]), frozenset([8, 6])]) return set( frozenset(x) for x in powersequence(list(s)) )</lang>
Recursive Alternative
This is an (inefficient) recursive version that almost reflects the recursive definition of a power set as explained in http://en.wikipedia.org/wiki/Power_set#Algorithms. It does not create a sorted output.
<lang python> def p(l):
if not l: return [[]] return p(l[1:]) + [[l[0]] + x for x in p(l[1:])]
</lang>
Python: Standard documentation
Pythons documentation has a method that produces the groupings, but not as sets:
<lang python>>>> from pprint import pprint as pp >>> from itertools import chain, combinations >>> >>> def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
>>> pp(set(powerset({1,2,3,4}))) {(),
(1,), (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 4), (1, 3), (1, 3, 4), (1, 4), (2,), (2, 3), (2, 3, 4), (2, 4), (3,), (3, 4), (4,)}
>>> </lang>
Qi
<lang qi> (define powerset
[] -> [[]] [A|As] -> (append (map (cons A) (powerset As)) (powerset As)))
</lang>
R
Non-recursive version
The conceptual basis for this algorithm is the following: <lang>for each element in the set: for each subset constructed so far: new subset = (subset + element) </lang>
This method is much faster than a recursive method, though the speed is still O(2^n).
<lang R>powerset = function(set){ ps = list() ps1 = numeric() #Start with the empty set. for(element in set){ #For each element in the set, take all subsets temp = vector(mode="list",length=length(ps)) #currently in "ps" and create new subsets (in "temp") for(subset in 1:length(ps)){ #by adding "element" to each of them. tempsubset = c(pssubset,element) } ps=c(ps,temp) #Add the additional subsets ("temp") to "ps". } return(ps) }
powerset(1:4) </lang>
The list "temp" is a compromise between the speed costs of doing arithmetic and of creating new lists (since R lists are immutable, appending to a list means actually creating a new list object). Thus, "temp" collects new subsets that are later added to the power set. This improves the speed by 4x compared to extending the list "ps" at every step.
Recursive version
The sets package includes a recursive method to calculate the power set. However, this method takes ~100 times longer than the non-recursive method above. <lang R>library(sets)</lang> An example with a vector. <lang R>v <- (1:3)^2 sv <- as.set(v) 2^sv</lang>
{{}, {1}, {4}, {9}, {1, 4}, {1, 9}, {4, 9}, {1, 4, 9}}
An example with a list. <lang R>l <- list(a=1, b="qwerty", c=list(d=TRUE, e=1:3)) sl <- as.set(l) 2^sl</lang>
{{}, {1}, {"qwerty"}, {<<list(2)>>}, {1, <<list(2)>>}, {"qwerty", 1}, {"qwerty", <<list(2)>>}, {"qwerty", 1, <<list(2)>>}}
Racket
<lang racket>
- Direct translation of 'functional' ruby method
(define (powerset s)
(for/fold ([outer-set (set(set))]) ([element s]) (set-union outer-set (list->set (set-map outer-set (λ(inner-set) (set-add inner-set element)))))))
</lang>
Rascal
<lang rascal> import Set;
public set[set[&T]] PowerSet(set[&T] s) = power(s); </lang> An example output: <lang rascal> rascal>PowerSet({1,2,3,4}) set[set[int]]: {
{4,3}, {4,2,1}, {4,3,1}, {4,2}, {4,3,2}, {4,1}, {4,3,2,1}, {4}, {3}, {2,1}, {3,1}, {2}, {3,2}, {1}, {3,2,1}, {}
} </lang>
REXX
<lang rexx>/*REXX program to display a power set, items may be anything (no blanks)*/ parse arg S /*let user specify the set. */ if S= then S='one two three four' /*None specified? Use default*/ N=words(S) /*number of items in the list.*/ ps='{}' /*start with a null power set.*/
do chunk=1 for N /*traipse through the items. */ ps=ps combN(N,chunk) /*N items, a CHUNK at a time. */ end /*chunk*/
w=words(ps)
do k=1 for w /*show combinations, one/line.*/ say right(k,length(w)) word(ps,k) end /*k*/
exit /*stick a fork in it, we done.*/ /*─────────────────────────────────────$COMBN subroutine────────────────*/ combN: procedure expose $ S; parse arg x,y; $= !.=0; base=x+1; bbase=base-y; ym=y-1; do p=1 for y; !.p=p; end
do j=1; L= do d=1 for y; _=!.d; L=L','word(S,_); end $=$ '{'strip(L,'L',",")'}' !.y=!.y+1; if !.y==base then if .combU(ym) then leave end /*j*/
return strip($) /*return with partial powerset*/
.combU: procedure expose !. y bbase; parse arg d; if d==0 then return 1 p=!.d; do u=d to y; !.u=p+1
if !.u==bbase+u then return .combU(u-1) p=!.u end /*u*/
return 0</lang> output when using the default input:
1 {} 2 {one} 3 {two} 4 {three} 5 {four} 6 {one,two} 7 {one,three} 8 {one,four} 9 {two,three} 10 {two,four} 11 {three,four} 12 {one,two,three} 13 {one,two,four} 14 {one,three,four} 15 {two,three,four} 16 {one,two,three,four}
Ruby
<lang ruby># Based on http://johncarrino.net/blog/2006/08/11/powerset-in-ruby/
- See the link if you want a shorter version. This was intended to show the reader how the method works.
class Array
# Adds a power_set method to every array, i.e.: [1, 2].power_set def power_set # Injects into a blank array of arrays. # acc is what we're injecting into # you is each element of the array inject([[]]) do |acc, you| ret = [] # Set up a new array to add into acc.each do |i| # For each array in the injected array, ret << i # Add itself into the new array ret << i + [you] # Merge the array with a new array of the current element end ret # Return the array we're looking at to inject more. end end # A more functional and even clearer variant. def func_power_set inject([[]]) { |ps,item| # for each item in the Array ps + # take the powerset up to now and add ps.map { |e| e + [item] } # it again, with the item appended to each element } end
end
- A direct translation of the "power array" version above
require 'set' class Set
def powerset inject(Set[Set[]]) do |ps, item| ps.union ps.map {|e| e.union (Set.new [item])} end end
end
p [1,2,3,4].power_set p %w(one two three).func_power_set
p Set[1,2,3].powerset</lang>
- Output:
[[], [4], [3], [3, 4], [2], [2, 4], [2, 3], [2, 3, 4], [1], [1, 4], [1, 3], [1, 3, 4], [1, 2], [1, 2, 4], [1, 2, 3], [1, 2, 3, 4]] [[], ["one"], ["two"], ["one", "two"], ["three"], ["one", "three"], ["two", "three"], ["one", "two", "three"]] #<Set: {#<Set: {}>, #<Set: {1}>, #<Set: {2}>, #<Set: {1, 2}>, #<Set: {3}>, #<Set: {1, 3}>, #<Set: {2, 3}>, #<Set: {1, 2, 3}>}>
Scala
<lang scala>def powerset[A](s: Set[A]) = s.foldLeft(Set(Set.empty[A])) { case (ss, el) => ss ++ ss.map(_ + el) }</lang>
Scheme
<lang scheme>(define (power-set set)
(if (null? set) '(()) (let ((rest (power-set (cdr set)))) (append (map (lambda (element) (cons (car set) element)) rest) rest))))
(display (power-set (list 1 2 3))) (newline)
(display (power-set (list "A" "C" "E"))) (newline)</lang> Output:
((1 2 3) (1 2) (1 3) (1) (2 3) (2) (3) ()) ((A C E) (A C) (A E) (A) (C E) (C) (E) ())
Call/cc generation:<lang lisp>(define (power-set lst)
(define (iter yield) (let recur ((a '()) (b lst)) (if (null? b) (set! yield
(call-with-current-continuation (lambda (resume) (set! iter resume) (yield a)))) (begin (recur (append a (list (car b))) (cdr b)) (recur a (cdr b)))))
;; signal end of generation (yield 'end-of-seq))
(lambda () (call-with-current-continuation iter)))
(define x (power-set '(1 2 3))) (let loop ((a (x)))
(if (eq? a 'end-of-seq) #f (begin (display a) (newline) (loop (x)))))</lang>output<lang>(1 2)
(1 3) (1) (2 3) (2) (3) ()</lang>
Iterative:<lang scheme> (define (power_set_iter set)
(let loop ((res '(())) (s set)) (if (empty? s) res (loop (append (map (lambda (i) (cons (car s) i)) res) res) (cdr s)))))
</lang>
Output:<lang output> '((e d c b a)
(e d c b) (e d c a) (e d c) (e d b a) (e d b) (e d a) (e d) (e c b a) (e c b) (e c a) (e c) (e b a) (e b) (e a) (e) (d c b a) (d c b) (d c a) (d c) (d b a) (d b) (d a) (d) (c b a) (c b) (c a) (c) (b a) (b) (a) ())
</lang>
Seed7
<lang seed7>$ include "seed7_05.s7i";
const func array bitset: powerSet (in bitset: baseSet) is func
result var array bitset: pwrSet is [] (bitset.value); local var integer: element is 0; var integer: index is 0; var bitset: aSet is bitset.value; begin for element range baseSet do for key index range pwrSet do aSet := pwrSet[index]; if element not in aSet then incl(aSet, element); pwrSet &:= aSet; end if; end for; end for; end func;
const proc: main is func
local var bitset: aSet is bitset.value; begin for aSet range powerSet({1, 2, 3, 4}) do writeln(aSet); end for; end func;</lang>
Output:
{} {1} {2} {1, 2} {3} {1, 3} {2, 3} {1, 2, 3} {4} {1, 4} {2, 4} {1, 2, 4} {3, 4} {1, 3, 4} {2, 3, 4} {1, 2, 3, 4}
Smalltalk
Code from Bonzini's blog
<lang smalltalk>Collection extend [
power [ ^(0 to: (1 bitShift: self size) - 1) readStream collect: [ :each || i | i := 0. self select: [ :elem | (each bitAt: (i := i + 1)) = 1 ] ] ]
].</lang>
<lang smalltalk>#(1 2 4) power do: [ :each |
each asArray printNl ].
- ( 'A' 'C' 'E' ) power do: [ :each |
each asArray printNl ].</lang>
Standard ML
version for lists: <lang sml>fun subsets xs = foldr (fn (x, rest) => rest @ map (fn ys => x::ys) rest) [[]] xs</lang>
Tcl
<lang tcl>proc subsets {l} {
set res [list [list]] foreach e $l { foreach subset $res {lappend res [lappend subset $e]} } return $res
} puts [subsets {a b c d}]</lang> Output:
{} a b {a b} c {a c} {b c} {a b c} d {a d} {b d} {a b d} {c d} {a c d} {b c d} {a b c d}
Binary Count Method
<lang tcl>proc powersetb set {
set res {} for {set i 0} {$i < 2**[llength $set]} {incr i} { set pos -1 set pset {} foreach el $set { if {$i & 1<<[incr pos]} {lappend pset $el} } lappend res $pset } return $res
}</lang>
TXR
The power set function can be written concisely like this:
<lang txr>(defun power-set (s)
(reduce-right (op append (mapcar (op cons @@1) @2) @2) s '(())))</lang>
A complete program which takes command line arguments and prints the power set in comma-separated brace notation:
<lang txr>@(next :args) @(do (defun power-set (s)
(reduce-right (op append (mapcar (op cons @@1) @2) @2) s '(()))))
@(collect :vars (arg)) @arg @(end) @(bind pset @(power-set arg)) @(output) @ (repeat) {@(rep)@pset, @(last)@pset@(empty)@(end)} @ (end) @(end)</lang>
$ ./txr -l rosetta/power-set.txr 1 2 3 {1, 2, 3} {1, 2} {1, 3} {1} {2, 3} {2} {3} {}
What is not obvious is that the above power-set
function generalizes to strings and vectors.
<lang txr>@(do (defun power-set (s)
(reduce-right (op append (mapcar (op cons @@1) @2) @2) s '(()))) (format t "~s\n" (power-set "abc")) (format t "~s\n" (power-set "")) (format t "~s\n" (power-set #(1 2 3))))</lang>
txr power-set-generic.txr ((#\a #\b #\c) (#\a #\b) (#\a #\c) (#\a) (#\b #\c) (#\b) (#\c) nil) ((nil) nil) ((1 2 3) (1 2) (1 3) (1) (2 3) (2) (3) nil)
UnixPipes
<lang ksh> | cat A a b c
| cat A |\
xargs -n 1 ksh -c 'echo \{`cat A`\}' |\ xargs |\ sed -e 's; ;,;g' \ -e 's;^;echo ;g' \ -e 's;\},;}\\ ;g' |\ ksh |unfold `wc -l A` |\ xargs -n1 -I{} ksh -c 'echo {} |\ unfold 1 |sort -u |xargs' |sort -u
a a b a b c a c b b c c </lang>
UNIX Shell
From here <lang bash>p() { [ $# -eq 0 ] && echo || (shift; p "$@") | while read r ; do echo -e "$1 $r\n$r"; done }</lang> Usage <lang bash>|p `cat` | sort | uniq A C E ^D</lang>
Ursala
Sets are a built in type constructor in Ursala, represented as lexically sorted lists with duplicates removed. The powerset function is a standard library function, but could be defined as shown below. <lang Ursala>powerset = ~&NiC+ ~&i&& ~&at^?\~&aNC ~&ahPfatPRXlNrCDrT</lang> test program: <lang Ursala>#cast %sSS
test = powerset {'a','b','c','d'}</lang> output:
{ {}, {'a'}, {'a','b'}, {'a','b','c'}, {'a','b','c','d'}, {'a','b','d'}, {'a','c'}, {'a','c','d'}, {'a','d'}, {'b'}, {'b','c'}, {'b','c','d'}, {'b','d'}, {'c'}, {'c','d'}, {'d'}}
V
V has a built in called powerlist <lang v>[A C E] powerlist =[[A C E] [A C] [A E] [A] [C E] [C] [E] []]</lang>
its implementation in std.v is (like joy) <lang v>[powerlist
[null?] [unitlist] [uncons] [dup swapd [cons] map popd swoncat] linrec].
</lang>