This is a fun challenge. I wanted to see if I could figure out a way to do this without shuffle. The solution I settled on after much googling is to use a linear congruential generator algorithm, which is a psuedorandom number generator with the property that, given the right inputs, its output is a sequence of all integers in a range (0 .. m-1) in pseudorandom order with no repeats (until it exhausts the range, whereupon it begins the sequence again). In other words, it can be used as a "lazy shuffle" algorithm. Here's the implementation I came up with, as a Ruby Enumerator:
The "increment" value C could have been any number coprime with M; I chose 77777 purely for aesthetics.
Note that if we changed M.times do to loop do, the sequence would cycle infinitely.
Once you have this, all that's left is to format each number as a robot name, and then some bookkeeping for the forget! and reset! methods. Here's the final result:
This is a fun challenge. I wanted to see if I could figure out a way to do this without shuffle. The solution I settled on after much googling is to use a linear congruential generator algorithm, which is a psuedorandom number generator with the property that, given the right inputs, its output is a sequence of all integers in a range (0 .. m-1) in pseudorandom order with no repeats (until it exhausts the range, whereupon it begins the sequence again). In other words, it can be used as a "lazy shuffle" algorithm. Here's the implementation I came up with, as a Ruby Enumerator:
The "increment" value
C
could have been any number coprime withM
; I chose77777
purely for aesthetics.Note that if we changed
M.times do
toloop do
, the sequence would cycle infinitely.Once you have this, all that's left is to format each number as a robot name, and then some bookkeeping for the
forget!
andreset!
methods. Here's the final result:Just for kicks, here's the same thing in JavaScript: beta.observablehq.com/@jrunning/ro... (Too bad dev.to doesn't embed Observable notebooks.)