Đưa ra một đồng tiền công bằng làm đầu vào, tạo ra bất kỳ kết quả không công bằng cụ thể nào


13

Thật dễ dàng để tạo ra một đồng tiền công bằng bằng cách sử dụng một đồng tiền không công bằng, nhưng điều ngược lại khó thực hiện hơn.

Chương trình của bạn sẽ nhận được một số X (từ 0 đến 1, bao gồm) làm đầu vào. Đầu vào không chỉ đơn giản là được mã hóa cứng như một số ở giữa mã nguồn. Sau đó, nó phải trả về một chữ số duy nhất: a 1với xác suất X0ngược lại.

Chương trình của bạn chỉ được phép sử dụng một dạng trình tạo số ngẫu nhiên trong mã nguồn: int(rand(2))(hoặc tương đương), trả về số 0 hoặc dạng có xác suất bằng nhau. Bạn có thể bao gồm hoặc truy cập chức năng này nhiều lần bạn muốn trong mã của mình. Bạn cũng phải tự cung cấp chức năng như một phần của mã.

Chương trình của bạn không được phép sử dụng bất kỳ hàm tạo số ngẫu nhiên nào khác hoặc các nguồn bên ngoài (như hàm thời gian và ngày) có thể hoạt động như một hàm tạo số ngẫu nhiên. Nó cũng không thể truy cập bất kỳ tập tin bên ngoài hoặc chuyển công việc cho các chương trình bên ngoài.

Đây là mã golf, câu trả lời ngắn nhất chiến thắng.


Hình thức nào đầu vào mất? Nếu chúng tôi đảm bảo rằng đó là số dấu phẩy động của IEEE-754 với kích thước nhất định, thì điều này thực sự khá dễ dàng.
Peter Taylor

Câu trả lời:


4

Perl, 37 42 char

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

Lấy xác suất tùy ý làm đối số dòng lệnh. Xây dựng một số ngẫu nhiên thống nhất trong $dvà so sánh nó với đầu vào.

Trước đó, giải pháp 52 char

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

1
Tôi ấn tượng rằng bạn đã quay lại 6 năm sau để tối ưu hóa giải pháp này.
Misha Lavrov

3

Con trăn, 81 ký tự

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

Có thể tắt một chút, nhưng không bao giờ hơn 1%.


Có vẻ tốt hơn nhiều so với 1% với tôi. Tôi đã chạy chương trình của bạn 100.000 lần với xác suất [0,1] với bước 0,01 và so sánh điều này với random.random() < desiredProbabilityviệc sử dụng tập lệnh này: gist.github.com/3656877 Chúng khớp hoàn hảo i.imgur.com/Hr8uE.png
Matt

Mặc dù, như mong đợi, random.random() < xlà nhanh hơn đáng kể.
Matt

3

Toán học 165

Không được sắp xếp hợp lý, nhưng một số có thể tìm thấy thuật toán quan tâm:

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]]]

Sử dụng

f[.53]

1

Kiểm tra

Hãy xem liệu f[.53]thực sự tạo ra giá trị 1khoảng 53% thời gian. Mỗi thử nghiệm tính% cho các mẫu 10 ^ 4.

50 bài kiểm tra như vậy được chạy và tính trung bình.

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,5288, 0,528, 0,5379, 0,5293, 0,5263, 0,539, 0,5322, 0,5195, 0,5208, 0,538, 0,5 , 0,5297, 0,5318, 0,5243, 0,5281, 0,5361, 0,5349, 0,5308, 0,5265, 0,5309, 0,5233, 0,5345, 0,5316, 0,5376, 0,5264, 0,5269, 0,5295, 0,523, 0,5294, 0,526, 0,529 }

0,529798

Biểu đồ kết quả

biểu đồ

Giải thích (cảnh báo spoiler!)

Đại diện cơ sở 2 của .53 là

.10000111101011100001010001111010111000010100011110110

Tiếp tục từ trái sang phải, mỗi lần một chữ số:

Nếu RandomInteger [] trả về 1, thì trả lời = 1,

Khác Nếu RandomInteger thứ hai [] trả về 0, sau đó trả lời = 0,

Khác Nếu RandomInteger thứ ba [] trả về 0, câu trả lời = 0,

Khác ....

Nếu, khi tất cả các chữ số đã được kiểm tra, vẫn không có câu trả lời, thì hãy trả lời = RandomInteger [].


1

Haskell, 107 ký tự:

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

Ngôn ngữ Wolfram (Mathicala) , 42 byte

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

Hãy thử trực tuyến!

Đây là một cách tiếp cận đệ quy. Ungolfed, thuật toán là:

  • Nếu xác suất đầu vào pnhỏ hơn 1/2, thì khi coinflip tăng 0, trả về 0. Nếu không, hãy lặp lại 2p; giả sử tính chính xác, xác suất tổng thể nhận được 1 là một nửa 2phoặc p.
  • Nếu xác suất đầu vào plớn hơn 1/2, thì khi coinflip tăng 1, trả về 1. Nếu không, hãy lặp lại 2p-1; giả sử tính chính xác, xác suất tổng thể nhận được 0 là một nửa 1-(2p-1)hoặc 1-p.

Để làm cho nó ngắn hơn, chúng tôi bắt đầu với coinflip ngẫu nhiên, trong một trong hai nhánh, được trả lại một nửa thời gian. Nếu coinflip không khớp với trường hợp khi chúng tôi phải trả lại, hãy thay thế bằng kết quả đệ quy trên 2pmodulo 1. (Nghĩa là khi pnhỏ hơn 1/2, thay thế 1; khi plớn hơn 1/2 , thay thế 0. Điều này tương đương với việc thay thế ⌈1-2p⌉.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.