n人の中から公平にm人を選ぶ、くじ引きプログラムを作ってください。
→問題
perlで書いてみた。
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode;
sub e{encode("utf8", shift)};
sub d{decode("utf8", shift)};
die e("使用方法: $0 <全体の人数> <当選する人数>\n") if(@ARGV != 2);
my ($n, $m) = (d($ARGV[0]), d($ARGV[1]));
die e("引数は、整数でお願いします") if($n !~ /^\d+$/ || $m !~ /^\d+$/);
die e("全体の人数より当選する人数の方が多くなっています") if($n < $m);
my @list;
push @list, [$_, rand] for (1..$n);
my @sort = map{$_->[0]}
sort{$a->[1] <=> $b->[1]} @list;
print "$sort[$_]\n" for (1..$m);
spliceを使うと
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode;
sub e{encode("utf8", shift)};
sub d{decode("utf8", shift)};
die e("使用方法: $0 <全体の人数> <当選する人数>\n") if(@ARGV != 2);
my ($n, $m) = (d($ARGV[0]), d($ARGV[1]));
die e("引数は、整数でお願いします") if($n !~ /^\d+$/ || $m !~ /^\d+$/);
die e("全体の人数より当選する人数の方が多くなっています") if($n < $m);
my @list = (1..$n);
my @lot;
for (reverse 1..$m){
my $rnd = int rand(scalar @list);
push @lot, splice @list, $rnd, 1;
}
print "@lot\n";
javascriptで書いてみた。
function lot(n, m){
if(isNaN(n) || isNaN(m)){
alert("入力値は、半角数字でお願いします");
return;
}else if(n < m){
alert("error:第一引数(参加者の数)より第二引数(当選数)を少なくして下さい")
return;
}
var num = [];
for(var i=0; i<n; i++){num[i] = [Math.random(), i]};
num = num.sort();
var str = [];
for(i=0; i<m; i++){str.push(num[i][1] + 1)};
alert(str.sort(num_sort));
}
function num_sort(a, b){
return a-b;
}
lot(10, 2);
のようにくじ応募者数と当選者数を指定すると
alertで当選者の番号をかえします。
どうようの考えでExcelVBAで書いてみると・・・
Sub lot(m As Integer, n As Integer)
Dim list As Object
Dim i As Integer
Dim str As String
Dim temp() As String
Randomize
Set list = CreateObject("System.Collections.ArrayList")
For i = 0 To m - 1
temp() = Split(list(i), "*")
If str = "" Then
str = temp(1)
Else
str = str & "," & temp(1)
End if
Next i
MsgBox str
End Sub
確か、VBA単体ではソートができなかったはずなんで
.NET Frameworkの方の機能が使えるらしーので
そちらを使ってソートしてみました。