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


	
1
2
use List::Util qw/shuffle/;
sub bingo {shuffle(1..$_[0]);}

抽出して最後に追加が見あたらなかったので投稿~
Cだとswapすることになるのかな?
めんどそうだからperlで(笑

[10] => 8,10,6,1,3,5,9,4,7,2
[3] => 3,1,2
[2] => 2,1

# rand * 1000 だとうまくいかなかったなぜ?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
sub bingo($;)
{
    my $x = shift ;
    my @num = (1 .. $x);
    my $r;
    for( my $n = $x; $n>0; $n --)
    {
        $r = rand; $r *= 1000;
        push(@num, splice(@num, $r % $n, 1) );
    }
    print "[$x] => " . join(",", @num) . "\n";
}
srand;

bingo(10);
bingo(3);
bingo(2);

型ブログということでいいみたいです。
*1000
はどんなパッケージ内であっても、
mainパッケージに含まれているようです。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/local/bin/perl -w
use strict;
package hoge;

my $piyo = (*1000);
print $piyo, "\n";

my $fuga = (*N);
print $fuga, "\n";

# 出力結果 ( Perlのバージョンは5.8.8 )
# Name "hoge::N" used only once: possible typo at ./test.pl line 9.
# *main::1000
# *hoge::N

マニュアル確認しました。
1未満ですね失礼しました。
しかも、rand()は引数に指定したN未満という形で返すらしいです。
結局、掛け算する必要性すらなくorz

さらに、別のページでは僕の書いたコードは悪い例として載っていました(笑

下のように書くと良いらしいです。
#コードはそのページからのコピペです。
#ページ内検索:How do I shuffle an array randomly?

perlならではの書き方でなるほど~という感じ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
    # fisher_yates_shuffle( \@array ) : 
    # generate a random permutation of @array in place
    sub fisher_yates_shuffle {
        my $array = shift;
        my $i;
        for ($i = @$array; --$i; ) {
            my $j = int rand ($i+1);
            @$array[$i,$j] = @$array[$j,$i];
        }
    }
    fisher_yates_shuffle( \@array );    # @array そのものを入れ替える

Perlで書いてみた
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sub bingo()
{
    my @array = ( 1 .. shift );
    my @out   = ();
    while ( my $x = splice( @array, int(rand(scalar @array)) , 1 ) )
    {
        push @out , $x ;
    }
    return [ @out ];
}

print join "," , @{ &bingo(10) };

Index

Feed

Other

Link

Pathtraq

loading...