ลูกเต๋าจากการเปลี่ยนเครื่องกำเนิดไฟฟ้าแบบสุ่ม


10

บทนำ

คุณจะได้รับตัวสร้างจำนวนเต็มแบบสุ่มด้วยการใช้งานต่อไป

  • การเรียกใช้ครั้งแรกส่งคืน 1 เสมอ
  • การเรียกใช้ที่สองส่งคืนจำนวนเต็มแบบสุ่มระหว่าง 1 ถึง 2
  • การเรียกใช้ที่สามส่งคืนจำนวนเต็มแบบสุ่มระหว่าง 1 ถึง 3
  • การร้องขอ nth ส่งคืนเลขจำนวนเต็มแบบสุ่มระหว่าง 1 ถึง n โดยรวม

ขึ้นอยู่กับฟังก์ชั่นด้านบนเขียนตัวสร้างลูกเต๋าแบบสุ่มที่สุ่มสมบูรณ์โดยส่งคืนค่าระหว่าง 1 ถึง 6 (รวม) ด้วยความน่าจะเป็นที่เท่ากัน

กฎระเบียบ

  • โปรแกรม / ฟังก์ชั่นของคุณควรส่งผลให้จำนวนเต็มแบบสุ่มระหว่าง 1 ถึง 6 รวมอยู่ในรูปแบบที่ใช้งานได้บางอย่างเช่นไปยังเอาต์พุตมาตรฐานหรือเป็นค่าส่งคืนฟังก์ชัน
  • ตัวสร้างตัวเลขสุ่มจากน้อยไปหามากสามารถกำหนดเป็นฟังก์ชัน "ฟรี" ในโปรแกรมของคุณ (เช่นไม่นับรวมตัวอักษรของคุณ) หรือสคริปต์ / โปรแกรมแยกต่างหากที่ดำเนินการตามที่ต้องการสมมติว่าสถานะ ( n) เป็นแบบถาวร ระหว่างการโทร
  • สมมติว่าไม่มีมากกว่า 1000 ลูกเต๋าม้วนจะได้รับการร้องขอที่เคยมีในกรณีที่ใช้เพียงครั้งเดียวของโปรแกรมของคุณและเริ่มต้นกำเนิดจำนวนสุ่มสามารถตั้งค่าเพื่อ1ที่ปลาย 1000 nลูกเต๋าม้วนเพื่อหลีกเลี่ยงการล้นของ
  • โปรแกรมของคุณต้องไม่ใช้แหล่งที่มาของตัวเลขสุ่มอื่นใดยกเว้นตัวสร้างแบบสุ่มจากน้อยไปหามากที่กำหนดไว้ด้านบน แน่นอนคุณอาจขอตัวเลขสุ่มหลายตัวจากตัวสร้างตัวเลขสุ่มสำหรับผลลัพธ์การทอยลูกเต๋าเดี่ยว ๆ
  • นี่คือรหัสกอล์ฟดังนั้นผู้ชนะคือคำตอบที่สั้นที่สุดหรือโหวตมากที่สุดในกรณีที่เสมอกัน ถ้าคุณสามารถสร้าง 1,000 ลูกเต๋าม้วนใช้น้อยกว่า 1,000 สร้างตัวเลขสุ่มให้ตัวเองโบนัสประสิทธิภาพ 10 จุด

ตัวอย่าง

./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

โปรแกรมiterate(6):b=asc-rand(); print bผิดกฎหมายหรือใช้งานไม่ได้? ฉันอาจเข้าใจผิดกฎข้อที่สาม
beary605

@ beary605: ตัวสร้างตัวเลขสุ่มสามารถตั้งค่าใหม่ได้หลังจากที่มีการหมุน 1,000 ลูกเต๋าทั้งที่ไม่ใช่ระหว่างการทอยลูกเต๋าทุกครั้ง เหตุผลเดียวที่ฉันพูดถึงคือการจัดการกับ overflow ที่เป็นไปได้ในค่าที่ส่งคืนโดยตัวสร้างตัวเลขสุ่มไม่ใช่หนึ่งในข้อกังวลในความท้าทายนี้ แก้ไข:ฉันชี้แจงวัตถุประสงค์ของกฎหวังว่าจะช่วยได้
mellamokb

เมื่อคุณพูดว่า "เลขสุ่ม" คุณหมายถึง "จำนวนเต็มแบบสุ่ม" หรือ "จำนวนสุ่ม (ตัด) จำนวนจริง" หรือไม่ อาจมีการประชุมบางอย่างที่ฉันไม่รู้
DavidC

@DavidCarraher: เป็นจุดที่ดีมาก ฉันหมายถึงจำนวนเต็มแบบสุ่มและฉันเห็นว่าไม่ชัดเจน ฉันจะอัปเดตคำถาม แก้ไข:อัปเดต
mellamokb

