2

I want to create a generator that will generate all possible combinations of N length and with N different character sets.

Example: Input string -> AAA000 -> Output -> aaa000 , aaa001 ... aaz999 , aba000 , aba001 ... zzz999 .

In this example I want to generate (instead of each A) combinations of alpha charset and (instead of each 0) combinations of numeric charsets. So the output depends on input string.

I am beginner in C# and I have created only simple generator with single charset. But it's useless for me.

Thank you for any ideas.

juzo4321
  • 23
  • 3
  • what is the expected output with input = `B1` or `A0A` – fubo Apr 07 '15 at 10:11
  • Firstly I want to see how should it work with 2 charactersets A->alpha 0->numeric . And for A0A > a0a , a0b , a0c ... a9z , b0a , b0b , b0c ... z9z . for example B can be uppercased alpha characters. – juzo4321 Apr 07 '15 at 10:17

1 Answers1

1

You could use Eric Lippert's code to produce combinations to implement this.

Here's a demonstration. The method you want to call is Combinations() - it accepts a pattern as per your requirements and outputs a sequence of combinations:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            string pattern = "AA00";

            foreach (var s in Combinations(pattern))
                Console.WriteLine(s);
        }

        public static IEnumerable<string> Combinations(string pattern)
        {
            string letters = "abcdefghijklmnopqrstuvwxyz";
            string digits  = "0123456789";

            var sets = pattern.Select(ch => ch == 'A' ? letters : digits);

            return Combine(sets).Select(x => new String(x.ToArray()));
        }

        public static IEnumerable<IEnumerable<T>> Combine<T>(IEnumerable<IEnumerable<T>> sequences)
        {
            IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };

            return sequences.Aggregate(
              emptyProduct,
              (accumulator, sequence) =>
                from accseq in accumulator
                from item in sequence
                select accseq.Concat(new[] { item }));
        }
    }
}

Note: I have omitted all argument checking and validation for the sake of brevity.


[EDIT] Here's the example extended to show how you can add other char sets:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication2
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            string pattern = "A0*ë";

            foreach (var s in Combinations(pattern))
                Console.WriteLine(s);
        }

        public static IEnumerable<string> Combinations(string pattern)
        {
            var sets = pattern.Select(charset);

            return Combine(sets).Select(x => new String(x.ToArray()));
        }

        private static string charset(char charsetCode)
        {
            switch (charsetCode)
            {
                case 'A': return "abcdefghijklmnopqrstuvwxyz";
                case '0': return "0123456789";
                case '*': return "!£$%^&*()_+=-";
                case 'ë': return "àáâãäåæçèéêë";

                // Add new charset codes and charsets here as desired.

                default:  throw new InvalidOperationException("Bad charset code: " + charsetCode);
            }
        }

        public static IEnumerable<IEnumerable<T>> Combine<T>(IEnumerable<IEnumerable<T>> sequences)
        {
            IEnumerable<IEnumerable<T>> emptyProduct = new[] {Enumerable.Empty<T>()};

            return sequences.Aggregate(
                emptyProduct,
                (accumulator, sequence) =>
                    from accseq in accumulator
                    from item in sequence
                    select accseq.Concat(new[] {item}));
        }
    }
}
Community
  • 1
  • 1
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • Thank you for quick answer. It is working perfectly ! Now how to use more character sets Example: B > Uppercased alpha C > alpha numeric etc.. So how to change 'sets' in the code to add another charsets? (I have poor knowledge about linq) – juzo4321 Apr 07 '15 at 11:03
  • @juzo4321 I added an extended example. You should be able to see how you can add new charset codes and their corresponding charset. – Matthew Watson Apr 07 '15 at 11:22
  • Thank you very much again. It works as perfect as I expected ! – juzo4321 Apr 07 '15 at 11:46