基本的な答えは、範囲 1 .. (100 - 3 + 1) または 1..98 から 3 つの個別のランダム値を生成し、各値 n から n,n+1,n+2 を生成することです。
それだけで、重複しない要件が残ります。3 つの数値のうち任意の 2 つの数値の間のギャップの絶対値が少なくとも 3 であることをテストする必要があります。そうでない場合は、新しい番号を生成します。生成しても問題ないかどうかを判断する必要があります (「ランダム生成」が {1, 4, 7} の順列を生成したと仮定します):
1 2 3
4 5 6
7 8 9
または、数値のセット間にギャップが必要かどうか。ギャップが必要な場合は、生成された値のペア間の距離が 3 ではなく 4 以上であることを確認します。
3 つの値のセット間に少なくとも 1 のギャップを要求することを選択すると、次のスクリプトになりました。
#!/bin/bash
min=1 # Minimum value
max=100 # Maximum value
adj=3 # Number of adjacent values per set
num=3 # Number of sets
r_min=$min
r_max=$(($max - $adj + 1))
base=()
while [ ${#base[*]} -lt $num ]
do
next=$(($RANDOM % ($r_max - $r_min + 1) + $r_min))
ok=yes
for n in ${base[@]}
do
gap=$(($next - $n))
[ $gap -lt 0 ] && gap=$((- $gap))
if [ $gap -le $adj ]
then ok=no; break
fi
done
if [ $ok = yes ]
then base+=( $next )
fi
done
for n in ${base[@]}
do
for ((i = 0; i < $adj; i++))
do printf "%4d" $(($n + $i))
done
echo
done
ポイントのセットの数とセット ($num
および$adj
コード) 内のポイントの数が大きくなりすぎると、十分な可能性がないため、無限ループに陥る可能性があることに注意してください。たとえば、$adj
at 3 の場合、$num
25 以上に設定すると無限ループが保証されます。ただし、そのずっと前に簡単にトラブルに遭遇する可能性があります。
実行例:
$ bash randcont.sh
16 17 18
92 93 94
6 7 8
$ bash randcont.sh
81 82 83
40 41 42
13 14 15
$ bash randcont.sh
61 62 63
71 72 73
23 24 25
$ bash randcont.sh
54 55 56
7 8 9
46 47 48
$
乱数を生成するために使用されるメカニズムには偏りがあります — より低い数への偏りです。それが問題である場合は、それを修正する方法も考え出すことができます。
これが最善の方法であるとは確信していません。総当たりや無知を少なくする方法がいくつかあるでしょう。しかし、サンプル要件では「OK」に機能します。