Shuffling an Int Array
BlitzMax Forums/BlitzMax Beginners Area/Shuffling an Int Array
| ||
How does this look? Basically it's shuffling an int array so you can have a weighted certain set of numbers in a random order. Does this look ok or how would you simplify/improve it? SeedRnd MilliSecs() Local bonus:Int[] = ShuffleIntArray([1,1,1,1,1,2,2,2,3,3]) For i = 0 To bonus.length-1 Print bonus[i] Next End Function ShuffleIntArray%[](array%[]) Local intArray%[] For i = 0 To array.length-1 Local r% = Rand(array.length)-1 intArray = intArray[..intArray.length+1] intArray[i] = array[r] array = array[..r] + array[r+1..] Next Return intArray End Function |
| ||
Hello. Mmmmm. to many slices. Slices make memory fragmentation and require data movements. Try inside bucle make 2 random index and interchange contents. If you not need change original array make a copy previous outside bucle. Bye, Paposo |
| ||
Ah ok I get what you mean. Trying again. EDIT: Randomizing an array without using slices is eluding me atm... |
| ||
Ok here we go. I searched for another method and this was in some vbasic helper site. It doesn't seem to be quite as random as my slice version but I'm sure it's more efficient.Function ShuffleIntArray%[](array%[]) Local r%, n% For Local i:Int = 0 To array.length-1 r = Rand(array.length)-1 n = array[i] array[i] = array[r] array[r] = n Next Return array ' Local intArray%[] ' For i = 0 To array.length-1 ' Local r% = Rand(array.length)-1 ' intArray = intArray[..intArray.length+1] ' intArray[i] = array[r] ' array = array[..r] + array[r+1..] ' Next ' Return intArray End Function |
| ||
Ok one more modification. I added in the number of times you want to shuffle the numbers.SeedRnd MilliSecs() Local array:Int[] = ShuffleIntArray([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]) For i = 0 To array.length-1 Print array[i] Next End Function ShuffleIntArray%[](array%[], numShuffles%=10) Local i%, j%, r%, temp% For j = 0 To numShuffles-1 For i = 0 To array.length-1 r = Rand(array.length)-1 temp = array[i] array[i] = array[r] array[r] = temp Next Next Return array End Function |
| ||
Perhaps if you do the shuffle loop a couple of times it produces more random result. |
| ||
I posted the numShuffle modification 20 seconds before you posted zawran lol. But yeah that's what will do the trick. |
| ||
And here's some more array stuff that might help a beginner.'*** Add One item to the end of an array *** array = array[..] + [num%] '*** Add One item to the first of an array array = [num%] + array[..] '*** Insert value Before index n n=1 array = array[..n] + [value] + array[n..] '*** Insert value After index n n=1 array = array[..n+1] + [value] + array[n+1..] '*** Delete First item from an array *** array = array[1..] '*** Delete Last item from an array *** array = array[..array.length-1] '*** Delete index n n=1 array = array[..n] + array[n+1..] |
| ||
Slices make memory fragmentation How? |
| ||
FWIW, Chroma's approach is what I've always used: random pair-swapping. |
| ||
Hello. One slice allocate memory and copy data. The memory allocated in heap need are continuous. The SO search a continuous block. If you free any block of memory it make a hole in heap. This holes are used in another allocations if the size requested are <= that hole. The SO make reorganizations consuming time. In general is more eficient not allocate and release blocks of memory if it is not needed. Sorry is dificult for me write this in english. Bye, Paposo |
| ||
Does SO mean OS (operating system)? Otherwise, ok. |
| ||
Yes. :) SO=OS (Sistema Operativo=Operating System). |
| ||
I've never had to do random int arrays but I have randomized arrays of objects e.g a shuffle a deck of cards. What I do is have a field that is used for randomizing. I set that field to a random number (like 1-1000) and then sort the objects by it. |
| ||
This algorhytm forms new array of numbers by sequentally choosing one of remaining items of array (used ones are marked in auxillary array). SuperStrict Local Nums%[] = [ 1, 1, 2, 3, 5, 8, 13, 21, 34 ] Local NewNums%[] = RandomizedArray( Nums ) PrintArray Nums PrintArray NewNums Function RandomizedArray%[]( Array%[] ) Local ArrayLength% = Array.Dimensions()[ 0 ] Local NewArray%[ ArrayLength% ] Local UsedPos%[ ArrayLength% ] For Local N% = 0 To ArrayLength% - 1 Local NumPos% = Rand( 1, ArrayLength% - N% ) Local ShiftedPos% = -1 Repeat ShiftedPos% :+ 1 If Not UsedPos[ ShiftedPos% ] Then NumPos% :- 1 Until NumPos% = 0 NewArray[ N% ] = Array%[ ShiftedPos% ] UsedPos[ ShiftedPos% ] = True Next Return NewArray% End Function Function PrintArray( Array%[] ) Local Text$ For Local N% = 0 To Array.Dimensions()[ 0 ] - 1 Text$ :+ Array%[ N% ] + ", " Next DebugLog Text$ End Function |
| ||
Found much less resource-demanding and more convenient algo (and still more-less "clean"):SuperStrict SeedRnd MilliSecs() Local Nums%[] = [ 1, 1, 2, 3, 5, 8, 13, 21, 34 ] RandomizeArray( Nums ) PrintArray Nums Function RandomizeArray( Array%[] ) Local ArrayLength% = Array.Dimensions()[ 0 ] For Local N% = 0 To ArrayLength% - 2 Local M% = Rand( N%, ArrayLength% - 1) Local Z% = Array%[ N% ] Array%[ N% ] = Array%[ M% ] Array%[ M% ] = Z% Next End Function Function PrintArray( Array%[] ) Local Text$ For Local N% = 0 To Array.Dimensions()[ 0 ] - 1 Text$ :+ Array%[ N% ] + ", " Next DebugLog Text$ End Function |