2011年12月25日日曜日

[ExcelVBA] n人中m人が当選するくじ その3


■お題
n人中m人が当選するくじ除(問題出典:どう書く?org)
- 問題詳細 -
n人の中から公平にm人を選ぶ、くじ引きプログラムを作ってください。

■解答例
・乱数とソートを使ってみる
A列に乱数、B列に参加者の番号を記入し、A列をキーにソートをかけるとB列がシャッフルされて当選者数分の番号を返せばよいですね。
↑A列に乱数、B列に参加者の番号を記入


↑A列をキーにA列、B列をソート


では、コードです。
モジュール名:SubModule
  1. Option Explicit  
  2.   
  3. Function lot(n As Integer, m As IntegerAs Variant  
  4.     Randomize  
  5.   
  6.     Dim r As Integer  
  7.     For r = 1 To n  
  8.         Cells(r, 1) = Rnd()  
  9.         Cells(r, 2) = r  
  10.     Next  
  11.       
  12.     Range(Cells(1, 1), Cells(r, 2)).Sort key1:=Range("A1")  
  13.       
  14.     Dim result As Variant  
  15.     ReDim result(m - 1)  
  16.       
  17.     For r = 1 To m  
  18.         result(r - 1) = Cells(r, 2)  
  19.     Next  
  20.       
  21.     lot = result  
  22. End Function  
3行目:引数 n…参加者全員の数を指定、m…選ばれる人数を指定
4行目:乱数のシードを変更する。Randomize(Number) Numberは省略可。省略時、時刻からシード値を取得。
6行目:変数 r・・・行数を格納する用の変数を宣言
8行目:A列に乱数を記載する
9行目:B列に参加者の番号を記載
10行目:繰り返し
12行目:A列をキーにA列、B列をソート
14行目:変数 result・・・当選者の番号を格納する。
15行目:result配列の要素を確定する
18行目:B列の値を当選者としてresult変数に格納する
19行目:繰り返し
21行目:返り値としてresult配列を返す


実際にこんな感じで使う

モジュール名:MainModule
  1. Option Explicit  
  2.   
  3. Sub main()  
  4.     Dim result As Variant  
  5.     result = lot(10, 3)  
  6.       
  7.     Dim i As Integer  
  8.     For i = 0 To UBound(result)  
  9.         Debug.Print result(i)  
  10.     Next  
  11.       
  12.     Debug.Print "-------------"  
  13. End Sub  


実行結果
  1. 8   
  2. 4   
  3. 2   
  4. ------------  
  5. 1   
  6. 3   
  7. 2   
  8. ------------  
  9. 7   
  10. 5   
  11. 6   
  12. ------------  
  13. 5   
  14. 8   
  15. 9   
  16. ------------  

0 件のコメント: