Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get all the possible 3 letter permutations? [duplicate]

Possible Duplicate:
Listing all permutations of a string/integer

For example,

aaa .. aaz .. aba .. abz .. aca .. acz .. azz .. baa .. baz .. bba .. bbz .. zzz

Basically, imagine counting binary but instead of going from 0 to 1, it goes from a to z.

I have been trying to get this working to no avail and the formula is getting quite complex. I'm not sure if there's a simpler way to do it.

Edit

I have something like this at the moment but it's not quite there and I'm not sure if there is a better way:

private IEnumerable<string> GetWordsOfLength(int length)
{
    char letterA = 'a', letterZ = 'z';

    StringBuilder currentLetters = new StringBuilder(new string(letterA, length));
    StringBuilder endingLetters = new StringBuilder(new string(letterZ, length));

    int currentIndex = length - 1;

    while (currentLetters.ToString() != endingLetters.ToString())
    {
        yield return currentLetters.ToString();

        for (int i = length - 1; i > 0; i--)
        {
            if (currentLetters[i] == letterZ)
            {
                for (int j = i; j < length; j++)
                {
                    currentLetters[j] = letterA;
                }

                if (currentLetters[i - 1] != letterZ)
                {
                    currentLetters[i - 1]++;
                }
            }
            else
            {
                currentLetters[i]++;

                break;
            }
        }
    }
}
like image 299
Ryan Peschel Avatar asked Dec 15 '12 09:12

Ryan Peschel


2 Answers

For a variable amount of letter combinations, you can do the following:

var alphabet = "abcdefghijklmnopqrstuvwxyz";
var q = alphabet.Select(x => x.ToString());
int size = 4;
for (int i = 0; i < size - 1; i++)
    q = q.SelectMany(x => alphabet, (x, y) => x + y);

foreach (var item in q)
    Console.WriteLine(item);
like image 79
Magnus Avatar answered Sep 21 '22 12:09

Magnus


var alphabet = "abcdefghijklmnopqrstuvwxyz";
//or var alphabet = Enumerable.Range('a', 'z' - 'a' + 1).Select(i => (char)i);

var query = from a in alphabet
            from b in alphabet
            from c in alphabet
            select "" + a + b + c;

foreach (var item in query)
{
    Console.WriteLine(item);
}

__EDIT__

For a general solution, you can use the CartesianProduct here

int N = 4;
var result = Enumerable.Range(0, N).Select(_ => alphabet).CartesianProduct();
foreach (var item in result)
{
    Console.WriteLine(String.Join("",item));
}

// Eric Lippert’s Blog
// Computing a Cartesian Product with LINQ
// http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    // base case: 
    IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
    foreach (var sequence in sequences)
    {
        var s = sequence; // don't close over the loop variable 
        // recursive case: use SelectMany to build the new product out of the old one 
        result =
            from seq in result
            from item in s
            select seq.Concat(new[] { item });
    }
    return result;
}
like image 42
L.B Avatar answered Sep 21 '22 12:09

L.B