If I want to create a ring with 16 randomly generated 1s and 0s, in an other language I’d define an empty list of length 16, iterate through it to add the random generation and then use modulo(index, 16) to acces it.
If I want to create an empty ring in Sonic Pi, I need to type out (ring 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) and it only gets worse with bigger lists and rings. Is there an easier way to do such a thing?
Hi, this might be what you’re looking for.
r = (knit 0, 16) + (knit 1, 16)
puts r.shuffle
Hello @Loopiloop Welcome!
Yes, there are simpler ways of doing this.
As you have found, Sonic Pi does not have an idiomatic way to create a ring of random numbers directly - but there are ways of achieving the same thing - either still using other Sonic Pi functions, or with plain Ruby syntax (not officially supported).
Binarysweets has shown one way - (although if you’re specifically after a list of 16 numbers, you could use r.pick(16)
instead of r.shuffle
).
Here’s a few others - just to show you that there’s more than one way to skin a cat
puts (ring *Array.new(16){ rand_i })
(The above uses plain Ruby syntax and is not ‘officially supported’)
list = (ring)
16.times do
list = list + (ring rand_i)
end
puts list
In the end I settled for
r = (0, 1)
puts r.pick(16)
Perhaps you meant:
r = (ring 0, 1)
puts r.pick(16)
As well as
use_random_seed 1789 #change the seed value for different results
r = (ring rrand_i(0,1), rrand_i(0,1), rrand_i(0,1), rrand_i(0,1),
rrand_i(0,1),rrand_i(0,1),rrand_i(0,1),rrand_i(0,1),
rrand_i(0,1),rrand_i(0,1),rrand_i(0,1),rrand_i(0,1),
rrand_i(0,1),rrand_i(0,1),rrand_i(0,1),rrand_i(0,1))
puts r
A bit laborious but does mean that different random ranges can be accommodated for each position if required. I’m exploring shift registers and matrix sequencers and populating them using different value ranges, so the above works well enough and is straightforward to modify.
I keep forgetting to add “ring”, but yes, that’s what I ment
I do this. It’s sort of odd but does imbue the ring with superpowers!
Had a few stabs at this, originally tried to embed a times
loop in the ring command, may need lambda to achieve (or other).
Sharing because I’m pleased I cracked it, and curious if any adjustments to my method.
def rand_steps(s)
steps = []
s.times do
steps << rrand_i(0,1)
end
return steps
end
puts ring rand_steps(16)