Reputation: 2540
I need to find all possible combinations of a given string, from a minimum length to a maximum length.
interface allCombos(string: String, min: Number, max:Number): Array {}
So if my input string is ‘abcde’
, and my minimum length is 3, I want the result to be:
For length 3:
[‘abc’, ‘abd’, ‘abe’, ‘acd’, ..., ‘bcd’, ‘bce’, ..., ‘eda’, ...]
Concatenated with length 4:
[‘abcd’, ‘abdc’, ‘acdb’, ‘acbd’, …etc]
Concatenated with all possible combinations with length up to the max parameter. Which shouldn't be higher than the input word length.
I started thinking that all possible combinations would be ∑(3! + 4! + … + n!)
. But then I saw I'm wrong because for every length subset, there are many combinations for the whole world (for example 3-length combinations of a 6 letter string).
Can the community help me with this problem?
The solution can either be in JavaScript
, Python
or even pseudo code.
Edit
For knowledge's sake. Could anyone answer me, the formula that describes the result size in this case? I know its not ∑(3! + 4! + … + n!)
.
Upvotes: 3
Views: 2153
Reputation: 1522
Others showed you some nice options for combinations/permutations, but I think your full expected output is something like this:
from itertools import combinations
def allCombos(str, min_length, max_length):
str_combinations = []
for length in range(min_length, max_length):
combinations = [''.join(c) for c in combinations(str, length)]
str_combinations.append(combinations)
return str_combinations
Upvotes: 1
Reputation: 1
[Edit]: For knowledge's sake. Could anyone answer me, the formula that describes the result size in this case? I know its not ∑(3! + 4! + … + n!).
Below find three mathematical approaches which provide the same ultimate result using JavaScript. For further descriptions of the procedure see
further items of interest within the subject matter
There are apparently 3072 ways to draw this flower. But why?
What is the shortest string that contains all permutations of an alphabet?
const n = 4;
{
console.log("multiplication in loop:\n");
let l = 1,
k;
for (let i = k = n; l < i; k *= l++);
console.log({
[`${n}!`]: k
});
}
{
console.log("single multiplication 4 * 3 * 2 * 1:\n");
console.log({
[`${n}!`]: 4 * 3 * 2 * 1
});
}
{
console.log("multiplication in steps:\n");
let curr = n;
let acc = {};
acc[`${curr} * ${curr - 1}`] = curr * --curr;
console.log(acc);
acc[`${Object.keys(acc).pop()} * ${--curr}`] = curr * +acc[Object.keys(acc).pop()];
console.log(acc);
acc[`${Object.keys(acc).pop()} * ${--curr}`] = curr * +acc[Object.keys(acc).pop()];
console.log(acc);
}
Upvotes: 1
Reputation: 25997
You can use itertools.combinations
for this:
from itertools import combinations
["".join(li) for li in combinations('abcde', 3)]
This will give
['abc', 'abd', 'abe', 'acd', 'ace', 'ade', 'bcd', 'bce', 'bde', 'cde']
Brief explanation:
list(combinations('abcde', 3))
will give
[('a', 'b', 'c'),
('a', 'b', 'd'),
('a', 'b', 'e'),
('a', 'c', 'd'),
('a', 'c', 'e'),
('a', 'd', 'e'),
('b', 'c', 'd'),
('b', 'c', 'e'),
('b', 'd', 'e'),
('c', 'd', 'e')]
so all combinations of three of your letters. You can join the individual tuples then in a list comprehension.
You can then of course easily put this in a loop if you like:
min_length = 3
max_length = 5
res = {str(i): ["".join(li) for li in combinations('abcde', i)] for i in range(min_length, max_length + 1)}
This gives
{'3': ['abc', 'abd', 'abe', 'acd', 'ace', 'ade', 'bcd', 'bce', 'bde', 'cde'],
'4': ['abcd', 'abce', 'abde', 'acde', 'bcde'],
'5': ['abcde']}
If you want to have it in a single list:
import numpy as np
final_list = np.concatenate(res.values())
which yields
array(['abc', 'abd', 'abe', 'acd', 'ace', 'ade', 'bcd', 'bce', 'bde',
'cde', 'abcde', 'abcd', 'abce', 'abde', 'acde', 'bcde'],
dtype='|S5')
Upvotes: 3
Reputation: 3175
I am happy to introduce you to the wonderful python standard library itertools! You will want to use the combinations function. What is awesome about this library is that it solves almost all combinatoric loop problems.
import itertools
min_length = 2
max_length = 5
s = 'ABCDEF'
for i in range(min_length, max_length):
print('length', i, 'cominations')
print([_ for _ in itertools.combinations(s, i)])
Upvotes: 1