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

n人の中から公平にm人を選ぶ、くじ引きプログラムを作ってください。

Posted feedbacks - C#

jってこれでよかった(一様にランダムになる)か?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
public static bool[] MakeDrawing(int n, int m)
{
    if (n < 0) throw new ArgumentException();
    if (m < 0 || m > n) throw new ArgumentException();
    bool[] result = new bool[n];
    Random r = new Random();
    for (int i = 0; i < n; i++)
    {
        int j = r.Next(i + 1);
        result[i] = result[j];
        result[j] = (i < m);
    }
    return result;
}

C++ならstd::random_shuffle使えばいいね。
 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
using System;
using System.Collections.Generic;
class Program
{
  static void Main()
  {
    int n = 10, m = 3, seed = 1;
    Random r = new Random(seed);
    foreach (int i in GetRandom(n, m, r))
      Console.WriteLine(i);
  }
  public static int[] GetRandom(int n, int m, Random r)
  {
    n = Math.Max(n, 0);
    m = Math.Min(m, n);
    List<int> lst = new List<int>(n);
    for (int i = 0; i < n; ++i) lst.Add(i);
    for (int i = 0; i < m; ++i)
    {
      int k = r.Next(n - i) + i;
      int t = lst[i];
      lst[i] = lst[k];
      lst[k] = t;
    }
    lst.RemoveRange(m, n - m);
    lst.Sort();
    return lst.ToArray();
  }
}

yield句の便利さを最近知りました。
yield句を用いると、この手のコードを簡単にかけますね。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System;
using System.Collections;

class Program
{
    static void Main(string[] args) 
    {
        int n = 10, m = 4;
        foreach( var val in GetIterator(n,m) ) Console.WriteLine( val );
    }
    public static System.Collections.IEnumerable GetIterator( int n, int m)
    {
        Random r = new Random();
        ArrayList list = new ArrayList();
        for(int i=1; i<=n ; i++) list.Add( i );
        for(int i=0; i<m ; i++ )
        {
            var temp = list[r.Next(list.Count)];
            list.Remove(temp);
            yield return temp;
        }
    }
}

Index

Feed

Other

Link

Pathtraq

loading...