views:

138

answers:

8

Hi I have a list of tokens, like:

hel
lo
bye

and i want to generate all the possible combinations of such strings, like:

hello
lohel
helbye
byehel
lobye
byelo

Language is not important, any advice?

I found http://stackoverflow.com/questions/3846123/generating-permutations-using-bash, but this makes permutation on a single line.

A: 

Update: I see I wasn't explicit enough.

Haskell has a permutations function that would help:

import Data.List
permutations ["hel","lo","bye"] ==
[["hel","lo","bye"],["lo","hel","bye"],["bye","lo","hel"],
 ["lo","bye","hel"],["bye","hel","lo"],["hel","bye","lo"]]

If you want each permutation concatenated, use

map concat (permutations ["hel","lo","bye"]) ==
["hellobye","lohelbye","byelohel","lobyehel","byehello","helbyelo"]

If you actually want combinations of two substrings (like your example output) instead of all permutations of substrings, as @Sven noticed, use the Math.Combinatorics.Graph module and:

map concat (combinationsOf 2 ["hel","lo","bye"])

That matches your example data in some respects but not others. I could go on to speculate that you want "all possible strings" as the title says, or all permutations of two-token subsets, or what have you, but it's kind of pointless to speculate since you've already accepted an answer.

LarsH
Nice, but this permutes all letters on a given string, not set of strings.
LucaB
LucaB, permutations will work on any iterable. Look at the examples in python.
Mike Axiak
@LucaB, look again... the function permutes a list. If you pass it a list of characters (a string), it will permute those characters. If you pass it a list of strings, it will permute that list of strings.
LarsH
+5  A: 

itertools.permutations can do that for you.

>>> l = ['hel', 'lo', 'bye']
>>> list(itertools.permutations(l, 2))
[('hel', 'lo'), ('hel', 'bye'), ('lo', 'hel'), ('lo', 'bye'), ('bye', 'hel'), ('bye', 'lo')]

Or if you want combinations, you can use itertools.combinations.

>>> l = ['hel', 'lo', 'bye']
>>> list(itertools.combinations(l, 2))
[('hel', 'lo'), ('hel', 'bye'), ('lo', 'bye')]
Bertrand Marron
Deducing from the example, the OP actually wants combinations, not permutations.
Sven Marnach
Not exactly one per line, nor words.
kanaka
@Sven, I don't think so, but I edited my answer anyway.
Bertrand Marron
@kanaka, It's only a matter of joining strings, printing and formatting.
Bertrand Marron
+9  A: 

Your example can be written in Python as

from itertools import combinations
print list(combinations(["hel", "lo", "bye"], 2))

To combine the output to strings again:

print ["".join(a) for a in combinations(["hel", "lo", "bye"], 2)]

If you interested in the actual implementation of this function, have a look at the documentation.

Sven Marnach
Results in: <itertools.combinations object at 0xb7d1370c>
kanaka
Fixed this already before your comment :)
Sven Marnach
Still not one per line as requested.
kanaka
Can't find this request, even after reading the post again. Furthermore, it's rather trivial to change this.
Sven Marnach
"but this makes permutation on a single line." implies that he wants one per line (and his example output show it as such).
kanaka
@kanaka, it seems to me that the OP is only asking for advices, not complete solutions.
Bertrand Marron
You're right :)
LucaB
+1  A: 
a = ['hel', 'lo', 'bye']
print '\n'.join(''.join(x) for x in itertools.permutations(a, 2))
Mike Axiak
This only does 2 token combinations not all possible as requested.
kanaka
and yet his desired output had 2 token combinations as well :)
Mike Axiak
+1  A: 

Easy in python with itertools.

Here is the token permutation example:

import itertools

tokens = ["hel", "lo", "bye"]

for i in range(1, len(tokens) + 1):
    for p in itertools.permutations(tokens, i):
        print "".join(p)

Alternatively, this treats each character as a token:

import itertools

tokens = ["hel", "lo", "bye"]

chars = "".join(tokens)
for i in range(1, len(chars) + 1):
    for p in itertools.permutations(chars, i):
        print "".join(p)
kanaka
It gives all permutations of all chars.
demas
@demas corrected before you commented.
kanaka
OK, but the "-1" is not my vote.
demas
+1  A: 

Python has a permutations too. :)

demas
+2  A: 

Given that other languages are acceptable:

#!/usr/bin/perl

use strict; use warnings;
use Algorithm::Combinatorics qw(permutations);

my $data = [ qw( hel lo bye ) ];
my $it = permutations($data);

while ( my $p = $it->next ) {
    print @$p, "\n";
}
hellobye
helbyelo
lohelbye
lobyehel
byehello
byelohel
Sinan Ünür
A: 

Looks like you want permutations:

from itertools import permutations

# easy way to make a list for words
words = 'hel lo bye'.split()

# fetch two-word permutations, joined into a string
for word in [''.join(s) for s in permutations(words,2)]:
    print word

Output:

hello
helbye
lohel
lobye
byehel
byelo
Mark Tolonen