Rastgele Jeneratör Değişen Zar


10

Giriş

Aşağıdaki uygulama ile rastgele bir tamsayı oluşturucu verilir

  • İlk çağırma her zaman 1 değerini döndürür.
  • İkinci çağırma 1 ile 2 arasında rastgele bir tamsayı döndürür.
  • Üçüncü çağırma 1 ile 3 arasında rastgele bir tamsayı döndürür.
  • N'inci çağırma 1 ile n arasında (rastgele) bir tamsayı döndürür.

Yukarıdaki işleve dayanarak, eşit olasılıkla 1 ve 6 (dahil) arasında bir değer döndürerek, rasgele rastgele bir zar üreteci yazın.

kurallar

  • Programınız / işleviniz, bazı kullanılabilir biçimlerde, yani standart çıktıya veya işlev dönüş değeri olarak 1 ile 6 arasında rastgele bir tamsayı ile sonuçlanmalıdır.
  • Yukarıdaki artan rasgele sayı üreteci, programınızdaki "serbest" işlev (yani, karakter sayınıza sayılmaz) veya durumun ( n) kalıcı olduğu varsayılarak gerektiğinde yürütülen ayrı bir komut dosyası / program olarak tanımlanabilir. çağrılar arasında.
  • Programınızın tek kullanımlık durumunda 1000'den fazla zar atma talebinde bulunulmayacağını 1ve taşmalarını önlemek için ilk rasgele sayı üretecinin 1000 zar atma değerine sıfırlanabileceğini varsayın n.
  • Programınız kullanamaz herhangi yukarıda tanımlanan artan rastgele jeneratör hariç rasgele sayı diğer kaynağı. Elbette her bir zar rulosu çıkışı için rastgele sayı üretecinden birden fazla rastgele sayı isteyebilirsiniz.
  • Bu kod golf, bu yüzden kazanan en kısa cevap veya bir kravat durumunda çoğu oy. 1000'den az rastgele sayı kullanarak 1000 zar atarsanız, kendinize 10 puanlık bir verimlilik bonusu verin .

Misal

./asc-rand
1 # random integer between 1 and 1
./asc-rand
1 # random integer between 1 and 2
./asc-rand
3 # random integer between 1 and 3
./asc-rand
4 # random integer between 1 and 4

# dice-gen generates random dice based on output of asc-rand program.
./dice-gen
3
./dice-gen
6
./dice-gen
5
./dice-gen
1

Program iterate(6):b=asc-rand(); print byasa dışı mı yoksa çalışmıyor mu? Üçüncü kuralı yanlış anlayabilirim.
beary605

@ beary605: Rastgele sayı üreteci, her zar rulosu arasında değil, tüm 1000 zar rulosundan sonra sıfırlanabilir. Rastgele sayı üreteci tarafından döndürülen değer üzerinde olası taşmalar ile uğraşmaktan bahsetmemin tek nedeni bu zorluğun endişelerinden biri değil . Düzenleme: Kuralın amacını açıkladım, umarım yardımcı olur.
mellamokb

"Rasgele sayı" derken "rasgele tamsayı" veya "rasgele (kısaltılmış) gerçek sayı" mı demek istediniz? Belki farkında olmadığım bir kongre var.
DavidC

@DavidCarraher: Çok iyi bir nokta. Rastgele tam sayı demek istiyordum ve görüyorum ki bu net değil. Soruyu güncelleyeceğim. Düzenleme: Güncellendi.
mellamokb

1
Rasgeleleştiriciye kaç kez rasgele sayılar ürettiğini sorabilir miyiz? Yapamayacağımız izlenimi altındaydım.
Matt

Yanıtlar:


2

J - 13 karakter

Bu, Golfscript ile aynı varsayımları yapar: zar sayısının stdin'de olduğu ve ortaya çıkacak zar atışlarını listeledik.

r=:1+?  NB. free random function
r>:i.".1!:1]1

Patlama ile açıklanıyor:

r=:1+?           NB. r(x) = 1 + a random number between 0 and n-1
           ]1    NB. input file handle
       1!:1      NB. read in a string
     ".          NB. convert to integer
 >:i.            NB. make a list of numbers, from 1 to that integer
r                NB. apply the random function

