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

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

Posted feedbacks - Python

こんなんで。
1
2
3
4
5
6
7
8
9
import random
def lot(n,m):
    if n<m:
        print "Error"
        return
    myset = set()
    while len(myset)!=m:
        myset.add(random.randint(0,n-1))
    return myset

Pythonのrandomモジュールには、与えられたリストをシャッフルするshuffleという関数があります。
1
2
3
4
5
def lot(n, m):
    from random import shuffle
    people = range(n)
    shuffle(people)
    return people[:m]

その発想はなかったです。
確かに当選者を連続にとっても、それぞれの人の当選確率は同じなので公平ですね。
その発想をPythonで実装しました。
1
2
3
4
def lot(n, m):
    from random import random
    start = int(random() * n)
    return (range(n)+range(m))[start:start + m]

Pythonのrandomは高機能です。
1
2
3
4
def lot(n,m):
    from random import sample
    people = xrange(n)
    return sample(people,m)

今ひとつエレガントじゃないなぁ。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# -*- coding: utf-8 -*-
import random

def getRandList(x):
    l = range(x)
    random.shuffle(l)
    return l

def chusen(n,m):
    return getRandList(n)[:m]

print chusen(10,5)
print chusen(50,10)

random.shuffleは便利ですが、それだと味気ないので‥‥。

Rubyの「Enumerable#sort_by { rand }」と同じ発想でシャッフルしてみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import random
import sys

def lot(n, m):
  a = [(x, random.random()) for x in range(1, n + 1)]
  a.sort(lambda x, y: cmp(x[1], y[1]))
  return [x[0] for x in a][0:m]

if len(sys.argv) != 3:
  print "usage: %s all pickup" % (sys.argv[0])
else:
  print lot(int(sys.argv[1]), int(sys.argv[2]))

Index

Feed

Other

Link

Pathtraq

loading...