Girdi olarak adil bir para verildiğinde, herhangi bir haksız sonuç üretin


13

Haksız bir madeni para kullanarak adil bir madeni para üretmek kolaydır, ancak bunun tersini yapmak daha zordur.

Programınız girdi olarak bir X sayısı (0 ile 1 dahil) alır. Giriş, kaynak kodun ortasındaki bir sayı olarak sabit olarak kodlanmamalıdır. Daha sonra tek bir basamak döndürmelidir: a 1, X olasılığı ve 0başka bir olasılık .

Programınızın kaynak kodunda yalnızca bir rasgele sayı üreteci biçimi kullanmasına izin verilir: int(rand(2))(veya eşdeğeri); bu, sıfır veya eşit olasılıklı bir tane döndürür. Bu işlevi kodunuza istediğiniz kadar ekleyebilir veya erişebilirsiniz. Ayrıca, kodun bir parçası olarak işlevi kendiniz sağlamanız gerekir.

Programınızın, rasgele sayı oluşturma işlevi olarak işlev görebilecek başka rasgele sayı üreten işlevler veya harici kaynaklar (saat ve tarih işlevleri gibi) kullanmasına izin verilmez. Ayrıca harici dosyalara erişemez veya işi harici programlara iletemez.

Bu kod golf, en kısa cevap kazanır.


Girdi ne biçim alır? Belirli bir boyutta bir IEEE-754 kayan nokta sayısı olduğu garanti edilirse, bu aslında oldukça kolaydır.
Peter Taylor

Yanıtlar:


4

Perl, 37 42 karakter

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

Komut satırı argümanı olarak rastgele olasılık alır. Düzgün bir rasgele sayı oluşturur $dve girişle karşılaştırır.

Daha önce, 52 karakterlik çözüm

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

1
Bu çözümü optimize etmek için 6 yıl sonra geri döndüğünüzden çok etkilendim.
Misha Lavrov

3

Python, 81 karakter

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

Biraz kapalı olabilir, ancak asla% 1'den fazla olamaz.


Bana göre% 1'den daha iyi görünüyor. Programınızı [0,1] olasılıkları için 0,01'lik bir adımla 100.000 kez çalıştırdım ve bunu random.random() < desiredProbabilityşu komut dosyasıyla karşılaştırdım: gist.github.com/3656877 Mükemmel bir şekilde eşleşiyorlar i.imgur.com/Hr8uE.png
Matt

Beklendiği gibi random.random() < x, oldukça hızlı olmasına rağmen .
Matt

3

Mathematica 165

Kolaylaştırılmamış, ancak bazıları ilgili algoritmayı bulabilir:

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

kullanım

f[.53]

1

Kontrol

Bakalım zamanın yaklaşık% 53'ünü f[.53]gerçekten üretiyor mu 1. Her test, 10 ^ 4'lük numuneler için% değerini hesaplar.

Bu tür 50 test yapılır ve ortalaması alınır.

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.5382, 0.543, 0.5336, 0.5336, 0.5330 , 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.5326, 0.5316, 0.5334, 0.5165, 0.5296, 0.5266, 0.5266, 0.5266, 0.5266, 0.5266 }

0.529798

Sonuçların histogramı

histogram

Açıklama (spoiler uyarısı!)

.53'ün temel 2 temsili

.10000111101011100001010001111010111000010100011110110

Soldan sağa doğru, her seferinde bir basamak:

RandomInteger [] 1 döndürürse, answer = 1,

Başka İkinci RandomInteger [] 0 döndürürse, answer = 0,

Başka Üçüncü RandomInteger [] 0 döndürürse, cevap = 0,

Başka....

Tüm basamaklar test edildiğinde hala bir cevap yoksa, answer = RandomInteger [].


1

Haskell, 107 karakter:

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 Dili (Mathematica) , 42 bayt

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

Çevrimiçi deneyin!

Bu özyinelemeli bir yaklaşımdır. Ungolfed, algoritma:

  • Giriş olasılığı p1 / 2'den azsa, koinflip 0 ortaya çıktığında 0 değerini döndürün. Aksi takdirde tekrar açın 2p; doğruluk varsayarsak, 1 elde etme olasılığı 2pveya ' nın yarısıdır p.
  • Giriş olasılığı p1 / 2'den büyükse, koenflip 1 geldiğinde 1 değerini geri getirin. Aksi takdirde tekrar açın 2p-1; doğruluk varsayarsak, 0 elde etme olasılığı 1-(2p-1)veya ' nın yarısıdır 1-p.

Daha kısa hale getirmek için, her iki dalda da yarı yarıya iade edilen rastgele coinflip ile başlıyoruz. Coinflip, iade etmemiz gerektiğinde durumla uyuşmuyorsa, 2pmodulo 1'de tekrarlama sonucu değiştirin . (Yani, p1 p/2'den küçük olduğunda , 1'i değiştirin; 1 /2'den büyük olduğunda , 0 değerini değiştirin ⌈1-2p⌉. Bu, değiştirmeye eşdeğerdir .)

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.