Bu bir şekilde tatmin edici değilse, burada f''bir durum ve her şeyi içeren rastgele sayılar üretmek için çağrılabilecek daha uzun, 21 karakterlik bir program var .

r=:1+?  NB. free random function
c=:0
f=:3 :'r c=:1+c'

K analogları: serbest rasgele fonksiyon r:{*1_draw x}, stdin versiyonu (10 karakter) r'1+!. 0:` , fonksiyon versiyonu (14 karakter) c:0;f:{r@c+:1}denir f[].
algoritmalarhark

6

Python, 31 karakter

Scleaver'a benzer şekilde jeneratörü şu şekilde tanımlayın:

from random import randint
n=0
def r():
    global n;n+=1
    return randint(1,n)

Sonra zar ruloları döndürmek için bir fonksiyon:

D=lambda:eval('r(),'*6)[-1]%6+1

D()Düzgün rasgele bir zar rulosuna ihtiyacınız olduğunda arayın .


Ah, evalün akıllı kullanımı, hoşuma gitti.
scleaver

3

Scala 23

def s={r;r;r;r;r;r%6+1}

R yöntemi (yaklaşık) şu şekilde uygulanabilir:

var cnt = 0 
val rnd = new util.Random 

def r = {
  cnt %= 1000
  cnt += 1
  rnd.nextInt (cnt)
}

kaba bir test:

scala> (1 to 6).map (i => ((1 to 600) map (_=>s)).filter (_ == i).size)
res26: scala.collection.immutable.IndexedSeq[Int] = Vector(110, 105, 91, 96, 106, 102)

Her 6. çağrı 6 değer üzerinde eşit bir dağılım üretmelidir, bu yüzden 5'i atıyorum.


2

GolfScript (15 karakter)

Bu, gerekli rulo sayısının stdin'de sağlandığını varsayar ve stdout için birçok sonucu listeler.

# The free increasing random function
0:N;{N):N rand)}:r;

~{r{;r}5*6%)n}*

Çevrimiçi demo

1000 sayı üretmek için 1000'den az rulo kullandığım için 10 puanlık bonus kazanabilirken, bana 10 karakterden daha fazla mal olacak. N, 2 veya 3 gücünün katları olduğunda uygun entropinin çıkarılmasının önemsiz yaklaşımı çok kısadır, çünkü mod 3 mevcut sonuçların sayısı sadece 333 + 111 + 37 + 12 + 4 + 1 = 498'dir. örnekleme ve reddetme yaklaşımını benimsemek. Bu yaklaşımı kullanarak 1000 çağrıdan 2242 rulo bekleyebilirsiniz r, ancak defter tutmanın ekstra yükü vardır ve baseçok uzun bir işlev adıdır.


5
"ve baseçok uzun bir işlev adı" Görünüşe göre Mathematica kullanmıyorsunuz . Biz gibi mucizeler olsun NegativeBinomialDistribution, ExponentialGeneratingFunction, MathieuCharacteristicExponent, InverseFourierSequenceTransform, ve SemialgebraicComponentInstances. :-)
Mr.Wizard

1

Python 65 63

i=7
while i>5:[R()for x in range(9)];i=int(`R()`[-1])
print i+1

İşlev R(), yükselen randomize edicidir.

Kullanımı:

$ ./rollDice.py
3
$ ./rollDice.py
5

Neden döngünüzden kurtulmayın forve Rdöngünüzden önce bir kez arayın while?
Keith Randall

@KeithRandall Zar atma olarak döndürdüğüm sayı, yükselen jeneratörün döndürdüğü sayının son basamağıdır. Tüm olası basamaklar için eşit olasılıkları sağlamak için artan jeneratöre 10 çağrı yapmam gerekiyor.
Matt

Neden 10 çağrı? Prensipte, jeneratör rastgele ise, her çağrı (on) basamaktan herhangi biri için eşit olasılık sunmamalıdır mı? Tabii ki, pratikte, sadece sayıların her biri için eşit sayılara yaklaşmayı bekleyebilirsiniz.
DavidC

@DavidCarraher Jeneratör, 1'den n'ye rastgele sayılar döndürür; burada n, kaç kez çağırdığınızdır. Bu döndürülen sayının son basamağına bakıyorum. N, 10'un bir tam sayı katı değilse, olasılık muntazam olmayacaktır. Örneğin: n = 13 ise, olasılıklar şu şekilde parçalanır: 1,5,6 rulolar için 1/9 ve rulolar için 2/9 2,3,4
Matt

