Need to generate 9 unique integers less than 100 so neither of the two has a sum equal to the other one / two numbers
I need to generate 9 unique integers less than 100 such that there are no numbers x, y and z such that x + y = z and there are no numbers a, b, c and d such that a + b = c + d in VB.
Here's my VB code, but it generates sets of numbers that don't satisfy the last condition.
Public class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Numbers(9) As Integer
Dim w As Integer
Dim x As Integer
Dim y As Integer
Dim z As Integer
S:
Randomize()
Numbers(1) = CInt(Int((99 * Rnd()) + 1))
w = 2
Do While w < 10
Numbers(w) = CInt(Int((99 * Rnd()) + 1))
x = 1
Do While x < w
If Numbers(w) = Numbers(x) Then
GoTo S
End If
x = x + 1
Loop
w = w + 1
Loop
w = 1
x = 1
y = 1
Do While w < 10
x = 1
y = 1
Do While x < 10
y = 1
Do While y < 10
If Numbers(y) = Numbers(x) + Numbers(z) Then
GoTo S
End If
y = y + 1
Loop
x = x + 1
Loop
w = w + 1
Loop
w = 1
x = 1
y = 1
z = 1
Do While w < 10
x = 1
y = 1
z = 1
Do While x < 10
y = 1
z = 1
Do While y < 10
z = 1
Do While z < 10
If w <> x And w <> y And w <> z And x <> y And x <> z And y <> z And Numbers(x) + Numbers(y) = Numbers(z) + Numbers(w) Then
GoTo S
End If
z = z + 1
Loop
y = y + 1
Loop
x = x + 1
Loop
w = w + 1
Loop
MsgBox(Numbers(1) & " " & Numbers(2) & " " & Numbers(3) & " " & Numbers(4) & " " & Numbers(5) & " " & Numbers(6) & " " & Numbers(7) & " " & Numbers(8) & " " & Numbers(9))
End Sub
End Class
What am I doing wrong?
source to share
Here is my suggestion.
I think you will find it more readable:
Private Function CreateArray() As Integer()
Dim Target As Integer()
'' Create a list of all integers from 1 to 100, randomly sorted.
Dim Source As List(Of Integer) = Enumerable.Range(1, 100).OrderBy(Function(orderby) Guid.NewGuid()).ToList()
Target = New Integer(8) {}
Dim i As Integer = 0
For Each CurrentNumber As Integer In Source
If ValidateNumber(CurrentNumber, Target) Then
Target(i) = CurrentNumber
i += 1
End If
If i = 9 Then
Exit For
End If
Next
Return Target
End Function
Private Function ValidateNumber(Number As Integer, Target As Integer()) As Boolean
if Target.Length > 1 then '' otherwise there is no need to test at all
For i As Integer = 0 To Target.Length - 3
For j As Integer = i + 1 To Target.Length - 2
'' First condition: the sum of any two numbers must be different than any other number
If Target(i) + Target(j) = Number OrElse Target(i) + Number = Target(j) OrElse Target(j) + Number = Target(i) Then
Return False
End If
For k As Integer = j + 1 To Target.Length - 1
'' Second condition: the sum of any two numbers must be different than the sum of any other two numbers
If Target(i) + Target(j) = Target(k) + Number OrElse Target(i) + Target(k) = Target(k) + Number OrElse Target(i) + Number = Target(j) + Target(k) Then
Return False
End If
Next
Next
Next
end if
Return True
End Function
You can see an example in this fiddle.
Update
I think I found the problem in the second condition: in the second part I wrote Target(i) + Target(k) = Target(k) + Number
, but it should have been Target(i) + Target(k) = Target(j) + Number
.
I found a problem while editing mine ValidateNumber
to be more readable by adding meaningful named variables for numbers.
This is another reason why you should always use meaningful named variables.
Private Function ValidateNumber(Number As Integer, Target As Integer()) As Boolean
Dim First, Second, Third As Integer
If Target.Length > 1 Then '' otherwise there is no need to test at all
For i As Integer = 0 To Target.Length - 3
First = Target(i)
For j As Integer = i + 1 To Target.Length - 2
Second = Target(j)
'' First condition: the sum of any two numbers must be different than any other number
If First + Second = Number OrElse First + Number = Second OrElse Second + Number = First Then
Return False
End If
For k As Integer = j + 1 To Target.Length - 1
Third = Target(k)
'' Second condition: the sum of any two numbers must be different than the sum of any other two numbers
If First + Second = Third + Number OrElse First + Third = Second + Number OrElse First + Number = Second + Third Then
Return False
End If
Next
Next
Next
End If
Return True
End Function
I also updated the fiddle so you can test it yourself.
source to share
Don't use a random number for this unless you're lucky. Just repeat all possible combinations and wait.
Sub Main()
Dim n(9) As Integer ' Contains the list of 9 numbers
Dim sums As New List(Of Integer) ' List of the sums of all the numbers
n(0) = 1
For x As Integer = 1 To 8
n(x) = n(x - 1) + 1
Next
Do
Dim x As Integer = 8
' Get the next number from the list
Do
n(x) += 1
If n(x) >= 100 Then
If x = 0 Then
Exit Do
End If
n(x) = n(x - 1) + 1
x -= 1
Else
Exit Do
End If
Loop
' Get the list of all the sums
sums.Clear()
For a As Integer = 0 To 7
For b As Integer = a + 1 To 8
sums.Add(n(a) + n(b))
Next
Next
Dim wrong As Boolean = False
' Is a sum equal to a number in the list?
For Each s As Integer In sums
For x = 0 To 8
If s = n(x) Then
wrong = True
End If
Next
Next
' Are two sums equal to each other?
For a As Integer = 0 To sums.Count - 2
For b As Integer = a + 1 To sums.Count - 1
If sums(a) = sums(b) Then
wrong = True
End If
Next
Next
' Everything passed!
If Not wrong Then
Exit Do
End If
Loop
For Each x As Integer In n
Console.WriteLine(x)
Next
Console.WriteLine("Done")
Console.ReadLine()
End Sub
source to share
I am trying to create a random number method.
Method in Vb.NET :
Public Function GenerateRandomNumbers(min As Integer, max As Integer, count As Integer, exceptNumbers As Integer()) As List(Of Integer)
If count > max - min Then
Throw New ArgumentOutOfRangeException("your count is more than min and max range!")
End If
Dim lst = New List(Of Integer)()
Dim rand = New Random()
While count >= 0
Dim value = rand.[Next](min, max)
Dim upValue As Boolean = False
While lst.Any(Function(x) x = value) OrElse exceptNumbers.Any(Function(x) x = value)
If value < min Then
value += 1
upValue = True
ElseIf value > max Then
Exit While
ElseIf upValue Then
value += 1
Else
value -= 1
End If
End While
lst.Add(value)
count -= 1
End While
Return lst
End Function
Now you can use this model:
Dim lst = GenerateRandomNumbers(0, 100, 9, New Integer() {1, 5, 8, 6, 10, 2})
source to share