none
Combinate values RRS feed

  • Question

  • Hi all,

    I need to write a method that accept a list of elements (between 1 and 10) and that returns a list of list that contains all possible sequences.

    Exemple: input

    { "a", "b", "c" }

    Output : 

    { "a" },
    { "b" },
    { "c" },
    { "a", "b" },
    { "a", "c" },
    { "b", "a" },
    { "b", "c" },
    { "c", "a" },
    { "c", "b" },
    { "a", "b", "c" },
    { "a", "c", "b" },
    { "b", "a", "c" },
    { "b", "c", "a" },
    { "c", "a", "b" },
    { "c", "b", "a" },

    Seems easy, but I fail to find how to do that

    Thank for help

    Jojo

    Monday, June 11, 2018 2:10 PM

All replies

  • This may help: https://www.codeproject.com/Articles/26050/Permutations-Combinations-and-Variations-using-C-G

    In general, searching for "c# combinatorics" or "combinatorics algorithms" may help you along.

    Monday, June 11, 2018 3:35 PM
  • If you are interested in LINQ:

    string[] values = { "a", "b", "c" };
    
    IEnumerable<IEnumerable<string>> result = new[] { new string[0] };
    
    for( int n = 1; n <= values.Count(); ++n )
    {
       result = result.SelectMany( r => values.Where( v => !r.Contains( v ) ), ( r, v ) => r.Concat( new[] { v } ) );
    
       foreach( var row in result )
       {
          foreach( var col in row ) Console.Write( col + "  " );
          Console.WriteLine();
       }
    }
    

    • Proposed as answer by Dolen Zhang Tuesday, June 12, 2018 9:44 AM
    Monday, June 11, 2018 5:54 PM
  • Thanks for your answers,

    The mentionned code project seems interresting, but it will require more time for me to read all and understand.

    I was supposing that some simple LINQ instruction would do the job. I've tried the proposed code, the output is exactly what I was expecting ...but... the output is in the loop and prints temporary combination that are not in the final "result". If you print the result after the loop, there's only the collowing combinations 

    {"a", "b", "c" }, { "a", "c", "b" }, { "b", "a", "c" }, { "b", "c", "a" }, { "c", "a", "b" }, { "c", "b", "a"}

    and not the shortest ones.

    Anyway, with this start, I'll probably be able to get what I need.

    Thanks again

    Jojo


    • Edited by JojoShow Tuesday, June 12, 2018 2:40 PM
    Tuesday, June 12, 2018 2:40 PM
  • I have not tested this, but something like this should work . Note that it needs to be seeded with an empty string and you may want remove it when you are done.

    private void Combinations(List<string> elementsToCombine) { int elementCount = elementsToCombine.Count; List<string> results = new List<string>(); results.Add(string.Empty); for (int resultLength = 1; resultLength < elementCount; resultLength++) { for (int resultIndex = 0; resultIndex<results.Count; resultIndex++) {

    if(results[resultIndex].Length == resultLength-1) {

    foreach (string element in elementsToCombine) { results.Add(results[resultIndex] + element); }

    } } } }

    Ethan


    Ethan Strauss


    • Edited by Ethan Strauss Wednesday, June 13, 2018 1:20 AM Needed to fix bug which would have created duplicates
    Tuesday, June 12, 2018 10:02 PM