challenge 重複無し乱数

整数nを渡すと1 ~ n までの整数を重複しないようランダムに出力する関数「bingo」を作ってください。

このお題はraynstardさんの投稿を元にしています。ご投稿ありがとうございました。 投稿の内容には表示のしかたも含まれていたのですが、 このお題では「重複しない1~nまでの乱数をどうやって作るか」という点に集中することにして、 結果の整形は続編としてこの後のお題で出すことにします。 サンプル入出力は下のようになります。

>>> bingo(10)
[10, 7, 8, 4, 5, 2, 3, 1, 6, 9]
>>> bingo(3)
[2, 3, 1]
>>> bingo(3)
[2, 3, 1]
>>> bingo(3)
[3, 1, 2]
>>> bingo(10)
[7, 3, 8, 6, 4, 10, 9, 2, 1, 5]

Posted feedbacks - awk

% awk -f bingo.awk
5
[3, 5, 1, 4, 2]
24
[22, 11, 5, 2, 4, 3, 9, 24, 6, 7, 17, 16, 21, 15, 19, 18, 12, 14, 13, 23, 10, 20, 8, 1]
10
[7, 4, 9, 3, 5, 10, 2, 1, 8, 6]
10
[10, 8, 3, 2, 6, 7, 1, 9, 5, 4]
10
[5, 7, 1, 8, 10, 3, 6, 2, 4, 9]
10
[6, 2, 3, 5, 1, 9, 8, 10, 7, 4]
10
[6, 9, 8, 5, 4, 2, 1, 3, 10, 7]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
BEGIN {
	srand
}

{
	n = $1

	bingo(n,ar)
	show(n,ar)
}

function show(n,ar, i)
{
	printf "["
	for (i=1; i<n; i++) printf("%d, ", ar[i])
	printf("%d]\n", ar[n])
}

function rand_between_1_and_n(n, x)
{
	x = 1 + int(rand * n)
	return (x <= n)? x : rand_between_1_and_n(n)
}

function bingo(n,ar,  i,x,y,t)
{
	delete ar
	for (i=1; i<=n; i++) ar[i] = i

	for (i=n*2; i>0; i--) {
		x = rand_between_1_and_n(n)
		y = rand_between_1_and_n(n)
		if (x == y) continue

		t = ar[x] ; ar[x] = ar[y] ; ar[y] = t
	}
}

1〜nの要素を持つベクトルを作り,端から順に無作為に並べ替えてゆく。
ランダムさはそれで十分だろう。
スクリプト中のnへ値を渡すのは -v n=5 のように

 > awk -f p3402.awk -v n=10
 4 10 9 1 2 6 5 8 3 7
 > awk -f p3402.awk -v n=10
 4 10 9 1 2 6 5 8 3 7
 > awk -f p3402.awk -v n=10
 3 2 5 4 7 9 10 1 6 8
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
BEGIN {
    srand()
    for (i = 1; i <= n; i++) x[i] = i
    for (i = 1; i <= n; i++) {
        j = int(rand()*n)+1
        t = x[i]
        x[i] = x[j]
        x[j] = t
    }
    for (i = 1; i <= n; i++) printf " %i", x[i]
    print ""
}

Index

Feed

Other

Link

Pathtraq

loading...