[Coding.Tips++] // Equally Sized Random Piles
Alright let’s start with some coding tips and tricks. This might not be rocket science, but i find it really interesting and useful.
:: The Challenge
A while ago i had to split a number into x-random piles. The sum of all piles must be the number and each pile must have the same chance of getting the same size.
It’s a bit hard for me to explain it but let me give you an example:
Imagine you have a piece of paper (a long strip). You want to cut it into 5 pieces where every piece has the same chance of being somewhere between 1 and maxLength – 1 cm long.
For example if your piece of paper is 20 cm long and you need 5 pieces, you don’t just want to make a cut every 1-4 cm or something and use the rest for your last number. Then you might end up with something like 3, 4, 2, 4, 7. The last piece will always have a higher chance to be bigger than every other piece.
So we need to find a system that gives every piece the same chance of being as long as it’s other paper friends!
If you think about it for a while, this is not too easy, unless you already know about the method (or a similar one) i am going to talk about.
:: The Scenario
So let’s imagine your number is 30 and you need to create 5 random “equal” piles out of it.
For example your end result could look like 4, 6, 3, 7, 10. All those numbers would add up to 30 in the end. But how do you get them? Well it’s not too hard actually!
NOTE: All examples are in sort-of pseudo code.
So let’s define some things first:
|
1 2 |
int maxValue = 30; int amountOfPiles = 5; |
We know that our max value is 30 and that we need 5 piles in the end. The next step would be to iterate amountOfPiles – 1 times through our maxValue and pick random numbers. However there are 2 conditions:
- Pick a random number between 1 and maxValue -1
- You can not have the same random number twice
|
1 2 3 4 5 6 7 8 9 10 11 |
int maxValue = 30; int amountOfPiles = 5; int[] randomNumbers = int[amountOfPiles - 1]; for(i = 0; i < amountOfPiles - 1; i++) { do { int nextRandomNumber = randomnumber between 1 and (maxValue - 1); } while randomNumbers does contain nextRandomNumber; randomNumbers[i] = nextRandomNumber; } |
Now we will have 4 numbers that are somewhere between 1 and 29 each. Of course this is not what we want, cause adding up all those numbers could be way over 30!
Instead imagine our max number is a 30 cm piece of paper and the 4 random numbers we just created are cuts. This will leave you with what? Exactly! 5 pieces of paper! Now that sounds more like what we want.
All we have to do now is figure out how long each paper piece is, which we can achieve by doing following:
- Add the 0 and maxValue back to your randomNumbers
- Sort your randomNumbers ascending
- Get the difference between each following randomNumber and you will have your 5 piles!
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
int maxValue = 30; int amountOfPiles = 5; int[] randomNumbers = int[amountOfPiles - 1]; for(i = 0; i < amountOfPiles - 1; i++) { do { int nextRandomNumber = randomnumber between 1 and (maxValue - 1); } while randomNumbers does contain nextRandomNumber; randomNumbers[i] = nextRandomNumber; } print(randomNumbers) // Output: 8, 4, 2, 13, 22 // Add min and max of maxValue randomNumbers.Add(0); randomNumbers.Add(maxValue); // Sort it ascending randomNumbers.sort(); print(randomNumbers) // Output: 0, 2, 4, 8, 13, 22, 30 int[] result = int[numberOfPiles]; for(int i = 0; i < randomNumbers.length - 1; i++) { // Get the difference between two following numbers result[i] = randomNumbers[i + 1] - randomNumbers[i]; } print(result) // Output: 2, 2, 4, 5, 9, 8 // Which results into 30 when adding all up! |
This may be a long bit of code but it garantees you that every pile you get has an equal chance of size.
Hope this wasn’t too confusing and you actually learned from it!
Creep you guys later <3