1
เราได้รับอนุญาตให้ถามตัวสุ่มว่ามันสร้างตัวเลขสุ่มกี่ครั้ง? ฉันอยู่ภายใต้ความประทับใจที่เราไม่สามารถทำได้
Matt

คำตอบ:


2

J - 13 ตัวอักษร

สิ่งนี้ทำให้สมมติฐานเดียวกันกับ Golfscript: จำนวนของลูกเต๋าอยู่ใน stdin และเราจะแสดงรายการลูกเต๋าที่จะออกมา

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

อธิบายโดยการระเบิด:

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

ถ้านั่นเป็นที่น่าพอใจอย่างใดนี่เป็นอีกโปรแกรม 21-char ที่สามารถเรียกใช้f''เพื่อสร้างตัวเลขสุ่มโดยมีสถานะและทุกอย่าง

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

analogues K: ฟังก์ชั่นแบบสุ่มฟรีr:{*1_draw x}, รุ่น stdin (10 ถ่าน) r'1+!. 0:` , รุ่นฟังก์ชั่น (14 ถ่าน) เรียกได้ว่าเป็นc:0;f:{r@c+:1} f[]
algorithmshark

6

Python 31 ตัวอักษร

ในทำนองเดียวกันกับ scleaver ให้นิยามตัวกำเนิดดังนี้:

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

จากนั้นฟังก์ชั่นเพื่อส่งคืนลูกเต๋า:

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

โทรได้D()ตลอดเวลาที่คุณต้องการทอยลูกเต๋าแบบสุ่มสม่ำเสมอ


อาชอบใช้ eval อย่างชาญฉลาดฉันชอบมันมาก
scleaver

3

สกาล่า 23

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

เมธอด r สามารถนำไปใช้ (โดยประมาณ) เช่นนี้:

var cnt = 0 
val rnd = new util.Random 

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

การทดสอบคร่าวๆ:

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)

ทุกการโทรครั้งที่ 6 ควรสร้างการกระจายตัวที่เท่าเทียมกันใน 6 ค่าดังนั้นฉันจึงทิ้ง 5


2

GolfScript (15 ตัวอักษร)

สมมติว่าจำนวนม้วนที่ต้องการนั้นมีอยู่ใน stdin และแสดงรายการผลลัพธ์จำนวนมากเพื่อ stdout

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

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

การสาธิตออนไลน์

ในขณะที่ฉันสามารถรับโบนัส 10 คะแนนสำหรับการใช้น้อยกว่า 1,000 ม้วนเพื่อสร้างตัวเลข 1,000 มันจะทำให้ฉันเสียค่าใช้จ่ายมากกว่า 10 ตัวอักษร วิธีการเล็กน้อยในการดึงเอนโทรปีที่เหมาะสมเมื่อ N เป็นพหุคูณของ 2 หรือ 3 ตกสั้นเพราะจำนวนผลลัพธ์ที่มี mod 3 มีเพียง 333 + 111 + 37 + 12 + 4 + 1 = 498 ดังนั้นจึงจำเป็นต้อง ใช้วิธีตัวอย่างและปฏิเสธ เมื่อใช้วิธีนี้คุณจะได้รับ 2242 ม้วนจากการโทร 1,000 rครั้ง แต่มีค่าใช้จ่ายเพิ่มเติมจากการจัดเก็บหนังสือและbaseเป็นชื่อฟังก์ชั่นที่ยาวมาก


5
"และbaseเป็นชื่อที่ฟังก์ชั่นที่ยาวมาก" คุณเห็นได้ชัดไม่ได้ใช้Mathematica เราได้รับสิ่งมหัศจรรย์เช่นNegativeBinomialDistribution, ExponentialGeneratingFunction, MathieuCharacteristicExponent, และInverseFourierSequenceTransform 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

ฟังก์ชั่นR()เป็นตัวสุ่มขึ้น

การใช้งาน:

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

ทำไมไม่กำจัดforลูปของคุณและเพียงโทรRหนึ่งครั้งก่อนที่whileลูปของคุณ?
Keith Randall

@KeithRandall หมายเลขที่ฉันส่งคืนเนื่องจากการทอยลูกเต๋าของฉันเป็นเลขตัวสุดท้ายของตัวเลขที่ตัวกำเนิดเรียงจากน้อยไปหามาก ฉันต้องโทรไปที่เครื่องกำเนิด 10 จากน้อยไปมากเพื่อให้แน่ใจว่าความน่าจะเป็นที่เท่ากันสำหรับตัวเลขที่เป็นไปได้ทั้งหมด
Matt

