I need to generate 9 unique integers less than 100, such that there exists no numbers x,y and z such that x + y = z and no numbers a,b,c and d such that a + b = c + d in VB.
Here's my VB code, but it generates number sets that doesn't satisfy the latter 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?
Here is my suggestion.
I think you'll 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've found the problem in the second condition: in the second part of it I wrote Target(i) + Target(k) = Target(k) + Number
, but it should have been Target(i) + Target(k) = Target(j) + Number
.
I've found the problem while editing my ValidateNumber
to be more readable by adding meaningful named variables for the numbers.
This is yet 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've also updated the fiddle, so you can test it yourself.