Option Explicit
Private Type Wheel
A As Currency
End Type
Private Type Digits
B(0 To 7) As Byte
End Type
Private BC(0 To 255) As Byte
Private WHL(0 To 20) As Wheel ' Do not use 0th item
Private Tested As Long
Const POOL = 9
Private Sub Form_Load()
Dim idx As Currency, tly&, cmb&, pik&, win&
' Build bit count lookup table
For idx = 0 To 255
BC(idx) = Nibs(idx And 15) + Nibs(idx \ 16)
Next
' Enumerate different combinations
For cmb = 1 To POOL
tly = 0
For idx = 0 To (2 ^ POOL) - 1
If BitCount(idx / 5000) = cmb Then
tly = tly + 1
End If
Next
Debug.Print "For 1 -"; POOL; "there are"; tly; "different combinations of"; cmb; "numbers."
Next
SetWheel 1, 1, 2, 3, 4, 5, 9
SetWheel 2, 1, 3, 5, 6, 7, 9
SetWheel 3, 2, 4, 5, 6, 7, 8
Debug.Print
Debug.Print "Result", "Covered", "(Tested)"
' Find matches
win = 7
For pik = 2 To win
For cmb = 2 To pik
Tested = 0
tly = Matching(cmb, pik, win)
Debug.Print cmb; "if"; pik, tly, "("; Tested; ")"
Next
Next
End Sub
Private Sub SetWheel(ByVal Index As Long, ParamArray Num())
Dim vlu, cell As Long, bit As Long
Dim dgt As Digits, Wh As Wheel
For Each vlu In Num
cell = vlu \ 8
bit = vlu And 7
dgt.B(cell) = dgt.B(cell) Or (2 ^ bit)
Next
LSet Wh = dgt
WHL(Index).A = Wh.A
End Sub
Private Function Matching(ByVal match As Long, ByVal pick As Long, ByVal win As Long) As Long
Dim op1 As Wheel, op2 As Wheel
Dim idx1 As Long, idx2 As Long
' Loop through all possible combinations
For idx1 = 0 To (2 ^ POOL)
' Limit to the 'if X' value
If BitCount(idx1 / 5000) = pick Then
op1.A = idx1 / 5000
DoEvents
Tested = Tested + 1
' Loop through items in wheel
idx2 = 1
While WHL(idx2).A > 0
op2.A = WHL(idx2).A
idx2 = idx2 + 1
' Check for matching numbers
If BitCount(BigAnd(op1, op2)) >= match Then
Matching = Matching + 1
' Point to 0th item in wheel to exit loop
idx2 = 0
End If
Wend
End If
Next
End Function
Private Function BigAnd(W1 As Wheel, W2 As Wheel) As Currency
Dim d1 As Digits, d2 As Digits, d3 As Digits
Dim idx As Long
LSet d1 = W1
LSet d2 = W2
For idx = 0 To 7
d3.B(idx) = d1.B(idx) And d2.B(idx)
Next
LSet W2 = d3
BigAnd = W2.A
End Function
Private Function BitCount(ByVal X As Currency) As Long
Dim W As Wheel, d As Digits
Dim idx As Long, cnt As Long
W.A = X
LSet d = W
For idx = 0 To 7
cnt = cnt + BC(d.B(idx))
Next
BitCount = cnt
End Function
Private Function Nibs(ByVal Value As Byte) As Long
Select Case Value
Case 0
Exit Function
Case 1, 2, 4, 8
Nibs = 1
Exit Function
Case 3, 5, 6, 9, 10, 12
Nibs = 2
Exit Function
Case 7, 11, 13, 14
Nibs = 3
Exit Function
Case 15
Nibs = 4
End Select
End Function