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

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

Posted feedbacks - Ruby

単純に。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def lot(n, m)
  rest = Array.new(n) {|i| i }
  sel = []
  t = if m <= n/2 then m else n-m end
  n.downto(n-t+1) do |i|
    r = rand(i)
    sel << rest[r]
    rest.delete_at(r)
  end
  (if t == m then sel else rest end).sort
end

こんなのどうでしょう?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Array
  def randomize!
    rand_array = sort_by { |i| rand }
    replace rand_array
  end
end

def lot(n, m)
  if n >= m
    (1..n).to_a.randomize!.slice!(1, m).sort
  else
    puts "error: n must be bigger than m!"
    exit
  end
end

上の Ruby コードをもっと短くしてみた。
1
2
3
4
def lot(n, m)
 raise ArgumentError unless m > 0 && n > 0 && m <= n
 (1..n).to_a.sort_by {|i| rand}[0, m]
end

O(m)
n < m のとき循環します。
1
2
3
def lot(n,m)
  ((r=rand(n))...(r+m)).map {|e| e%n + 1 }
end

実際に使用する時は範囲チェック(1<=m<=n)を追加すること。
1
(1..n).sort_by{rand}[0,m]


	
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def kujibiki(users, m)
	raise ArgumentError unless users.size >= m 

	results=[]
	m.times{
		v=((users.size * rand()).to_i)
		results << users.delete_at(v)
	}
	results
end

users = [0,1,2,3,4,5,6,7,8,9]
p kujibiki(users, 10)

選んだ数が、結果の配列になければ追加します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
n = 10
m = 3
results = []

if 1 <= m && m <= n
  i = 0
  while i < m
    chosen_one = rand(n) + 1
    unless results.include?(chosen_one)
      results << chosen_one
      i += 1
    end
  end
  p results.sort
else
  puts "mは1以上n以下で指定してください。"
end

m > n でも n > m でも引数が1つでも公平に。shuffle使用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def kuji(n, m = n)
  m, n = n, m if m > n
  srand
  [*(1..n)].shuffle[0..(m-1)]
end

kuji(10, 3).sort # => [1, 2, 3]
kuji(3, 10).sort # => [2, 4, 6]
kuji(10, 10) # => [6, 7, 9, 1, 10, 4, 2, 3, 5, 8]
kuji(10) # => [10, 2, 8, 6, 1, 9, 4, 3, 5, 7]

こっちの方がRubyっぽいかしらん? IntegerクラスとRangeクラスに定義してみました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Integer
  def kuji(m = self)
    srand
    [*(1..self)].shuffle.first(m)
  end
end

class Range
  def kuji(m = self)
    srand
    [*self].shuffle.first([*m].last)
  end
end

#Integer
10.kuji(3) # => [2, 6, 10]
10.kuji # => [9, 10, 6, 1, 2, 3, 4, 5, 8, 7]

#Range
(1..10).kuji(3) # => [5, 4, 2]
(1..10).kuji # => [9, 6, 7, 4, 8, 5, 1, 10, 2, 3]

Index

Feed

Other

Link

Pathtraq

loading...