ทำไมต้องโทร 10 ครั้ง โดยหลักการแล้วหากเครื่องกำเนิดไฟฟ้าสุ่มการโทรแต่ละครั้งไม่ควรให้ความน่าจะเป็นเท่ากันสำหรับหลักสิบ (สิบ) ใด ๆ แน่นอนในทางปฏิบัติคุณสามารถคาดหวังว่าจะนับจำนวนเท่ากันสำหรับแต่ละตัวเลขเท่านั้น
DavidC

@DavidCarraher ตัวสร้างส่งกลับตัวเลขสุ่มจาก 1 ถึง n โดยที่ n คือจำนวนครั้งที่คุณเรียกมัน ฉันกำลังดูตัวเลขสุดท้ายของหมายเลขที่ส่งคืนนี้ ถ้า n ไม่ใช่จำนวนเต็มคูณด้วย 10 ความน่าจะเป็นไม่เท่ากัน ตัวอย่างเช่น: หาก n = 13 ความน่าจะเป็นจะลดลงดังนี้: 1/9 สำหรับม้วน 1,5,6 และ 2/9 สำหรับม้วน 2,3,4
แมตต์

@ Matt: ฉันคิดว่าR()จะส่งคืนทุ่นและคุณก็คว้าหลักที่สำคัญน้อยที่สุด ตอนนี้มันได้รับการชี้แจงที่R()ส่งกลับจำนวนเต็มมันทำให้รู้สึก
Keith Randall

1

Python 56

r หมายถึง:

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

เครื่องปั่นลูกเต๋า d:

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

การใช้งานเช่นสำหรับ 100 ม้วน:

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

คุณสามารถลบได้import mathถ้าคุณแทนที่math.ceil(...)ด้วยint(...)+1
Matt

ฉันต้องการ แต่มันจะผลิต 7 เป็นผลลัพธ์ที่เป็นไปได้
scleaver

โอ้ใช่. ฉันคิดถึงสิ่งนั้น
Matt

mellamokb ชี้แจงคำถามที่ฉันมีเกี่ยวกับตัวเพิ่มอันดับแบบสุ่ม คุณไม่ได้รับอนุญาตให้ขอ n
Matt

1

Mathematica 51

ตัวสร้างตัวเลขสุ่มrถูกรีเซ็ตโดยการตั้งค่าตัวแปรโกลบอลnเป็น 1

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

รหัส

ไม่ได้ทำงานอยู่สำหรับรหัสสั้นที่สุด ...

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

การใช้

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

60000 ม้วนของลูกเต๋าที่จำเป็น 60031 hโทรไป Tallyแสดงการแยกย่อยตามหมายเลข 1-6

60031

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


1

Perl, 22 หรือ 45

การใช้ตัวสร้างตัวเลขสุ่มจากน้อยไปมาก:

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

ฝ่ายผลิต:

#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 }

ทดสอบออก:

หมายเลข chisquare
1 1,0001867 0.348569
2 1,0004853 2.355161
3 9994395 3.141602
4 10,000177 0.003133
5 9999227 0.059753
6 9999481 0.026936
T 60000000 5.935154
ทอยลูกเต๋า 60000000 ม้วนใช้เวลา 600,00042 การโทรหา r และ 570.432735 วินาที



0

GolfScriptขนาด 8 ไบต์

f;3f*f(-

ลองออนไลน์!

มันจะหมุนตัวกำเนิดหนึ่งครั้งจากนั้นกำจัดผลลัพธ์ จากนั้นมันจะหมุน f2 และคูณด้วย 3 (3 หรือ 6) จากนั้นจึงลบ f3-1 (0, 1, 2) ซึ่งส่งผลให้ (3-2, 3-1, 3-0) หรือ (6-2, 6-1, 6-0) W5

Golfscript และฟังก์ชั่นแบบสุ่มมีอยู่ก่อนที่คำถามนี้จะถูกโพสต์ดังนั้นจึงเป็นเรื่องทางกฎหมาย

นี่คือการส่งแบบเรียกใช้ครั้งเดียวเท่านั้น หากคุณจำเป็นต้องเรียกใช้หลายครั้งในการโทรครั้งเดียว

GolfScriptขนาด 12 ไบต์

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

ลองออนไลน์!

สิ่งนี้จะรีเซ็ตการเรียกของคุณเป็น 0 ดังนั้นมันจะรีเซ็ตตาม TIO นี้แสดงผลลัพธ์สุ่ม 50 รายการ


0

C (gcc) , 31 ไบต์

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

ทุก 6 การโทรความน่าจะเป็นของทุกหมายเลขที่อยู่ระหว่าง 1 ถึง 6 รวมกันจะถูกสร้างขึ้นเท่ากัน

cคือ#defined เป็นการเรียกใช้ฟังก์ชันที่สร้างตัวเลขสุ่มที่สมบูรณ์แบบ

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.