Reputation: 11
I would like for my code to express the sum of random numbers generated to be in a range. Between 120 and 235.
What's the best way to do that without changing my code too much?
I'm positive it needs to create 2 Dims
and an if else
statement, but I can't word it properly.
I'm using Visual Studio 2017
Public Class Form1
Private Sub Button1_Click(ByVal sender As Object, e As EventArgs) Handles Button1.Click
Randomize()
TextBox1.Text = Rand(1, 100)
TextBox2.Text = Rand(Long.Parse(TextBox1.Text), 100)
TextBox3.Text = Rand(Long.Parse(TextBox2.Text), 100)
TextBox4.Text = Rand(Long.Parse(TextBox3.Text), 100)
TextBox5.Text = Rand(Long.Parse(TextBox4.Text), 100)
TextBox6.Text = Rand(Long.Parse(TextBox5.Text), 100)
End Sub
Private Function Rand(v As Long) As String
Throw New NotImplementedException()
End Function
Private Function Rand(ByVal Low As Long, ByVal High As Long) As Long
Rand = Int((High - Low + 1) * Rnd()) + Low
End Function
End Class
Upvotes: 0
Views: 424
Reputation: 32248
I'ld suggest to use the .Net Random class to generate random numbers. It's also simpler to use.
Find the first random number between 0
and the Minimum value, then the second random number will be in range: randomMin(MinValue) => (MinValue - randomMin, MaxValue - randomMin)
:
randomMin = rnd1.Next(Min + 1)
randomMax = rnd2.Next(Min - randomMin, Max - randomMin + 1)
result = randomMin + randomMax
To remember that, in the Random class, the upper limit is exclusive, so we need to add 1 to the Max value to include it in the range of random values.
Make a sample test:
(These code samples suppose that the VB.Net version in use is at least V.14, VS 2015+)
Private rnd1 As Random = New Random()
Private rnd2 As Random = New Random()
'(...)
Dim Min As Integer = 120
Dim Max As Integer = 235
For i = 0 To 100
Dim randomValues = GetRandomNumbersInRange(Min, Max)
Console.WriteLine($"Random Min: {randomValues.rndMin} Random Max {randomValues.rndMax}")
Console.WriteLine($"Sum: {randomValues.rndMin + randomValues.rndMax}")
Next
'(...)
Private Function GetRandomNumbersInRange(Min As Integer, Max As Integer) As
(rndMin As Integer, rndMax As Integer)
Dim randomMin As Integer = rnd1.Next(Min + 1)
Return (randomMin, rnd2.Next(Min - randomMin, Max - randomMin + 1))
End Function
If you want the method to directly return the sum, you could change the method return type like this:
Dim Min As Integer = 120
Dim Max As Integer = 235
For i = 0 To 100
Console.WriteLine(GetSumRandomNumbersInRange(Min, Max))
Next
'(...)
Private Function GetSumRandomNumbersInRange(Min As Integer, Max As Integer) As Integer
Dim randomMin As Integer = rnd1.Next(Min + 1)
Return randomMin + rnd2.Next(Min - randomMin, Max - randomMin + 1)
End Function
The random numbers could also be selected with:
randomMid(MaxValue - MinValue) => (MinValue, MaxValue - randomMid)
It this case, possibly implemented as:
Private Function GetSumRandomNumbersInRange2(Min As Integer, Max As Integer) As Integer
Dim randomFirst As Integer = rnd1.Next(Max - Min + 1)
Return randomFirst + rnd2.Next(Min, Max - randomFirst + 1)
End Function
Upvotes: 1
Reputation: 54417
Here is the algorithm I would use to accomplish this task:
You now have six random numbers with a sum in the desired range. You may just need to add or subtract 1 to one of the values in case rounding has pushed the sum outside the range. You can choose one of the numbers at random to adjust.
'Create a random number generator.
Dim rng As New Random
'Create a random number in the desired range for the final sum.
Dim sum = rng.Next(120, 235 + 1)
'Generate six proportional values as fractions of 1.0.
Dim proportions = Enumerable.Range(1, 6).Select(Function(n) rng.NextDouble()).ToArray()
'Get the sum of all the proportional values.
Dim proportionsSum = proportions.Sum()
'Normalise the proportional values so that they sum to 1.0
proportions = Array.ConvertAll(proportions, Function(r) r / proportionsSum)
'Break the final sum up into the specified proportions.
Dim numbers = Array.ConvertAll(proportions, Function(r) CInt(Math.Round(r * sum)))
'Adjust as required if rounding has pushed the sum below the minimum value.
Do While numbers.Sum() < 120
'Get a random element index.
Dim index = rng.Next(0, numbers.Length)
'Increment the element at that index.
numbers(index) = numbers(index) + 1
Loop
'Adjust as required if rounding has pushed the sum above the maximum value.
Do While numbers.Sum() > 235
'Get a random element index.
Dim index = rng.Next(0, numbers.Length)
'Decrement the element at that index.
numbers(index) = numbers(index) - 1
Loop
'The numbers array now contains six random values with a sum in the range 120 to 235.
Upvotes: 0