Ruby'de rastgele bir sayı nasıl alınır


Yanıtlar:


952

kullanım rand(range)

Gönderen Yakut Rastgele Numaraları :

Eğer altı kenarlı kalıp bir rulo simüle etmek rasgele bir sayı Gerekirse, kullanmak: 1 + rand(6). Craps'ta bir rulo simüle edilebilir 2 + rand(6) + rand(6).

Son olarak, sadece rastgele bir kayan noktaya ihtiyacınız varsa, randargüman olmadan arayın .


As Marc-André Lafortune bahsedildi (o upvote go) altına onun cevabını , Ruby 1.9.2 kendi vardır Randomsınıfını (Marc-André kendisi o debug yardımcı dolayısıyla 1.9.2 hedef bu özellik için).

Örneğin, 10 sayı tahmin etmeniz gereken bu oyunda , bunları şu şekilde başlatabilirsiniz:

10.times.map{ 20 + Random.rand(11) } 
#=> [26, 26, 22, 20, 30, 26, 23, 23, 25, 22]

Not:

"Eşdeğer sıfırdan büyük veya ona eşit ve argümandan küçük rastgele bir tamsayı" döndürdüğünden , bu nedenle eşdeğer Random.new.rand(20..30)olur . 30'u içeriyorsa, 11 hariç 0 ile 11 arasında rastgele bir sayı bulmam gerekiyor.20 + Random.rand(11)Random.rand(int)20..30


2
Bu çok yakut olmayan bir şey değil mi? Her şeyin bir nesne, en az sürpriz olduğunu düşündüm ve ...
Dan Rosenstark

1
@yar: Biraz "ölüyor". Şimdi Ruby'de Rasgele bir sınıf var (cevabımı gör)
Marc-André Lafortune

3
@VonC: Cevabınızı yeni Randomsınıftan bahsetmek için düzenlediğiniz harika , ancak Random.newörneğinizde olduğu gibi birden çok kez aramak korkunç bir fikir . Cevabımı bunu belirtmek için düzenledim.
Marc-André Lafortune

2
@VonC ah :) ben biraz sert olsaydım üzgünüm, sadece beni şaşırttı
horseyguy

