11

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;
            }
        }
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Ryan Peschel
  • 11,087
  • 19
  • 74
  • 136
  • 3
    Take a look at [this question](http://stackoverflow.com/questions/756055/listing-all-permutations-of-a-string-integer) – Zbigniew Dec 15 '12 at 09:56
  • Also take a look at this question [Generate list of all possible permutations of a string](http://stackoverflow.com/questions/361/generate-list-of-all-possible-permutations-of-a-string) – Ortwin Angermeier Dec 15 '12 at 10:03

4 Answers4

33

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);
Magnus
  • 45,362
  • 8
  • 80
  • 118
14
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;
}
L.B
  • 114,136
  • 19
  • 178
  • 224
  • I'm surprised but yes, this works. – Carra Dec 15 '12 at 10:02
  • 2
    I thought of something like this but what if I have a variable amount of possible letter combinations? I just used 3 as an example. Might need to be 4 or 5 – Ryan Peschel Dec 15 '12 at 10:02
  • @RyanPeschel than use [CartesianProduct here](http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx) giving it n alphabet. – L.B Dec 15 '12 at 10:09
4

You have 26^3 counts for 3 "digits". Just iterate from 'a' to 'z' in three loops.

ashley
  • 1,177
  • 1
  • 14
  • 17
4

Here's a very simple solution:

for(char first = 'a'; first <= (int)'z'; first++)
    for(char second = 'a'; second <= (int)'z'; second++)
        for(char third = 'a'; third <= (int)'z'; third++)
            Console.WriteLine(first.ToString() + second + third);
Carra
  • 17,808
  • 7
  • 62
  • 75