Kyma Forum
  Kyma Support
  whats the simplest way of shuffling an array?

Post New Topic  Post A Reply
profile | register | preferences | faq | search

next newest topic | next oldest topic
Author Topic:   whats the simplest way of shuffling an array?
cristian_vogel
Member
posted 10 February 2010 05:07         Edit/Delete Message   Reply w/Quote
I have a collection of samples in an array. I know how to reverse the array

array := array reverse.

But is there a nice simple way to shuffle the indices?


IP: Logged

SSC
Administrator
posted 10 February 2010 11:13         Edit/Delete Message   Reply w/Quote
If you simply want to access the elements of the array at random, you could generate a random index each time you wanted a new element. This does not, however, prevent you from selecting the same element more than once.

To shuffle the elements in the array, think of the array as a deck of cards being shuffled by a dealer. On each shuffle, the dealer is permuting the order of the cards. We want to pick one of these permutations at random. Here's an example (if you copy/paste this into a text file in Kyma, you can select it and use ctrl+Y to evaluate it. Each time you evaluate it, you'll get a different random permutation of the array):

code:

| ps r shuffled |
ps := PermutationStream on: #(1 2 3 4 5).
r := Random new.
(((r next * ps size) truncated + 1) min: ps size) timesRepeat: [shuffled := ps next].
shuffled

Here is the same code but with comments and an extra variable for clarity:

code:

| ps r shuffled nbrRepetitions |

"Create a PermutationStream on the original Array that
will give us a new permutation each time we send it the
message next. And create a Random number stream that
will give us a random number between 0 and 1 each time
we send it the message next."
ps := PermutationStream on: #(1 2 3 4 5).
r := Random new.

"Generate a random number of permutations by sending the
next message a random number of times. To get the random
number of repetitions send next to the Random stream (giving
us a value between 0 and 1). Multiply that by the size of the
PermutationStream (the number of permutations). We want an
integer number of repetitions so truncate the result (giving us
a value from 0 to ps size). Add 1 because Smalltalk arrays are
indexed starting with 1, not 0. To be extra careful, take the min
of this and size of the PermutationStream."
nbrRepetitions := ((r next * ps size) truncated + 1) min: ps size.

"Permute the order of the array nbrRepetitions times."
nbrRepetitions timesRepeat: [shuffled := ps next].
shuffled


[This message has been edited by SSC (edited 10 February 2010).]

IP: Logged

cristian_vogel
Member
posted 10 February 2010 11:59         Edit/Delete Message   Reply w/Quote
nice

thanks!


is this an example of the use of the new varTimesRepeat: ?

Also, what is PermutationStream on: ?

Will this be documented somewhere? It's a very useful type of stream.

[This message has been edited by cristian_vogel (edited 10 February 2010).]

IP: Logged

cristian_vogel
Member
posted 10 February 2010 13:34         Edit/Delete Message   Reply w/Quote
weirdness...

try executing this with 10 elements - it hangs! - and around 9 elements goes real slow

| ps r shuffled |
ps := PermutationStream on: #(1 2 3 4 5 6 7 8 9 10).
r := Random new.
(((r next * ps size) truncated + 1) min: ps size) timesRepeat: [shuffled := ps next].
shuffled

IP: Logged

SSC
Administrator
posted 10 February 2010 13:35         Edit/Delete Message   Reply w/Quote
I just added a new message, 'shuffle', that you can send to SequencebleCollections (like Arrays or Strings) in the upcoming release of Kyma (X.74) to do this more efficiently. For example

code:

| a |
a := 'helloworld'.
a shuffle

Result = 'lloodehrwl'

IP: Logged

cristian_vogel
Member
posted 10 February 2010 13:41         Edit/Delete Message   Reply w/Quote
thats great.

What I was intrigued by about this in Kyma, was the idea of shuffling an array of files, of kyma objects, perhaps like an array of running generators like ramps and bpms

will this be possible, or will it be only strings, or only elements at compile time?


edit: actually, a few seconds thinking about that - the best wasy to shuffle through arrays of objects , especially capytalk or pasted objects, is with my old favourite 'AnalogSequencer' right?

[This message has been edited by cristian_vogel (edited 10 February 2010).]

IP: Logged

SSC
Administrator
posted 10 February 2010 13:42         Edit/Delete Message   Reply w/Quote
"try executing this with 10 elements - it hangs! - and around 9 elements goes real slow"

The number of permutations of an n-long array is n! To get an idea of why it goes 'real slow', try evaluating:

10 factorial

in Kyma by selecting it and using ctrl+Y. (Hint the answer is 3,628,800).

So probably best to hang in there for the next update which has a much more efficient solution. (Maybe you could use the PermutationStream version to experiment with short arrays in the meantime).

IP: Logged

cristian_vogel
Member
posted 10 February 2010 13:44         Edit/Delete Message   Reply w/Quote
Ouch! Yes. It had the feeling of a MASSIVE number!

I was running it on a collection of filenames from a directory, so yes I can understand why Kyma went awry!

thanks for thread, it is very educational

IP: Logged

SSC
Administrator
posted 10 February 2010 13:48         Edit/Delete Message   Reply w/Quote
quote:

What I was intrigued by about this in Kyma, was the idea of shuffling an array of files, of kyma objects, perhaps like an array of running generators like ramps and bpms

will this be possible, or will it be only strings, or only elements at compile time?


It works on Arrays or OrderedCollections of any elements (so yes, file names, CapyTalk code, etc). The shuffling is in Smalltalk so it takes place at compile time. But the elements could be CapyTalk expressions.

For example, in the Samples field of a Multisample module, you could use:

{'pottery break 1.aif' sampleFileNamesInSameFolder shuffle}

[This message has been edited by SSC (edited 10 February 2010).]

IP: Logged

All times are CT (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply

Contact Us | Symbolic Sound Home

This forum is provided solely for the support and edification of the customers of Symbolic Sound Corporation.


Ultimate Bulletin Board 5.45c