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 - diff

#2269 によると rand() % n はまずいということなので、修正しました。std::min や std::max は [0, n) の範囲にあることを保証するため、念のため。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
--- main.orig	Sat Aug 18 00:35:58 2007
+++ main.cpp	Sat Aug 18 00:41:24 2007
@@ -21,7 +21,9 @@ struct RandomGenerator
 
     int operator()(int n) const
     {
-        return std::rand() % n;
+        const int i = static_cast<int>(static_cast<double>(std::rand()) * n / RAND_MAX);
+
+        return std::max(0, std::min(i, n - 1));
     }
 };

もしかしたら配列の範囲超えちゃうかなと思って剰余を使用しましたが
よく考えてみるとかけ算でも良かったかも。

最大で0.9掛けにしかならないし。
あれ?でも確率的には1.0もありうる?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
--- doukaku46.pl.org    2007-08-23 00:40:42.921875000 +0900
+++ doukaku46.pl        2007-08-23 00:41:49.203125000 +0900
@@ -5,8 +5,7 @@
     my $r;
     for( my $n = $x; $n>0; $n --)
     {
-        $r = rand; $r *= 1000;
-        push(@num, splice(@num, $r % $n, 1) );
+        push(@num, splice(@num, rand() * $n, 1) );
     }
     print "[$x] => " . join(",", @num) . "\n";
 }

Index

Feed

Other

Link

Pathtraq

loading...