LoginLogin

Random Array (Shuffle)

Root / FAQs / [.]

📌🔒
SamCreated:
Hello there. I'd like to know how to assign a random number to each part of an array while always having a different number. Example:
DIM A[5]
FOR I=0 TO 4
A[I]=RND(5)
NEXT
In this example, they should all have a number between 0 and 4, but the problem is that I can't make all of them be different (one 0, one 1, one 2, one 3 and one 4). Should I completely change the structure of my code, or only a small change should work? Thank you in advance for telling me your thoughts.

You'll have to keep track of what numbers have been used. One way that I'm sure isn't the best is to populate another array with the range of numbers you want, randomly select an index from there and check it against some value out of the range you want (for example -1 if you only want positive integers), replace the value you took with the "used" one, and then select another random index until you get one that isn't the used value and keep doing that until you filled your array.
DIM A[5] = [-1,-1,-1,-1,-1]
DIM NUMS[5] = [0,1,2,3,4]
FOR I=0 TO 4
  WHILE A[I] == -1
   T = RND(5)
   IF NUMS[T] != -1
     A[I] = NUMS[T]
     NUMS[T] = -1
   ENDIF
  WEND
NEXT
EDIT: See SquareFingers' post below

You're going to need to keep track of what numbers have been used or can be used. If you're only going to 4, I'd recommend creating a list of all the numbers you can use. Then you can randomly pick a number from that array, store it in your destination and remove it from the pool. EDIT: What Lumage just posted.

Thanks.

N%=5
DIM A%[N%]
FOR I%=0 TO N%-1
 A%[I%]=I%
NEXT
FOR I%=N%-1 TO 1 STEP -1
 SWAP A%[I%],A%[RND(I%+1)]
NEXT

Another solution is sort them based on another randomized array. DIM A[5] DIM B[5] FOR I=0 to 4 A[ I ] =I B[ I ] =RND(100) NEXT SORT B,A

Another way to do it is with swaps
DIM A[5]

FOR I=0 TO 4
A[I]=I
NEXT

FOR I=0 TO 100
SWAP A[RND(5)] , A[RND(5)]
NEXT
It may not be the most efficient code, but it's clean and easy to follow. Edit: yikes, squarefingers beat me to it, lol.

DIM RANNUM[61]
FOR U=0 TO 60
RUNNUM[U]=U
NEXT
Completely random, I promise.

lol Here's another one using strings...
A$="01234"
FOR I=4 TO 0 STEP -1
  R=RND(I+1)
  S$=S$+MID$(A$,R,1)
  A$=SUBST$(A$,R,1,"")
NEXT
? S$

Using string indexing with DrZog's string method makes it a bit shorter and look a bit neater:
A$="01234"
FOR I=5 TO 1 STEP -1
 R=RND(I)
 S$=S$+A$[R]
 A$[R]=""
NEXT
? S$
DrZog's earlier post with swaps won't quite give every permutation exactly equal probability, and neither will brilliance360's, though the deviation will be very very small in either case. A (very very very small) improvement to brilliance360's code, in this respect, would be to use RNDF() instead of RND(100).

SquareFinger's algorithm is orifinally developped by Fisher and Yates, So it is called Fisher-Yates shuffle. https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

SquareFinger's algorithm is orifinally developped by Fisher and Yates, So it is called Fisher-Yates shuffle. https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
It's such a simple, common sense algorithm that it's easily possible to discover it without any knowledge of it existing beforehand. I wasn't aware of it, even though my implementation had bias issues. (my apologies if you posted this just as an FYI)