Linuxでサイコロを振る

sortコマンドの-Rオプションを利用してランダム性を与える。

$ seq 6 | sort -R | head -1
3

bashならseqの部分を次のように書いてもよい。

$ echo {1..6} | xargs -n 1 | sort -R | head -1
5

ばらつきを確かめるために、10,000回実行してみる。
ついでに頭にtimeコマンドを付けて所要時間を測る。

$ time for i in `seq 10000`; do seq 6 | sort -R | head -1 >> dice.out; done

real	0m11.360s
user	0m0.043s
sys	0m3.454s

uniqコマンドの-cオプションを利用してヒストグラムを作る。

$ cat dice.out | sort | uniq -c
   1631 1
   1718 2
   1637 3
   1654 4
   1651 5
   1709 6

検証環境は以下のとおり。

$ uname -r
2.6.32-642.1.1.el6.x86_64
$ rpm -qf `which sort`
coreutils-8.4-43.el6.x86_64
$ rpm -qf `which uniq`
coreutils-8.4-43.el6.x86_64

おまけ

bashの組み込み変数RANDOMを使う手もある。RANDOMは参照されるたびに0~32767(32,768パターン)の整数をランダムに返す。

$ echo $(($RANDOM%6+1))
6

ただし、このサイコロの各目が出る確率は異なる。32,768は6で割り切れないためだ。剰余が2なので、1と2が他の目よりほんのちょっと出やすいはず。

$ for i in `seq 0 32767`; do echo $(($i%6+1)); done | sort | uniq -c
   5462 1
   5462 2
   5461 3
   5461 4
   5461 5
   5461 6

実際に1,000万回振ってみる。

$ time for i in `seq 10000000`; do echo $(($RANDOM%6+1)); done | sort | uniq -c
1665407 1
1665933 2
1666690 3
1667355 4
1667291 5
1667324 6

real	1m40.431s
user	1m13.327s
sys	0m28.025s

思ったとおりにならない。試行回数が少ないのか、確率分布が離散一様分布でないのか…