-1

I'm struggling in the making of algorithm that "shuffles" a set of numbers in such way that they are sorted in ascending order starting from 0 ,the next number must not exceed the previous one + 1, they must also have a length of 15 and every single number from the set of numbers must be included. For example if we have the numbers :

0, 1

the desired output is :

0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 (yes those are 14 zeros)

0,0,0,0,0,0,0,0,0,0,0,0,0,1,1

..

0,1,1,1,1,1,1,1,1,1,1,1,1,1,1

same goes if the numbers were

0, 1, 2

0,0,0,0,0,0,0,0,0,0,0,0,0,1,2 (every number must be included)

I tried the following and I failed miserably :

Version 1

private static List<List<int>> GetNumbers(int lastNumber)
    {
        if (lastNumber == 0)
        {
            return new List<List<int>> { new List<int> { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
        }
        int[] setOfNumbers = new int[lastNumber + 1];
        List<List<int>> possibleRoutes = new List<List<int>>().ToList();
        for (int i = 0; i <= lastNumber; i++)
        {
            setOfNumbers[i] = i;
        }
        var temp = new List<int>();
        int[] possibleRoute = new int[15];
        for (int j = 0; j < size - lastNumber; j++)
        {
            possibleRoute[j] = 0;
        }
        for (int j = lastNumber; j < possibleRoute.Length; j++)
        {
            for (int k = j; k > 0; k--)
            {
                possibleRoute[k] = lastNumber - 1;
            }
            for (int i = size - 1; i >= j; i--)
            {
                possibleRoute[i] = lastNumber;
            }
            possibleRoutes.Add(possibleRoute.ToList());
            generalCounter++;
        }
        return possibleRoutes;
    }

Version 2

private static List<List<int>> GetNumbers(int lastNumber)
    {
        if (lastNumber == 0)
        {
            return new List<List<int>> {new List<int> {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
        }
        int[] setOfNumbers = new int[lastNumber + 1];
        List<List<int>> possibleRoutes = new List<List<int>>().ToList();
        for (int i = 0; i <= lastNumber; i++)
        {
            setOfNumbers[i] = i;
        }
        var temp = new List<int>();
        int[] possibleRoute = new int[15];
        for (int j = 0; j < size - lastNumber; j++)
        {
            possibleRoute[j] = 0;
        }
        for (int i = 1 ; i <= lastNumber ; i++)
        {
            int newNumber = lastNumber - i;
            for (int k1 = i + 1; k1 <= size; k1++)
            {
                for (int j = possibleRoute.Length - 1; j > k1 - i - 1; j--)
                {
                    possibleRoute[j] = lastNumber;
                }
                for (int k = i; k <= k1 - 1; k++)
                {
                    possibleRoute[k] = newNumber;
                }
                possibleRoutes.Add(possibleRoute.ToList());
                generalCounter++;
            }
        }
        return possibleRoutes;
    }
Community
  • 1
  • 1
KOPEUE
  • 260
  • 4
  • 15
  • Can you demonstrate what you've tried so far? – rory.ap Apr 05 '16 at 19:39
  • 1
    Now can you please explain what *specifically* you're having trouble with? What isn't working? Remember, the people on this site are *real* people who have trouble guessing what's on your mind without you telling us. We aren't going to just glance at your code and be able to see what's wrong with it, nor are we going to take it "back to our desk" and spend hours trying to figure out how to get it working. This site is about *specific* problems. – rory.ap Apr 05 '16 at 19:42
  • Well the code is completely broken there's more than 1 problem in there, and I'm honestly expecting a different approach then mine I really don't people to work with my code because it's way too bad, I'm still beginner and I posted it just to show you that I tried all I could but couldn't make it work. – KOPEUE Apr 05 '16 at 19:45

2 Answers2

1

I misunderstood the problem. Starting this answer over.

Let's state the problem another way.

We have a number of items, fifteen.

We have a number of digits, say 0, 1, 2.

We wish to know what are the combinations of x zeros, y ones and z twos such that x + y + z = 15 and x, y and z are all at least one.

So, reduce it to an easier problem. Suppose there is one zero. Now can you solve the easier problem? The problem is now smaller: the problem is now "generate all the sequences of length 14 that have at least one 1 and one 2". Do you see how to solve the easier problem?

If not, break it down into a still easier problem. Suppose there is one 1. Can you solve the problem now? The problem now is to find all the sequences that have thirteen 2s in them, and there's only one of those.

Now suppose there are two 1s. Can you solve the problem there?

Do you see how to use the solution to the easier problems to solve the harder problems?

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • As far as I understand you suggest me to create a List with all the currently known solution for specific length and than recursively add more into it. I might be completely wrong but even if I'm not I don't see how can I implement it .. – KOPEUE Apr 05 '16 at 19:55
  • 1
    @KOPEUE: Don't worry about implementation details like lists at this point. You need to be able to solve small versions of the problem on pieces of paper. Write down all the solutions of length three, drawn from the digits 0, 1, 2, for example. There are not very many of them. Now, given that list of solutions, describe how you could transform it into a list of solutions of length four. Get some insight into how to solve the problem with a computer by solving it by hand first. – Eric Lippert Apr 05 '16 at 20:36
  • @KOPEUE: Here, I'll work an example for you. – Eric Lippert Apr 05 '16 at 20:41
  • 2
    Strictly speaking, that's not a solution since the original problem requires that "every single number from the set of numbers must be included" (i.e. the first number in the sequence needs to be 0, assuming the sets includes a 0.) So the recursion needs to include the starting value as well as the ending value and the size of the set. – rici Apr 05 '16 at 20:44
  • One thing @EricLippert all the combinations must start with 0 and include all the numbers also 0 2 breaks the rule because 2 > 0 + 1 – KOPEUE Apr 05 '16 at 21:04
  • @KOPEUE: Ah, I misunderstood the constraints on the problem. I'll fix my worked example. – Eric Lippert Apr 05 '16 at 21:09
0

A simple strategy which works with a wide variety of problems like this is to list the possibilities in lexicographical order. In pseudocode, you would do something like this:

  1. Set V to the first possible sequence, in lexicographical order.

  2. Repeat the following:

    • Output V
    • If possible, set V to the next sequence in lexicographical order.
    • If that was not possible, exit the loop.

For many cases, you can solve the second sub-problem ("set V to the next sequence") by searching backwards in V for the right-most "incrementable" value; that is, the right-most value which could be incremented resulting an a possible prefix of a sequence. Once that value has been incremented (by the minimum amount), you find the minimum sequence which starts with that prefix. (Which is a simple generalization of the first sub-problem: "find the minimum sequence".)

In this case, both of these sub-problems are simple.

  • A value is incrementable if it is not the largest number in the set and it is the same as the preceding value. It can only be incremented to the next larger value in the set.

  • To find the smallest sequence starting with a prefix ending with k, start by finding all the values in the set which are greater than k, and putting them in order at the end of the sequence. Then fill in the rest of the values after the prefix (if any) with k.

For the application of this approach to a different enumeration problem, see https://stackoverflow.com/a/30898130/1566221. It is also the essence of the standard implementation of next_permutation.

Community
  • 1
  • 1
rici
  • 234,347
  • 28
  • 237
  • 341