Melona380 - 1 year ago 46

Vb.net Question

Ok, so I want to divide a number randomly not evenly...

so lets say we have 20 I need 5 (Divisor) random chunks of 20.

4 4 4 4 4

Instead I want something like

6 2 4 3 5

It cant exceed the starting number

How can this be accomplished in vb?

Please help, Been stuck for hours.

Answer Source

```
Public Iterator Function DivideUp(ByVal Number As Integer, ByVal Groups As Integer, Optional ByVal Variance As Integer = 5) As IEnumerable(Of Integer)
Dim rnd As New Random()
While Groups > 0 AndAlso Number > 0
If Groups = 1 Then
Yield Number
Exit Function
End If
If Variance > Number - Groups Then Variance = Number - Groups
Dim temp As Integer = Number / Groups
temp += rnd.Next(Variance * -1, Variance)
Yield temp
Number -= temp
Groups -= 1
End While
End Function
```

Call it like this:

```
For Each num As Integer In DivideUp(20, 5)
Console.WriteLine(num)
Next
```

Something more conventional:

```
Public Function DivideUp(ByVal Number As Integer, ByVal Groups As Integer, Optional ByVal Variance As Integer = 5) As Integer()
Static rnd As New Random()
Dim result(Groups-1) As Integer
For i As Integer = 0 To Groups - 1
If Variance > Number - Groups Then Variance = Number - Groups
If i = Groups - 1 Then
result(i) = Number
Else
Dim temp As Integer = Number / Groups
temp += rnd.Next(Variance * -1, Variance)
result(i) = temp
Number -= temp
End If
Next i
Return result
End Function
```

If you want to get real fancy, you could use a log or natural log of your random variance to try make it more likely to stay closer to the median, ie: if your number divides evenly into groups of 4, do you want it to be rarer to see a 2 than a 3, rarer to see a 1 than a 2?

Finally, a test harness:

```
Dim errorCount As Integer = 0
For i As Integer = 0 To 10000
Dim items = DivideUp(100, 12)
Dim sum As Integer = 0
For Each j As Integer In items
Console.Write(j)
Console.Write(" ")
sum += j
Next j
Console.WriteLine("Total: {0}", sum)
If sum <> 100 Then
errorCount += 1
Dim tempColor = Console.ForegroundColor
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Error: incorrect total!")
Console.ForegroundColor = tempColor
End If
Next i
If errorCount > 0 Then
Dim tempColor = Console.ForegroundColor
Console.ForegroundColor = ConsoleColor.Red
Console.WriteLine("Error: incorrect total on {0} tries!")
Console.ForegroundColor = tempColor
End If
```

If you're working with real money, you need to use a cryptographic random number generator (the simple `Random`

type won't cut it) and you want to actually save each of these results (plus run it more like a few million times than just 10,000). Then you pull that data into something like R and graph your distributions, to make sure things flat (evenly distributed) with no visible bias. And you have to do this for a number of different Number/Group/Variance combinations. Failure to rigorously validate the randomness the purge any bias **will** result in someone gaming your system to win much more often than they should.