2

First i want to say i'm still learning so my programming skills are not very good, and i'm willing to accept any advice you have. Second i'm still learning english so i want to say sorry for the inconvenience.

Well my problem is this, i need help improving my algorithm or any information about it, i don't know what words use for searching this.

The algorithm is supposed to find all the combinations of numbers that added is equal to a given number. Example: if i have the number 6 my results are supposed to be: [1,5],[2,4],[2,2,2],[3,3]

i have the following:

public List<List<int>> discompose(int number)
    {
        List<List<int>> discomposedPairs = new List<List<int>>();
        if (number <= 3)
            return discomposedPairs;
        int[] numsForCombine = new int[number-1];
        for(int i = 1; i < number;i++){
            numsForCombine[i - 1] = i;
        }
        int ini = 0;
        int end = numsForCombine.Length - 1;
        while (ini <= end)
        {
            List<int> pair = new List<int>();
            pair.Add(numsForCombine[ini++]);
            pair.Add(numsForCombine[end--]);
            discomposedPairs.Add(pair);
        }
        return discomposedPairs;
    }
    public List<List<int>> discomposePair(List<int> pair)
    {
        List<List<int>> parDisc = new List<List<int>>();
        for (int i = 0; i < pair.Count; i++) {
            if (pair[i] > 3)
            {
                List<List<int>> disc = discomposeList(discompose(pair[i]));
                foreach (List<int> item in disc)
                {
                    if (i > 0)
                    {
                        var temp = pair.GetRange(0, i);
                        temp.AddRange(item);
                        parDisc.Add(temp);
                    } else {
                        item.AddRange(pair.GetRange(i+1, pair.Count-(i+1)));
                        parDisc.Add(item);
                    }
                }
            }
        }
        return parDisc;
    }
    public List<List<int>> discomposeList(List<List<int>> list)
    {
        List<List<int>> mainDiscomposedList = new List<List<int>>();
        for (int i = 0; i < list.Count; i++)
        {
            mainDiscomposedList.Add(list[i]);
           List<List<int>> discomposedSubset = discomposePair(list[i]);
            foreach(List<int> item in discomposedSubset){
                mainDiscomposedList.Add(item);
            }
        }
        return mainDiscomposedList;
    }

The first method descompose the number given in pairs that added are equal the number given. The second and the third method are the ugliest they are recursive and have bucles so they don't have any good performance. Between the two generates a List with numbers as i the problem says but there are a few inconvenients: 1) Don't have good performance 2) Gives a lot of repetitive sequences here is the output for the number 10

[2,8,]
[2,2,6,]
[2,2,2,4,]
[2,2,2,2,2,]
[2,2,3,3,]
[2,3,5,]
[2,3,2,3,]<-------------repeated
[2,4,4,]
[2,2,2,4,]<-------------repeated
[2,4,2,2,]<-------------repeated
[3,7,]
[3,2,5,]<-------------repeated
[3,2,2,3,]<-------------repeated
[3,3,4,]
[3,3,2,2,]
[4,6,]
[2,2,6,]<-------------repeated
[4,2,4,]<-------------repeated
[4,2,2,2,]<-------------repeated
[4,3,3,]<-------------repeated
[5,5,]
[2,3,5,]<-------------repeated
[5,2,3,]<-------------repeated

Finally i want to improve the performance and have the less possible repeated items being a repeated item [1,1,3], [1,3,1], [3,1,1] [Here is the full project link]1

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
Helios
  • 21
  • 1
  • 3
  • [1,6] = 7 ................ – Mitch Wheat Feb 24 '13 at 03:31
  • I am having a lot of trouble following each variable since they are not in English (maybe that's just me, though). If you could either comment each one in English or just change the variables around, then I might be able to help. – Holden Lewis Feb 24 '13 at 03:35
  • [1,6] a typo sorry for that... about the variables i'll do something about that just a moment... – Helios Feb 24 '13 at 03:37
  • 2
    possible duplicate of [Generating the partitions of a number](http://stackoverflow.com/questions/400794/generating-the-partitions-of-a-number) – mbeckish Feb 24 '13 at 04:47

1 Answers1

6

Here's one approach that first builds the combinations into a tree structure, then arranges them into lists of ints:

internal class Combination
{
    internal int Num;
    internal IEnumerable<Combination> Combinations;
}

internal static IEnumerable<Combination> GetCombinationTrees(int num, int max)
{
    return Enumerable.Range(1, num)
                     .Where(n => n <= max)
                     .Select(n =>
                         new Combination
                         {
                             Num = n,
                             Combinations = GetCombinationTrees(num - n, n)
                         });
}

internal static IEnumerable<IEnumerable<int>> BuildCombinations(
                                               IEnumerable<Combination> combinations)
{
    if (combinations.Count() == 0)
    {
        return new[] { new int[0] };
    }
    else
    {
        return combinations.SelectMany(c =>
                              BuildCombinations(c.Combinations)
                                   .Select(l => new[] { c.Num }.Concat(l))
                            );
    }
}

public static IEnumerable<IEnumerable<int>> GetCombinations(int num)
{
    var combinationsList = GetCombinationTrees(num, num);

    return BuildCombinations(combinationsList);
}

public static void PrintCombinations(int num)
{
    var allCombinations = GetCombinations(num);
    foreach (var c in allCombinations)
    {
        Console.WriteLine(string.Join(", ", c));
    }
}

When run with the input value 6, this produces:

1, 1, 1, 1, 1, 1
2, 1, 1, 1, 1
2, 2, 1, 1
2, 2, 2
3, 1, 1, 1
3, 2, 1
3, 3
4, 1, 1
4, 2
5, 1
6
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • 1
    i didn't understand anything about your code but i suppose that with a little research i will be able to. Thanks a lot. – Helios Feb 24 '13 at 05:01
  • @mbeckish thanks for the link i couldn't research more because i didn't kwnow how is called this. and well loooks like it is a duplicated thread sorry about that... – Helios Feb 24 '13 at 05:04
  • for versions earlier than .NET 4.0, the PrintCombinations method should have Console.WriteLine(string.Join(",", c.Select(x => x.ToString()).ToArray())); – Prathap Aug 16 '14 at 17:14
  • To find ALL combinations (regardless of recurrence), remove `.Where(n => n <= max)` in `GetCombinationTrees` method. This gets the total of all non-zero compositions. –  Mar 25 '18 at 22:16