รับเหรียญที่ยุติธรรมเป็นอินพุตให้สร้างผลลัพธ์ที่ไม่เป็นธรรมโดยเฉพาะ


13

มันง่ายที่จะสร้างเหรียญที่ยุติธรรมโดยใช้เหรียญที่ไม่เป็นธรรม แต่สิ่งที่ตรงกันข้ามนั้นยากที่จะทำ

โปรแกรมของคุณจะได้รับหนึ่งหมายเลขX (ระหว่าง 0 ถึง 1, รวม) เป็นอินพุต ข้อมูลที่ป้อนต้องไม่ถูกกำหนดค่าตายตัวเป็นตัวเลขที่อยู่ตรงกลางของซอร์สโค้ด จากนั้นจะต้องส่งคืนหลักเดียว: a ที่1มีความน่าจะเป็นXและ a 0อย่างอื่น

โปรแกรมของคุณได้รับอนุญาตให้ใช้ตัวสร้างตัวเลขสุ่มเพียงหนึ่งรูปแบบในซอร์สโค้ด: int(rand(2))(หรือเทียบเท่า) ซึ่งจะส่งกลับค่าศูนย์หรืออันที่มีความน่าจะเป็นเท่ากัน คุณสามารถรวมหรือเข้าถึงฟังก์ชั่นนี้หลาย ๆ ครั้งตามที่คุณต้องการในรหัสของคุณ คุณต้องให้ฟังก์ชั่นด้วยตัวคุณเองเป็นส่วนหนึ่งของรหัส

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

นี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุดชนะ


อินพุตใช้รูปแบบใด หากเรารับประกันว่าเป็นเลขทศนิยมของ IEEE-754 ตามขนาดที่กำหนดนี่เป็นเรื่องง่ายมาก
Peter Taylor

คำตอบ:


4

Perl, 37 42ถ่าน

($d/=2)+=rand>.5for%!;print$d/2<pop|0

รับค่าความน่าจะเป็นโดยพลการเป็นอาร์กิวเมนต์บรรทัดคำสั่ง สร้างตัวเลขสุ่มที่เหมือนกัน$dและเปรียบเทียบกับอินพุต

ก่อนหน้านี้วิธีแก้ปัญหาถ่าน 52 ตัว

$p=<>;do{$p*=2;$p-=($-=$p)}while$--(.5<rand);print$-

1
ฉันประทับใจที่คุณกลับมาอีก 6 ปีต่อมาเพื่อปรับปรุงวิธีการแก้ปัญหานี้
Misha Lavrov

3

Python 81 ตัวอักษร

import random
print(sum(random.randint(0,1)*2**-i for i in range(9))<input()*2)+0

สามารถปิดได้เล็กน้อย แต่ไม่เกิน 1%


ดูดีกว่า 1% สำหรับฉัน ฉันใช้โปรแกรมของคุณ 100,000 ครั้งสำหรับความน่าจะเป็น [0,1] ด้วยขั้นตอนที่ 0.01 และเปรียบเทียบกับการrandom.random() < desiredProbabilityใช้สคริปต์นี้: gist.github.com/3656877พวกเขาเข้ากันได้อย่างสมบูรณ์แบบi.imgur.com/Hr8uE.png
Matt

แม้ว่าตามที่คาดไว้random.random() < xจะเร็วกว่ามาก
แมตต์

3

Mathematica 165

ไม่คล่องตัว แต่บางคนอาจพบอัลกอริทึมที่น่าสนใจ:

d = RealDigits; r = RandomInteger;
f@n_ := If[(c = Cases[Transpose@{a = Join[ConstantArray[0, Abs[d[n, 2][[2]]]], d[n, 2][[1]]], 
         RandomInteger[1, {Length@a}]}, {x_, x_}]) == {}, r, c[[1, 1]]]

การใช้

f[.53]

1

ตรวจสอบ

