n人中m人が当選するくじ
Posted feedbacks - Perl
これでどうだ!
1 2 3 4 5 6 7 8 | sub lot {
my ($n, $m) = @_;
my @list = map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_, rand] }
(1 .. $n);
splice(@list, 0, $m);
}
|
つい書いてしまった。
1 2 3 4 5 | sub lot {
my ($n, $m) = @_;
my @a = 0..$n-1;
map { splice @a, int rand scalar @a, 1 } 1..$m;
}
|
てか m 人が常に連続でも題意は満たしてるよね。ということで1ステートメントに。
1 2 3 4 | sub lot {
my ($n, $m) = @_;
splice @{[ 0..$n-1, 0..$n-1 ]}, int rand $n, $m;
}
|
一応O(nm)になってるかな?
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 | #!/usr/local/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $nmax = shift;
my $mmax = shift;
my @winner;
#warn "selecting $nmax from $mmax\n";
for my $n ( 0 .. $nmax - 1 ) {
my $count = 0;
for my $m ( 1 .. $mmax ) {
next if grep { defined $_ and $_ == $m } @winner;
if ( rand( $count ) < 1 ) {
$winner[$n] = $m;
}
$count++;
}
}
print join( "\n", @winner) , "\n";
|
進捗表示と範囲チェックを追加。
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 | #!/usr/local/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $nmax = shift;
my $mmax = shift;
if ( $nmax >= $mmax ) {
print "$_\n" for ( 1 .. $mmax );
exit;
}
my @winner;
#warn "selecting $nmax from $mmax\n";
for my $n ( 0 .. $nmax - 1 ) {
print STDERR '.';
my $count = 0;
for my $m ( 1 .. $mmax ) {
next if grep { defined $_ and $_ == $m } @winner;
if ( rand( $count ) < 1 ) {
$winner[$n] = $m;
}
$count++;
}
}
print STDERR "\n";
print join( "\n", @winner) , "\n";
|
1 2 | use List::Util qw/shuffle/;
sub lot {($n,$m)= @_; (shuffle(1..$n))[1..$m];}
|
動作環境 Fedora7 Perl5.8.8
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | #!/usr/bin/perl
use strict;
exit main();
sub main{
if(@ARGV != 2){
print "usage: perl 3360.pl <total-number> <target-number>\n";
return 1;
}
my $rtn = 0;
if($rtn = is_num($ARGV[0])){
print "$ARGV[0] not integer\n";
return $rtn;
}
if($rtn = is_num($ARGV[1])){
print "$ARGV[1] not integer\n";
return $rtn;
}
if($ARGV[0] <= $ARGV[1]){
print "$ARGV[0] isn't greater than $ARGV[1]\n";
return 3;
}
my $total = $ARGV[0];
my $target = $ARGV[1];
my $rand_numbers = get_rand_number($total,$target);
print join "\n", @$rand_numbers;
return 0;
}
sub is_num{
my ($num) = shift;
if($num !~ / [0-9]+$/){
return 2;
}
return 0;
}
sub get_rand_number{
my ($total,$target) = @_;
my $numbers = [];
my $rand = undef;
for(my $i=0; $i<$target; $i++){
$rand = int(rand($total))+1;
if(!grep { /^$rand$/ } @$numbers){
push @$numbers, $rand;
}
else{
redo;
}
}
return $numbers;
}
|





にしお
#3360()
Rating0/0=0.00
[ reply ]