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.

6
  • arr(15) only gives you 15 elements. Commented Nov 4, 2015 at 23:53
  • 1
    So...have you tried anything Commented Nov 4, 2015 at 23:55
  • 3
    arr(15) (aka arr(0 to 15)) gives 16 elements. Commented Nov 4, 2015 at 23:56
  • I thought the number gives you number of elements so arr(15) would be 0-14? But Jeeped is always right ^_^; Edit: ah, the number is upperbound not elements. But if you have option base of 1, then it's elements =P Edit2: so I have been doing it all wrong XD Commented Nov 4, 2015 at 23:57
  • Yeah, if just a single value is in the brackets, it treats it as the upper bound, with 0 as the lower bound. Commented Nov 5, 2015 at 0:01

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

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!

3 Comments

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.
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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.