I also stumbled across this and wrote Idev suite, contained in miSCellaneous_lib. It’s basic idea is to search grid environments of moving sources with avoidance of repetitions as an additional feature. As a special case the source can also be static, then it looks like your use case, see the example below.
/////////////// text from help
DIdev / PIdef / PLIdev search for numbers with integer distance from a source signal / pattern up to a given deviation. Repetitions within a lookback span are avoided, DIdev / PIdef / PLIdev randomly choose from possible solutions. Intended for search within integer grids (pitches, indices etc.), however applications with non-integer sources are possible, see examples.
The main musical idea of these classes is, that it’s often unwanted to have certain characteristics repeated within a perceptional time window. This might apply to melodic lines as well as to rhythmic patterns or sequences of timbre and can be continued in the domain of microsound. The principle can easily be understood with pitches, therefore most examples are of this kind.
In the following example integers are searched within the neighbourhood of a rounded sine source. The hi and lo deviation is constant (+/-5) and a lookBack value of 3 garantuees that there are no repetitions of integer values within a group of 4 (e.g. find a closest repetition within the last 5 points). In general lookback and deviations can be dynamic, the source doesn’t need to be rounded and the comparison threshold for the repetition check can also be passed as a dynamic argument.
PIdev.new(pattern, maxLookBack: 3, loDev: -3, hiDev: 3, lookBack, thr: 0.001, length: inf)
The source value pattern to start search from.
Integer, the maximum lookback span. Fixed, defaults to 3.
Determines the current low deviation for the search. Defaults to -3.
Determines the current high deviation for the search. Defaults to 3.
Determines the current lookback span for avoiding repetitions. Can be modulated but must not exceed maxLookBack. If no value is passed, then maxLookBack is taken.
Threshold for equality comparison. Can be modulated, defaults to 1e-3.
Number of repeats. Defaults to inf.
// gives random integers between 0 and 20, no reps within 6 items
PIdev(10, 20, -10, 10, 5).iter.nextN(30)
-> [ 18, 6, 7, 4, 8, 15, 13, 3, 11, 18, 6, 2, 0, 15, 3, 13, 18, 19, 11, 0, 20, 4, 15, 7, 17, 6, 19, 0, 9, 20 ]
PLIdev is the PLx (proxy) variant of PIdev, DIdev the demand rate ugen version.