Translate

2009年9月28日月曜日

n人中m人が当選するくじ

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の方の機能が使えるらしーので
そちらを使ってソートしてみました。

2009年9月27日日曜日

指定されたフォルダ以下のゴミ削除

指定したフォルダ以下にある、ファイル名が"~"で終わるファイルを削除するプログラムを作ってください。 指定したフォルダの中にあるフォルダのさらに中にあるファイルも削除の対象です。

問題



perlで書いてみた。

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use File::Find;
sub e{encode("utf8", shift)};
sub d{decode("utf8", shift)};

die e("使用方法: $0 directory string") if(@ARGV != 2);

my $directory = $ARGV[0];
find(\&del, $directory);
exit;

sub del{
my $pattern = $ARGV[1];
unlink $_ if(-f $_ && /$pattern$/);
}



javascriptでは・・・基本的に無理ですね。
WSH使えばできないこともないですが...

2009年9月5日土曜日

Cを少しずつ学習してみるテスト。

ひとまず、こんにちはこんにちは!から。

#include 

int main(void){
printf("こんにちは、こんにちは!!¥n");
return 0;
}


1行目:printf関数を使うがために、 #includeで標準ライブラリ(stdio.h)を読込む。
3行目:mainの前のキーワードは、返り値の型をさしている。後述をするが、0を返すのでintを指定
    mainは、ここからコードが始まるので必ず必要。
    mainの後の括弧内は、引数を指定。今回はないのでvoid。
4行目:printfで標準へ出力。
5行目:return 0で正常に終了できたことを知らせる。 mainにだけ必要。
<参考>
【C言語講座】標準ライブラリ関数


型と最小範囲のメモ

最小範囲
char-127〜127
unsigned char0〜255
signed char-127〜127(=char)
int-32767〜32767
unsigned int0〜65535
signed int-32767〜32767(=int)
short int-32767〜32767(=int)
unsigned short int0〜65535
long int-2147483647〜2147483647
signed long int-2147483647〜2147483647(=long int)
unsigned long int0〜4294967295
float小数精度6桁
double小数精度10桁
long double小数精度10桁



ちょっとメモ。
・main関数が起点
・main関数の最後はreturn0をする
・scanfで受け取った値は、&をつけた変数に渡す(ポインターでよい?)
・条件式では、0以外の値が真、0が偽と評価される。
・if文で文が1つの時は、中括弧使わない。。
・標準入力で文字を受け渡す方法が今のところよくわからん(現在独習Cの3章付近)


第6章にきた。
ポインター。

ポインターかぁ。。

#include 

int main(void){
int *p, q;
q = 199;
q = &q;
printf("%d", *p);

return 0;
}


perlだとこんな感じか。
use strict;
use warnings;

my $q = 199;
my $p = ¥$q;
print ${$p}, "¥n";

&がリファレンスで*がデリファレンスという感じかと
思ったけどそういう使い方とはちょいと違うのね。

最初の型宣言で、int型のアドレスを受け取る入れ物を
用意するってのが int *p なのね。
で、アドレスを渡しておかないとこの子には格納することができないのね。