brainfuck, 94 bytes
+[[<+>>+<-]++[>-<------]>-[>]<<[>>+>]>,]++++++++++[[[<]<]+[-[>[.>]]<[<]>+[>]>]<<
.[<<[<]>-]++>]
Formatted:
+
[
[<+> >+<-]
++[>-<------]>-[>]
<<[>>+>]
>,
]
++++++++++
[
[[<]<]
+
print
[
-[>[.>]]
<[<]
>+[>]
>
]
<<.
increment
[
<<[<]
>-
]
++>
]
Expects input of the form 9,10,11
without a trailing newline, and outputs subsets in the same format, sometimes with a trailing comma. The first line printed will always be empty, signifying the empty set.
The basic idea is to place a bit next to each element, then repeatedly increment the binary number while printing the corresponding subset before each increment. (A bit indicates whether an element is in the subset.) A sentinel bit to the left of the array is used to terminate the program. This version actually creates an exponential number of sentinels to save some bytes; a more efficient 99-byte solution that only uses one sentinel can be found in the revision history.
Each bit is encoded as one plus its value; i.e., it can be either 1
or 2
. The tape is laid out with the bit before each element and a single zero cell between adjacent elements. The comma is included on the tape for non-final elements, so that we don't need to do anything special tocan conveniently just print elements without doing any extra work to handle delimiters.