@Matt: R()Bir şamandıra döndürdüğünü ve en önemsiz rakamı yakaladığınızı varsaydım . Şimdi R()bir tamsayıyı döndürdüğü açıklığa kavuştuğuna göre , mantıklı.
Keith Randall

1

Python, 56

r şu şekilde tanımlanır:

from random import randint
n=0
def r(z):
    global n;n+=1
    return randint(1,n)

zar üreteci d:

import math;d=lambda:math.ceil(6.*r(r(r(r(r(r(0))))))/n)

kullanım, örneğin, 100 rulo için:

for i in range(100):print d()

ile import mathdeğiştirirseniz büyük olasılıkla silebilirsinizmath.ceil(...)int(...)+1
Matt

Yapardım, ancak 7 olası bir çıktı olarak üretecekti.
scleaver

Ah evet. Onu özledim.
Matt

mellamokb yükselen randomizatör hakkında sahip olduğum bir soruyu açıklığa kavuşturdu. Sizden n istemenize izin verilmiyor.
Matt

1

Mathematica 51

Rasgele sayı üreteci, rgenel değişken n1'e ayarlanarak sıfırlanır .

n = 1; r[c_] := RandomInteger[{1, c}]

kod

En kısa kod için değil ...

h := (n++; If[n < 4 \[Or] (y = r@n) > 6 Quotient[n, 6], h, y~Mod~6 + 1])

kullanım

t = Table[h, {60000}];
n
SortBy[Tally[t], First]

60000 zar zar gerekli 60031 çağrı h. Tally1-6 sayılarına göre dökümü gösterir.

60031

{{1, 9923}, {2, 9966}, {3, 10016}, {4, 10028}, {5, 10009}, {6, 10058}}


1

Perl, 22 veya 45

Artan rastgele sayı üretecinin uygulanması:

my $n=0;
sub r { $n++; return 1+int(rand$n); }

Üretme:

#copy of the Scala solution; short code; uses 6N rolls
sub s{r;r;r;r;r;1+r%6}
#more efficient implementation, uses approximately 6+N+lnN rolls
sub roll { do{$a=r-1}while($a>$n-$n%6);return 1+(1+$a)%6 }

Test etme:

n numarası chisquare
1 10001867 0.348569
2 10004853 2.355161
3 9994395 3.141602
4 10000177 0.003133
5 9999227 0.059753
6 9999481 0.026936
T 60000000 5.935154
60000000 zar atma 60000042 r ve 570.432735 saniyeye çağrı aldı


0

x86 opcode, 15 bayt

f:  mov cx, 6
    call r ; return in AX
    loop $-3
    cwd
    div word [f+1]
    inc dx
    ret ; return in DX

Görünüşe göre bu düşük kaliteli bir yazı mı?
Muhammed Salman

0

GolfScript , 8 bayt

f;3f*f(-

Çevrimiçi deneyin!

Jeneratörü bir kez açar, sonra sonuçtan kurtulur. Daha sonra f2 yuvarlar ve 3 (3 veya 6) ile çarpar, ardından f3-1 (0, 1, 2) çıkarır (3-2, 3-1, 3-0) veya (6-2, 6-1, 6-0) W5.

Golfscript ve rastgele fonksiyon bu soru gönderilmeden önce vardı, bu yüzden yasal bir başvuru.

Bu yalnızca bir kez çalıştırılan gönderidir. Bir çağrıda birkaç kez çalıştırmanız gerekiyorsa,

GolfScript , 12 bayt

f;3f*f-)0:i;

Çevrimiçi deneyin!

Bu, i çağrınızı 0'a sıfırlar, böylece buna göre sıfırlanır. Bu TIO 50 rastgele sonuç göstermektedir.


0

C (gcc) , 31 bayt

f(i){for(i=5;i--;)c;i=~-c%6+1;}

Her 6 çağrıda bir, 1 ile 6 dahil her sayının üretilme olasılığı eşittir.

colan #definemükemmel rasgele sayılar üreten bir işlev çağrısı olarak d.

Çevrimiçi deneyin!

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.