Partitions of a list

9

The answer to this question is much too long

Your challenge is to write a partitioning function in the smallest number of characters.

Input example

['a', 'b', 'c']

Output example

[(('a'),('b'),('c')),
 (('a', 'b'), ('c')),
 (('a', 'c'), ('b')),
 (('b', 'c'), ('a')),
 (('a', 'b', 'c'))]

The input can be a list/array/set/string etc. whatever is easiest for your function to process

You can also choose the output format to suit yourself as long as the structure is clear.

Your function should work for at least 6 items in the input

gnibbler

Posted 2012-10-12T03:40:34.550

Reputation: 14 170

shall the empty partition also be part of the output? – FUZxxl – 2015-04-24T09:24:35.347

Answers

3

GolfScript (43 chars)

{[[]]:E\{:v;{:^E+1/{^1$-\[~[v]+]+}/}%}/}:P;

or

{[[]]:E\{:v;{:^E+1/{^1$-\{[v]+}%+}/}%}/}:P;

Same input format, output format, and function name as Howard's solution. There's no brute forcing: this takes the simple iterative approach of adding one element from the input list to the partition each time round the outer loop.

Peter Taylor

Posted 2012-10-12T03:40:34.550

Reputation: 41 901

6

GolfScript, 51 characters

{[[]]\{[.;]`{1$[1$]+@@`1$`{[2$]-@@[+]+}++/}+%}/}:P;

The script defines a variable P which takes an array from top of the stack and pushes back a list of all partitions, e.g.

[1 2] P            # => [[[1] [2]] [[1 2]]]
["a" "b" "c"] P    # => [[["a"] ["b"] ["c"]] [["b"] ["a" "c"]] [["a"] ["b" "c"]] [["a" "b"] ["c"]] [["a" "b" "c"]]]

It does also work on larger lists:

6, P ,p            # prints 203, i.e. Bell number B6
8, P ,p            # 4140

You may perform own tests online.

Howard

Posted 2012-10-12T03:40:34.550

Reputation: 23 109

6

J, 51 characters

([:<a:-.~])"1~.((>:@i.#:i.@!)#l)<@;/."1[l=:;:1!:1[1

Takes input from the keyboard, items separated by spaces:

   ([:<a:-.~])"1~.((>:@i.#:i.@!)#l)<@;/."1[l=:;:1!:1[1
a b c
+-----+------+------+------+-------+
|+---+|+--+-+|+--+-+|+-+--+|+-+-+-+|
||abc|||ab|c|||ac|b|||a|bc|||a|b|c||
|+---+|+--+-+|+--+-+|+-+--+|+-+-+-+|
+-----+------+------+------+-------+

Gareth

Posted 2012-10-12T03:40:34.550

Reputation: 11 678

1

Haskell, 90 87 71 66

Saved 5 bytes thanks to nimi.

x#[]=[[[x]]]
x#(y:s)=((x:y):s):map(y:)(x#s)
p=foldr((=<<).(#))[[]]

Example:

*Main> p "abc"
[["abc"],["bc","a"],["ac","b"],["c","ab"],["c","b","a"]]

alephalpha

Posted 2012-10-12T03:40:34.550

Reputation: 23 988

A few bytes to save: rearrange the parentheses in the 2nd line of #: :map(y:)(x#s) and turn the lambda into a point-free version: foldr((=<<).(#))[[]]. – nimi – 2015-04-23T22:40:32.327

0

Python 2, 131 bytes

def P(L):
 if len(L)<2:yield[L];return
 for p in P(L[1:]):
	for n,s in enumerate(p):yield p[:n]+[[L[0]]+s]+p[n+1:]
	yield[[L[0]]]+p

Try it online

Uses this algorithm.

mbomb007

Posted 2012-10-12T03:40:34.550

Reputation: 21 944