1

I'm new at this. I want to create an array of 16 elements. Let's say that my array is ReDim arr(15) as Integer and in that array I want to put the numbers from 1 to 16 but scrambled, for example arr(0) = 3, arr(5) = 8 and so on.

Community
  • 1
  • 1
Luis
  • 11
  • 1
  • 3

2 Answers2

2

Give this a try:

Sub MAIN()
   Dim ary(1 To 16) As Variant
   Dim i As Long, msg As String

   For i = 1 To 16
      ary(i) = i
   Next i

   Call Shuffle(ary)

   msg = ""
   For i = 1 To 16
      msg = msg & vbCrLf & ary(i)
   Next i
   MsgBox msg
End Sub

Sub Shuffle(InOut() As Variant)
    Dim HowMany As Long, i As Long, J As Long
    Dim tempF As Double, temp As Variant

    Hi = UBound(InOut)
    Low = LBound(InOut)
    ReDim Helper(Low To Hi) As Double
    Randomize

    For i = Low To Hi
        Helper(i) = Rnd
    Next i


    J = (Hi - Low + 1) \ 2
    Do While J > 0
        For i = Low To Hi - J
          If Helper(i) > Helper(i + J) Then
            tempF = Helper(i)
            Helper(i) = Helper(i + J)
            Helper(i + J) = tempF
            temp = InOut(i)
            InOut(i) = InOut(i + J)
            InOut(i + J) = temp
          End If
        Next i
        For i = Hi - J To Low Step -1
          If Helper(i) > Helper(i + J) Then
            tempF = Helper(i)
            Helper(i) = Helper(i + J)
            Helper(i + J) = tempF
            temp = InOut(i)
            InOut(i) = InOut(i + J)
            InOut(i + J) = temp
          End If
        Next i
        J = J \ 2
    Loop
End Sub

enter image description here

Gary's Student
  • 95,722
  • 10
  • 59
  • 99
1

Here is some very lazy code:

Dim arr(15) As Integer
Dim i As Integer, j As Integer
i = 1
Do
    j = Int(16 * Rnd)
    If arr(j) = 0 Then
        arr(j) = i
        i = i + 1
    End If
Loop Until i = 17

Rnd generates a single from 0 to 1, multiply that by 16 and strip the decimal portion with Int and it will give you a random number from 0 to 15.

It isn't efficient, I wouldn't use this in production, but it'll do the job.

Hope this helps!

Andy Wynn
  • 1,171
  • 7
  • 11
  • No it wont, I thought of that in this code. If the rnd function returns a value that has already been used, it will just restart the loop. – Andy Wynn Dec 02 '15 at 13:54
  • You are correct, I apologize and will delete my comment. I missed the if statement. This works great for the requested small subset. I would be interested in knowing the average number loops to get them all filled. By the odds there is a chance of an infinite loop if the subset got to large. That is not what was asked, and this small of a subset would not run that risk. – Scott Craner Dec 02 '15 at 14:17
  • 1
    Yeah, as I said it isn't great code but it'll do the job here of you are only going to use it for small sets. I ran it 500 times and it took an average of 35 loops to complete, but all 500 took less than a second, so I'm not too worried. If this was code for a serious production I would write it properly. – Andy Wynn Dec 03 '15 at 15:12