Search code examples
bashrandomshufflesequentialcontiguous

Using bash to create random contiguous number sequences from a given range


Using a given range of values, I'm trying to generate random instances of three contiguous numbers.

For example, given the range 1-100, and desiring three (non-overlapping) random instances of three contiguous numbers, the output would be something like:

4 5 6
50 51 52
32 33 34

I've been trying to use the command shuf, for example,

shuf -i 1-100 -n 3

but this doesn't seem to permit the generation of random contiguous number sequences. Any ideas?


Solution

  • It is possible to generate the triples uniformly and without the need for testing and rejecting overlaps.

    The problem reduces to finding a random sequence of size k {a1ak} from {1…N−2} such that the minimum difference between any two values of the subsequence is at least 3. (N−2 because the values selected are the first values of each triple, so the largest cannot be greater than N−2.)

    This can be done by starting with a random ordered subsequence {a'1a'k} from {1…N−((k−1)×2+2)} and then setting each ai to a'i+2(i−1). Finally, the sequence can be randomly shuffled.

    This can be easily be generalized to find tuples of size m.

    In bash:

    # tuples n k m
    tuples () { 
        local -i n=${1:-100} k=${2:-3} m=$((${3:-3}-1))
        if ((n < k*m + k)); then return 1; fi
        local -i i=0 a
        for a in $(shuf -i 1-$((n - k * m)) -n $k | sort -n); do
            # -s'  ' to work around a bug in coreutils 8.20 and 8.21
            seq -s'  ' $((a+i)) $((a+i+m))
            i+=m
        done | shuf
    }