ลองดูว่าf[.53]จะสร้างมูลค่า1ประมาณ 53% ของเวลาหรือไม่ การทดสอบแต่ละครั้งจะคำนวณ% สำหรับตัวอย่างที่ 10 ^ 4

50 การทดสอบดังกล่าวจะถูกเรียกใช้และโดยเฉลี่ย

Table[Count[Table[f[.53], {10^4}], 1]/10^4 // N, {50}]
Mean[%]

{0.5292, 0.5256, 0.5307, 0.5266, 0.5245, 0.5212, 0.5316, 0.5345, 0.5297, 0.5334, 0.5306, 0.5286, 0.5288, 0.5289, 0.5293, 0.5263, 0.5393, 0.5192, 0.5195, 0.5195, 0.5209, 0.5382, 0.5382, 0.538, , 0.5297, 0.5318, 0.5243, 0.5281, 0.5361, 0.5349, 0.5308, 0.5265, 0.5309, 0.5233, 0.5233, 0.5345, 0.5316, 0.5376, 0.5264, 0.5269, 0.5295, 0.523, 0.523, 0.523, 0.5294, 0.5324, 0.5316, 0.5316, 0.528, }

0.529798

ฮิสโตแกรมของผลลัพธ์

histogram

คำอธิบาย (การแจ้งเตือนสปอยเลอร์!)

การแสดงฐาน 2 ของ. 53 คือ

.10000111101011100001010001111010111000010100011110110

ดำเนินการต่อจากซ้ายไปขวาทีละหนึ่งหลัก:

ถ้า RandomInteger [] ส่งคืน 1 ให้ตอบ = 1

มิฉะนั้นถ้า RandomInteger ตัวที่สอง [] ส่งคืนค่า 0 ให้ตอบ = 0

มิฉะนั้นถ้า RandomInteger ตัวที่สาม [] ส่งคืนค่า 0 คำตอบ = 0

อื่น....

หากเมื่อทุกตัวเลขได้รับการทดสอบยังคงไม่มีคำตอบให้ตอบ = RandomInteger []


1

Haskell, 107 ตัวอักษร:

import System.Random
g p|p>1=print 1|p<0=print 0|1>0=randomIO>>=g.(p*2-).f
f x|x=1|1>0=0.0
main=readLn>>=g

0

ภาษา Wolfram (Mathematica) , 42 ไบต์

RandomInteger[]/.⌈1-2#⌉:>#0@Mod[2#,1]&

ลองออนไลน์!

นี่เป็นวิธีแบบเรียกซ้ำ Ungolfed อัลกอริทึมคือ:

  • ถ้าความน่าจะป้อนข้อมูลที่pมีค่าน้อยกว่า 1/2 แล้วเมื่อ Coinflip ขึ้นมา 0 กลับ 0. มิฉะนั้น recurse บน2p; สมมติว่าถูกต้องน่าจะเป็นภาพรวมของการได้รับ 1 เป็นครึ่งหนึ่งของหรือ2pp
  • ถ้าความน่าจะป้อนข้อมูลที่pมีค่ามากกว่า 1/2 แล้วเมื่อ Coinflip ขึ้นมา 1 กลับ 1. มิฉะนั้น recurse บน2p-1; สมมติว่าถูกต้องน่าจะเป็นภาพรวมของการรับ 0 เป็นครึ่งหนึ่งของหรือ1-(2p-1)1-p

เพื่อให้สั้นลงเราเริ่มต้นด้วยการสุ่ม coinflip ซึ่งในแต่ละสาขาจะได้รับคืนครึ่งเวลา หาก coinflip ไม่ตรงกับกรณีที่เราควรส่งคืนให้แทนที่ด้วยผลของการเรียกใช้ซ้ำใน2pmodulo 1 (นั่นคือเมื่อpน้อยกว่า 1/2 ให้แทนที่ 1 เมื่อpมีค่ามากกว่า 1/2 , แทนที่ 0 นี่เทียบเท่ากับการแทนที่⌈1-2p⌉)

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