Results 1 to 5 of 5

Thread: [VB6] - Lottery-Algorithm

  1. #1

    Thread Starter
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,262

    [VB6] - Lottery-Algorithm

    On a german Forum I developed the following Lottery-Algorithm (which i haven't found on the Internet in this form).

    I would like to hear your opinions and/or suggestions to improve it

    EDIT: cleaned up Version: https://www.vbforums.com/showthread....=1#post5556369

    vb Code:
    1. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    2.  
    3. Sub Lottery(ByVal DrawNumbers As Long, ByVal TotalNumbers As Long)
    4. Dim arrSource() As Long    
    5. Dim arrDest() As Long
    6.  
    7. Dim i As Long
    8. Dim j As Long
    9. Dim Counter As Long
    10. Dim RandomNumber As Long
    11.  
    12.     'What Lottery is played
    13.     ReDim arrDest(1 To DrawNumbers)
    14.     ReDim arrSource(1 To TotalNumbers)
    15.    
    16.     'Create Source-Array
    17.     For i = 1 To TotalNumbers
    18.    
    19.         arrSource(i) = i
    20.    
    21.     Next
    22.    
    23.     Counter = 0
    24.  
    25.     Randomize
    26.  
    27.     Do
    28.  
    29.         RandomNumber = Int(UBound(arrSource) * Rnd + 1)
    30.    
    31.         Counter = Counter + 1
    32.         arrDest(Counter) = arrSource(RandomNumber)
    33.        
    34.         'Cutting out the RandomNumber drawn
    35.         For j = RandomNumber + 1 To UBound(arrSource)
    36.        
    37.             CopyMemory arrSource(j - 1), arrSource(j), 4
    38.            
    39.         Next
    40.        
    41.         'Cut down the Source-Array
    42.         ReDim Preserve arrSource(1 To UBound(arrSource) - 1)
    43.            
    44.     Loop Until Counter = DrawNumbers
    45.    
    46.     For i=1 to DrawNumbers
    47.      
    48.          Debug.Print arrDest(i)
    49.  
    50.     Next
    51.  
    52. End Sub
    53.  
    54. 'Calling the function with
    55. Call Lottery (6, 49)
    Last edited by Zvoni; Feb 16th, 2022 at 03:05 AM.

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: [VB6] - Lottery-Algorithm

    That is generally good, but there are a couple of relatively minor issues.

    While CopyMemory has its uses, moving one Long (even if done 49*6 times in total) is not worth it - the overhead of calling an API outweighs the speed benefit.

    On a semi-related note, ReDim Preserve is one of the slowest things you can do, so if you care about speed, try to avoid it. One way is to use a variable to indicate the "ubound" position, and when you want to remove an item just move the item at "ubound" to it, then decrease the "ubound" variable. In cases like this one (where you create the array only to add/remove items), a Collection may be a better idea.

  3. #3

    Thread Starter
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,262

    Re: [VB6] - Lottery-Algorithm

    Quote Originally Posted by si_the_geek View Post
    That is generally good, but there are a couple of relatively minor issues.

    While CopyMemory has its uses, moving one Long (even if done 49*6 times in total) is not worth it - the overhead of calling an API outweighs the speed benefit.

    On a semi-related note, ReDim Preserve is one of the slowest things you can do, so if you care about speed, try to avoid it. One way is to use a variable to indicate the "ubound" position, and when you want to remove an item just move the item at "ubound" to it, then decrease the "ubound" variable. In cases like this one (where you create the array only to add/remove items), a Collection may be a better idea.
    Hi Si,

    thx for the idea.

    You mean something like this?

    vb Code:
    1. Sub Lottery(ByVal DrawNumbers As Long, ByVal TotalNumbers As Long)
    2.     Dim arrSource() As Long
    3.     Dim arrDest() As Long
    4.      
    5.     Dim i As Long
    6.     Dim UpperBound As Long
    7.     Dim Counter As Long
    8.     Dim RandomNumber As Long
    9.      
    10.         'What Lottery is played
    11.         ReDim arrDest(1 To DrawNumbers)
    12.         ReDim arrSource(1 To TotalNumbers)
    13.        
    14.         'Create Source-Array
    15.         For i = 1 To TotalNumbers
    16.        
    17.             arrSource(i) = i
    18.        
    19.         Next
    20.        
    21.         Counter = 0
    22.         UpperBound = TotalNumbers
    23.  
    24.         Randomize
    25.      
    26.         Do
    27.      
    28.             RandomNumber = Int(UpperBound * Rnd + 1)
    29.        
    30.             Counter = Counter + 1
    31.             arrDest(Counter) = arrSource(RandomNumber)
    32.            
    33.             'Swapping the RandomNumber drawn with the Number at UpperBound
    34.             arrSource(RandomNumber) = arrSource(UpperBound)
    35.  
    36.             UpperBound = UpperBound - 1
    37.                
    38.         Loop Until Counter = DrawNumbers
    39.        
    40.         For i = 1 To DrawNumbers
    41.          
    42.              Debug.Print arrDest(i)
    43.      
    44.         Next
    45.      
    46.     End Sub
    47.    
    48.  
    49.     'Calling the function with
    50.     Call Lottery(6, 49)

    As for the Collection-Object: I plainly dislike it, and i wouldn't be able to give you a reason for it ....

  4. #4
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: [VB6] - Lottery-Algorithm

    That's it.

    I can understand not liking the Collection as it isn't great in terms of a general-purpose tool, but it does have its uses - and in situations like this it can often be quicker (but for such a small data set, that wont matter).

  5. #5

    Thread Starter
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    5,262

    Re: [VB6] - Lottery-Algorithm

    Cleaned up version of it:
    Code:
    Sub CallLottery()
    Dim arrLottery() As Long
        arrLottery = Lottery(10, 49, True, False, 40) 'order unimportant, no duplicates --> Classic Lottery, in this case: Pick 10 Numbers from 40 to 49
        arrLottery = Lottery(6, 49, True, True)   'order unimportant, with duplicates
        arrLottery = Lottery(6, 49, False, False) 'order important, no duplicates --> Raffle, Horse-Race --> a call "Lottery(52, 52, False, False)" would be a full shuffle of a deck of cards
        arrLottery = Lottery(6, 49, False, True)  'order important, with duplicates --> Password-Generator?
    End Sub
    
    Public Function Lottery(ByVal DrawNumbers As Long, ByVal TotalNumbers As Long, Optional ByVal Sorted As Boolean = True, Optional ByVal Duplicates As Boolean = False, Optional ByVal LowerBound As Long = 1) As Long()
    Dim arrSource() As Long
    Dim arrDest() As Long
    Dim i As Long
    Dim UpperBound As Long
    Dim Counter As Long
    Dim RandomNumber As Long
        'Redim Arrays according to Arguments
        ReDim arrDest(1 To DrawNumbers)
        ReDim arrSource(LowerBound To TotalNumbers)
        'Build Source-Array
        For i = LBound(arrSource) To UBound(arrSource)
            arrSource(i) = i
        Next
        Counter = 0
        UpperBound = UBound(arrSource)
        Randomize
        Do
            RandomNumber = Int((UpperBound - LowerBound) * Rnd + LowerBound)
            Counter = Counter + 1
            arrDest(Counter) = arrSource(RandomNumber)
            If Not Duplicates Then
                'Swap drawn member with highest remaining member of Source-Array
                arrSource(RandomNumber) = arrSource(UpperBound)
                'reduce "virtually" the Source-Array
                UpperBound = UpperBound - 1
            End If
        Loop Until Counter = DrawNumbers
        If Sorted Then QuickSort arrDest
        Lottery = arrDest
    End Function
    
    Public Sub QuickSort(vSort As Variant, Optional ByVal lngStart As Variant, Optional ByVal lngEnd As Variant)
      If IsMissing(lngStart) Then lngStart = LBound(vSort)
      If IsMissing(lngEnd) Then lngEnd = UBound(vSort)
      Dim i As Long
      Dim j As Long
      Dim h As Variant
      Dim x As Variant
      i = lngStart: j = lngEnd
      x = vSort((lngStart + lngEnd) / 2)
      Do
        Do While (LCase(vSort(i)) < LCase(x)): i = i + 1: Loop
        Do While (LCase(vSort(j)) > LCase(x)): j = j - 1: Loop
        If (i <= j) Then
          h = vSort(i)
          vSort(i) = vSort(j)
          vSort(j) = h
          i = i + 1: j = j - 1
        End If
      Loop Until (i > j)
      If (lngStart < j) Then QuickSort vSort, lngStart, j
      If (i < lngEnd) Then QuickSort vSort, i, lngEnd
    End Sub
    Last edited by Zvoni; Feb 16th, 2022 at 03:12 AM.
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width