重複無し乱数
Posted feedbacks - Ruby
久々の1行問題
1 2 3 4 5 6 7 8 | def bingo(n)
(1..n).to_a.sort_by{rand}
end
bingo 10 # => [4, 2, 1, 10, 8, 5, 3, 7, 6, 9]
bingo 3 # => [3, 1, 2]
bingo 3 # => [1, 3, 2]
bingo 3 # => [2, 3, 1]
bingo 10 # => [3, 2, 6, 5, 7, 4, 1, 8, 10, 9]
|
普通にやってみた
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def bingo(num)
raise ArgumentError.new("fixnum only") unless num.kind_of? Fixnum
raise ArgumentError.new("1 ijyou de onegai simasu") unless num >= 1
results = []
ary=(1..num).to_a
ary.size.times{
index = (rand * ary.size).to_i
results << ary.delete_at(index)
}
results
end
|
Ruby 1.9にはArray#shuffleが存在します
1 2 3 | def bingo(n)
[*1..n].shuffle
end
|
どこかで見たことがある問題だなぁ… コードはあまり確かめずに書いた. 配列の参照範囲とか間違ってなければいいけど.
1 2 3 4 5 6 7 8 | def bingo( n )
ary = (1..n).to_a
n.downto(1) {| i |
e = ary.delete_at( rand( i ) )
ary.push( e )
}
ary
end
|
こうすると配列作成コスト1回で済む・・・? 繰り返し部分をxsを返す式にしようとinjectやら何やら色々試したけど いまひとつきれいにできないのであきらめました.
1 2 3 4 5 | def bingo(n)
xs = *1..n
n.times {|i| xs << xs.slice!(rand(n - i)) }
xs
end
|
うーん,なかなか短くならない.
1 2 3 4 5 | def bingo(n)
pool, ret = (1..n).to_a, []
ret << (pool.delete_at(rand(pool.size))) until pool.empty?
ret
end
|
randメソッドを利用して自作してみた.
1 2 3 4 | def bingo(n)
ary = Array.new(n){|i| i+1}
Array.new(n){|i| ary.delete_at(rand(n-i).modulo(n-i))}
end
|



raynstard
#3402()
Rating0/0=0.00
このお題はraynstardさんの投稿を元にしています。ご投稿ありがとうございました。 投稿の内容には表示のしかたも含まれていたのですが、 このお題では「重複しない1~nまでの乱数をどうやって作るか」という点に集中することにして、 結果の整形は続編としてこの後のお題で出すことにします。 サンプル入出力は下のようになります。
[ reply ]