1
Random.rand yok aslında, bir dizi kabul eder. (
1.9.3'ten

591

Eğer kullanabilirsiniz ancak rand(42-10) + 10arasında rastgele bir sayı elde etmek 10ve 42(10 dahil olup 42 seçkin olduğu), aramak edebiliyoruz Ruby 1.9.3, çünkü daha iyi bir yol var:

rand(10...42) # => 13

Benim backportsmücevher gerektiren Ruby tüm sürümleri için kullanılabilir .

Ruby 1.9.2 ayrıca Randomkendi rastgele sayı üreteci nesnelerinizi oluşturabilmeniz ve güzel bir API'ye sahip olmanız için sınıfı tanıttı :

r = Random.new
r.rand(10...42) # => 22
r.bytes(3) # => "rnd"

RandomDoğrudan çağrı böylece sınıf kendisi rastgele jeneratör görevi görür:

Random.rand(10...42) # => same as rand(10...42)

İle ilgili notlar Random.new

Çoğu durumda, en basit randveya kullanmaktır Random.rand. Rastgele bir sayı istediğinizde yeni bir rastgele jeneratör oluşturmak gerçekten kötü bir fikirdir . Bunu yaparsanız, rastgele jeneratörün özelliklerine kıyasla acımasız olan ilk tohumlama algoritmasının rastgele özelliklerini elde edersiniz .

Eğer kullanırsanız Random.new, böylece aramak gerekir olarak nadiren mümkün olduğu gibi bir kez, örneğin MyApp::Random = Random.newve her yerde kullanabilirsiniz.

Random.newYararlı olduğu durumlar şunlardır:

  • Eğer bir mücevher yazıyoruz ve dizisi ile müdahale istemiyoruz rand/ Random.randana programlar güvenerek olabileceğini
  • rastgele sayıların ayrı tekrarlanabilir dizilerini istiyorsunuz (her iş parçacığı için bir tane söyleyin)
  • rasgele sayıların tekrarlanabilir bir sekansını kaydedip devam ettirmek istersiniz ( Randomnesneler sıralanabilirken kolay )

1
Mükemmel! +1. Bu yeni özelliği yansıtmak için kendi cevabımı tamamladım (ve Hata # 3104; ile katkınızdan bahsederek).
VonC

1
@yar: backportsGemim RUby 1.8.7, 1.9.1, 1.9.2 için yeni olan ancak Ruby'de uygulanan bir yöntem koleksiyonudur. Sonuçların Ruby ile uyumlu olmasını sağlamak için RubySpec kullanıyorum.
Marc-André Lafortune

@ Marc-André Lafortune, bunun için teşekkürler. Hız gereksinimleri nedeniyle Ruby olmayan (C ya da her neyse) Ruby'nin ne kadarının uygulandığı bana garip geldi. Ama ara
verdik

5
Random.rand(10..42)çalışmıyor. Random.randSınıf yöntemi bir dizi kabul etmez. (Yakut 1.9.2p180)
horseyguy

1
@banister: vay canına, yeni api'nin (aralık, bayt vb. ile rand) doğrudan Random nesnesi aracılığıyla kullanılabilir olduğuna ikna oldum. aralıklı rand 1.9.3 olacak ve ben bayt için bir özellik isteği yapacağım. Cevabımı düzenledim
Marc-André Lafortune

46

Sadece bir sayı değil, aynı zamanda hex veya uuid arıyorsanız, modülün 1.9.2+ sürümünde yakut çekirdeğe doğru SecureRandomyol aldığını ActiveSupportbelirtmek gerekir. Yani tam gelişmiş bir çerçeveye ihtiyaç duymadan:

require 'securerandom'

p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88

p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409

p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"

Burada belgelenmiştir: Ruby 1.9.3 - Modül: SecureRandom (lib / securerandom.rb)


4 basamaklı rasgele sayıya ihtiyacınız varsa ne olur?
onurozgurozkan

1
sanırım SecureRandom.random_number(1000..9999)
onurozgurozkan

1
SecureRandom.random_number()bir aralık almaz, bu yüzden hayır. Muhtemelen SecureRandom.random_number(10_000)(0-9999 için) veya SecureRandom.random_number(9_000)+1_000(1000-9999 için ) gibi bir şey istersiniz .
mwp

1
Random.rand (1000..9999)
Jesse Farmer

37

randYöntemle rastgele bir sayı oluşturabilirsiniz . randYönteme iletilen bağımsız değişken bir integerveya a olmalıdır rangeve aralık içinde karşılık gelen rasgele bir sayı döndürür:

rand(9)       # this generates a number between 0 to 8
rand(0 .. 9)  # this generates a number between 0 to 9
rand(1 .. 50) # this generates a number between 1 to 50
#rand(m .. n) # m is the start of the number range, n is the end of number range

Bence rand(1..6)okumalarınızı en çok cevaplayandan daha net kullanın rand(6)+1.
isomorphismes

21

Anladım. Görünüşe göre rand adlı yerleşik bir (?) İşlevi var:

rand(n + 1)

Birisi daha ayrıntılı bir cevapla cevap verirse, bunu doğru cevap olarak işaretleyeceğim.


2
Evet, Çekirdek modülünde yerleşiktir.
Christoph Schiessl

17

Peki buna ne dersin?

n = 3
(0..n).to_a.sample

3
Bu çözüm gibi bir sayı dizisi oluşturmanın, O (n) iken randO (1) olduğu gibi geniş aralıklarda korkunç performansa sahip olduğuna dikkat edilmelidir .
Travis


9

Sadece kullanabilirsiniz random_number.

Pozitif bir tamsayı n olarak verilirse, random_numberbir tamsayı döndürür: 0 <= random_number<n.

Şöyle kullanın:

any_number = SecureRandom.random_number(100) 

Çıktı 0 ile 100 arasında herhangi bir sayı olacaktır.


6
rand(6)    #=> gives a random number between 0 and 6 inclusively 
rand(1..6) #=> gives a random number between 1 and 6 inclusively

Range seçeneğinin yalnızca ruby'nin daha yeni (1.9+ sanırım) sürümlerinde kullanılabildiğini unutmayın.


Aralık seçeneğinin yalnızca içinde mevcut olduğuna inanıyorum ruby 1.9.3+. 1.9.2En azından denediğimde işe yaramadı .
Batkins

6

aralık = 10..50

Rand (aralık)

veya

range.to_a.sample

veya

range.to_a.shuffle (bu, tüm diziyi karıştırır ve rastgele bir sayı seçmek için ilk veya son olarak rastgele bir sayı veya bu diziden herhangi birini seçebilirsiniz)


range.to_a.sampleörnek büyük olduğunda korkunç bir fikirdir.
Grzegorz


4

Bu bağlantı bu konuda yardımcı olacaktır;

http://ruby-doc.org/core-1.9.3/Random.html

Ve yakutta rastgele sayılar üzerinde biraz daha netlik;

0 ile 10 arasında bir tamsayı oluşturun

puts (rand() * 10).to_i

0'dan 10'a kadar bir sayı oluşturun Daha okunabilir bir şekilde

puts rand(10)

15 dahil 10'dan 15'e kadar bir sayı oluşturun

puts rand(10..15)

Rastgele Olmayan Rastgele Sayılar

Program her çalıştırıldığında aynı sayı dizisini oluşturun

srand(5)

10 rasgele sayı üret

puts (0..10).map{rand(0..10)}

Ayrıca yakut rastgele nos üzerinde çok net bir resim için adım adım bu blog takip edebilirsiniz; sitepoint.com/tour-random-ruby
Sam

4

Ruby'de rastgele sayı almanın kolay yolu,

def random    
  (1..10).to_a.sample.to_s
end

2

Belki sana yardım eder. Bunu uygulamamda kullanıyorum

https://github.com/rubyworks/facets
class String

  # Create a random String of given length, using given character set
  #
  # Character set is an Array which can contain Ranges, Arrays, Characters
  #
  # Examples
  #
  #     String.random
  #     => "D9DxFIaqR3dr8Ct1AfmFxHxqGsmA4Oz3"
  #
  #     String.random(10)
  #     => "t8BIna341S"
  #
  #     String.random(10, ['a'..'z'])
  #     => "nstpvixfri"
  #
  #     String.random(10, ['0'..'9'] )
  #     => "0982541042"
  #
  #     String.random(10, ['0'..'9','A'..'F'] )
  #     => "3EBF48AD3D"
  #
  #     BASE64_CHAR_SET =  ["A".."Z", "a".."z", "0".."9", '_', '-']
  #     String.random(10, BASE64_CHAR_SET)
  #     => "xM_1t3qcNn"
  #
  #     SPECIAL_CHARS = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "=", "+", "|", "/", "?", ".", ",", ";", ":", "~", "`", "[", "]", "{", "}", "<", ">"]
  #     BASE91_CHAR_SET =  ["A".."Z", "a".."z", "0".."9", SPECIAL_CHARS]
  #     String.random(10, BASE91_CHAR_SET)
  #      => "S(Z]z,J{v;"
  #
  # CREDIT: Tilo Sloboda
  #
  # SEE: https://gist.github.com/tilo/3ee8d94871d30416feba
  #
  # TODO: Move to random.rb in standard library?

  def self.random(len=32, character_set = ["A".."Z", "a".."z", "0".."9"])
    chars = character_set.map{|x| x.is_a?(Range) ? x.to_a : x }.flatten
    Array.new(len){ chars.sample }.join
  end

end

https://github.com/rubyworks/facets/blob/5569b03b4c6fd25897444a266ffe25872284be2b/lib/core/facets/string/random.rb

Benim için iyi çalışıyor



1

Rasgeleleştirme array#shuffleyöntemini deneyin

array = (1..10).to_a
array.shuffle.first

1
Eğer varsa gereken bütün bir diziyi yapmak, en azından yerini .shuffle.firstile .sample!
Camille Goudeseune

0

Önce RNG'yi srand () ile tohumlamayı unutmayın .


2
Srand () öğesini çağırmazsanız ne olur?
Alex B

21
tohum, önceden çağrılmadıysa tohum o anki zamandan itibaren otomatik olarak çağrılır.
Julian H
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.