< Back to IRCAM Forum

Random without duplicates

Dear OM community,

Is there an OM equivalent to the Max “urn” object? This allows for random integer values within a range with no duplicates.

Thanks,

Doug

Hello Doug,

There is no such object in OM as far as I know, but it is possible to create it either using a loop or directly in Lisp:

 

;;; Generates a list of different random integers between and :

(lambda (n min max)

(loop with random-list

while (< (length random-list) n)

do (let ((num (om::om-random min max)))

(unless (find num random-list)

(push num random-list)))

finally return random-list)

)

 

(you can paste this code, for instance, in a “lisp” box)

A test should be added to ensure that n <= (max - min), otherwise the loop will never return.

Jean

Dear Jean,

Thank you much for your quick reply! I must admit that my Lisp skills are still rather low, although I know C, C++, and Java.

I was able to create a patch based on the code you posted, but it does not seem to do what I intended. Probably I did not explain my intention clearly.

My wish is to treat an input list (a group of pitches, for instance) like pulling pieces of paper from a hat one at a time until all items of the list have been chosen once. With each query to the object one item randomly chosen from the input list would result until all have been chosen once, and then it would revert to the entire original list and begin the process again.

Thank you for any additional ideas,

Doug

My wish is to treat an input list (a group of pitches, for instance) like pulling pieces of paper from a hat one at a time until all items of the list have been chosen once.

=> this amounts to performing a random permutation of the original list (in OM: permut-random)

and then it would revert to the entire original list and begin the process again.

=> This may be a bit more complicate if the total number of pitches is not a multiple of the original list’s length (otherwise you can just repeat the process n times and append the results).

…an easy trick could be to repeat the PERMUT-RANDOM the right number of times (ceiling n list-length) and then eventually “cut” the end of the resulting list to the required length (e.g. using FIRST-N).