Bir olasılığı tam olarak hesaplayın


9

Bu görev, bir olasılığı tam olarak hesaplamak için kod yazmakla ilgilidir. Çıktı, en düşük biçimde kesir olarak yazılan kesin bir olasılık olmalıdır. Asla çıktı almamalı, daha 4/8doğrusu 1/2.

Bazı pozitif tamsayılar için n, 1s ve -1s uzunlukta eşit rastgele bir dize düşünün ve A olarak nadlandırın. Şimdi Ailk değerine bitiştirin . Yani A[1] = A[n+1]1'den indeksleme eğer Aşimdi uzunluğa sahiptir n+1. Şimdi n, ilk ndeğerleri her biri 1 / 4,1 / 2, 1/4 olasılıkla -1, 0 veya 1 olan ikinci bir rastgele uzunluk dizesini düşünün ve B olarak adlandırın.

Örneğin, düşünün n=3. İçin olası değerler Ave Bolabilir A = [-1,1,1,-1]ve B=[0,1,-1]. Bu durumda iki iç ürün 0ve şeklindedir 2.

Şimdi iç ürünü incelemek A[1,...,n]ve Bve iç ürünü A[2,...,n+1]ve B.

Kodunuz, her iki iç ürünün de sıfır olma olasılığını vermelidir.

Çünkü n=1bu olasılık açıktır 1/2.

Kodda nasıl nbelirtilmiş olduğunu umursamıyorum ama çok basit ve nasıl değiştirileceği açık olmalıdır.

Diller ve kütüphaneler

İstediğiniz dil ve kütüphaneleri kullanabilirsiniz. Kodunuzu çalıştırmak istiyorum, bu yüzden mümkünse linux kodunuzu çalıştırmak / derlemek için lütfen tam bir açıklama ekleyin.


2
İlk birkaçının test senaryoları nyardımcı olacaktır. Ayrıca A, B ve iki iç ürünün açık bir örneği de yardımcı olabilir.
Martin Ender

Tamsayıyı kodlamayı seçersek, n=4sıfır, iki veya üç bayt olarak sayılır mı? Çıkış olmak zorunda mı aynen a/b ya olur [a b], örneğin izin verilebilir?
Dennis

@Dennis Kesin olmalı. Eğer tamsayıyı kodlarsanız değiştirmek için tek bir yerde değiştirmek zorunda kalacak mıyım n? Aksi takdirde, buna izin verilmediğini düşünüyorum.

Evet, programım kartezyen gücü hesaplamak için tamsayıyı yalnızca bir kez kullanır. Diğer her şey sonuçta elde edilen diziden türetilir.
Dennis

Yanıtlar:


7

Pyth, 48 47 46 44 bayt

K,smlf!|Fms*Vd.>Tk2^,1_1Q^+0tM3Q^8Qj\//RiFKK

Çevrimiçi deneyin: Gösteri

Çevrimiçi sürüm muhtemelen hesaplamaz n=6. Dizüstü bilgisayarımda (çevrimdışı sürüm) yaklaşık 45 saniye sürer.

Kaba kuvvet yaklaşımı.

Açıklama:

smlf!|Fms*Vd.>Tk2^,1_1Q^+0tM3Q   implicit: Q = input number
                          tM3    the list [-1, 0, 1]
                        +0       add zero, results in [0, -1, 0, 1]
                       ^     Q   all possible lists of length Q using these elements
 m                               map each list d (B in Lembik's notation) to:
                  ,1_1              the list [1, -1]
                 ^    Q             all possible lists of length Q
   f                                filter for lists T (A in Lembik's notation),
                                    which satisfy:
       m        2                      map each k in [0, 1] to:
        s*Vd.>Tk                          scalar-product d*(shifted T by k)
    !|F                                not or (True if both scalar-products are 0)      
  l                                 determine the length                
s                                add all possibilities at the end

K,...^8QQj\//RiFKK   
 ,...^8Q             the list [result of above, 8^Q]
K                    store it in K
              iFK    determine the gcd of the numbers in K
            /R   K   divide the numbers in K by the gcd
         j\/         join the two numbers by "/" and print

dang,
gcd'yi

+0r1_2daha kısadır /R2r2_2.
isaacg

Ben adil sayılır 89/512 sürümü olması gerektiğini düşünüyorum.

@Lembik Ok Değiştirdi.
Jakube

İtiraf etmeliyim ki, bu hiç gerçekleşmedi, bu 47 karakterle yapılabilir!

8

Mathematica 159 100 87 86 85 bayt

n=3;1-Mean@Sign[##&@@Norm/@({1,0,0,-1}~t~n.Partition[#,2,1,1])&/@{1,-1}~(t=Tuples)~n]

Değiştirmek için nsadece değişken tanımını başlangıçta değiştirin.

Kaba kuvvet olduğu için oldukça yavaş, ancak ilk sekiz sonuç:

n   P(n)
1   1/2
2   3/8
3   7/32
4   89/512
5   269/2048
6   903/8192
7   3035/32768
8   169801/2097152

Sonuncusu zaten 231 saniye sürdü ve çalışma süresi çok üstel.

açıklama

Dediğim gibi kaba kuvvet. Esasen, sadece mümkün olan her şeyi numaralandırıyorum Ave Bolası her çift için iki nokta ürününü hesaplıyorum ve sonra elde edilen çiftlerin bir kısmını buluyorum {0, 0}. Mathematica'nın kombinatorik ve lineer cebir fonksiyonları bunu golf oynamakta oldukça yardımcı oldu:

{1,-1}~(t=Tuples)~n

Bu , 1veya -1mümkün olan tüm n-tuplleri üretir A. İçin n = 3olmasıdır:

{{1, 1, 1}, 
 {1, 1, -1}, 
 {1, -1, 1}, 
 {1, -1, -1}, 
 {-1, 1, 1}, 
 {-1, 1, -1}, 
 {-1, -1, 1}, 
 {-1, -1, -1}}

Hesaplamak Biçin neredeyse aynı şeyi yapıyoruz:

{1,0,0,-1}~t~n

Tekrarlayarak 0, 0içerdiği her bir demet için her bir tetiği çoğaltırız ve böylece veya 0iki katına çıkarırız . Yine örnek olarak kullanmak :1-1n = 3

{{-1, -1, -1},
 {-1, -1, 0}, {-1, -1, 0},
 {-1, -1, 1},
 {-1, 0, -1}, {-1, 0, -1},
 {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0},
 {-1, 0, 1}, {-1, 0, 1},
 {-1, 1, -1},
 {-1, 1, 0}, {-1, 1, 0},
 {-1, 1, 1},
 {0, -1, -1}, {0, -1, -1},
 {0, -1, 0}, {0, -1, 0}, {0, -1, 0}, {0, -1, 0},
 {0, -1, 1}, {0, -1, 1},
 {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1},
 {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
 {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
 {0, 1, -1}, {0, 1, -1},
 {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
 {0, 1, 1}, {0, 1, 1},
 {1, -1, -1},
 {1, -1, 0}, {1, -1, 0},
 {1, -1, 1},
 {1, 0, -1}, {1, 0, -1},
 {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
 {1, 0, 1}, {1, 0, 1},
 {1, 1, -1},
 {1, 1, 0}, {1, 1, 0},
 {1, 1, 1}}

Şimdi, mümkün Aolan her biri için, ve Bile mümkün olan her birinin nokta ürününü istiyoruz . Mevcut eğer Örneğin olduğunu , her iki ile nokta ürün istiyorum ve birlikte . Hepsi bizim zaten bir matrisin satırları olduğundan, iki alt listeyi başka bir matrisin sütunları olarak istiyoruz , böylece aralarında basit bir nokta ürünü hesaplayabiliriz. Ancak, transpozasyon , sadece 2 elementli döngüsel alt listelerin bir listesini verir . Bunun yaptığı şey:A[1 .. n]A[2 .. n+1]A{1, 1, -1}{1, 1, -1}{1, -1, 1}BA{{1, 1, -1}, {1, -1, 1}}{{1, 1}, {1, -1}, {-1, 1}}A

Partition[#,2,1,1]

Bu yüzden bunu hesaplıyoruz ve nokta ürünümüzü listemizle alıyoruz B. Artık iç içe bir liste aldığımızdan (her olası Abir ayrı vektör verdiğinden), bunları düzleştiriyoruz ##&@@.

Bir çift olup olmadığını öğrenmek için {x, y}ise {0, 0}biz hesaplamak Sign[Norm[{x,y}]] nerede Normverir √(x²+y²). Bu 0veya verir 1.

Son olarak, şimdi sadece s ve s 1listesindeki s fraksiyonlarını bilmek istediğimizden tek ihtiyacımız listenin aritmetik ortalamasıdır. Bununla birlikte, bu, hem en az bir nokta ürününün sıfır olmayan olma olasılığını verir, bu nedenle istenen sonucu elde etmek için onu çıkarırız .011


6

Pyth - 65 55 bayt

Bir bayt maliyetinde kesir azaltma hatası düzeltildi.

Kaba kuvvet yaklaşımı kullanır ve çok golf edilebilir, ancak orada bir şeyler almak istedim. Çok yavaş

*F-KP/Jmms*Vked,thdPhd*makhk^,1_1Q^[1ZZ_1)Q,ZZ2/lJ^2/K2

Hem üretmek için Kartezyen ürünlerini kullanan Ave Byaparak değişken olasılıkları yapıyor, 0kaynak listesinde iki kez görünüp, daha sonra iç o ürünü sıfıra olanları sayar. İç ürün Vectorization syntaktik şeker ile kolaylaştırılmıştır . Kesiri basitleştirmek başlangıçta beni korkutuyordu, ama Pkırağı Çarpanlara Ayırma fonksiyonu ve sadece 2 güçle azaltmamız gerektiğinin fark edilmesi oldukça kolaydı .

Burada çevrimiçi deneyin .


Nasıl değiştiririm n?

@Lembik Pyth programı, ikinci metin kutusunda (çevrimiçi derleyici kullanıyorsanız) belirtilen bir kullanıcı girişi ister.
Jakube

@Jakube Ah teşekkürler! Ve aslında çok çalışıyor gibi görünüyor :)

6

CJam, 58 57 54 51 46 bayt

WX]m*Zm*_{~.+2,@fm<\f.*::+0-!},,__~)&:T/'/@,T/

Çalıştırmak için WX]ve arasında istenen tamsayıyı ekleyin m*.

@ Jimmy23013 için biraz büyü ve 5 bayt golf için teşekkürler!

CJam yorumlayıcısında çevrimiçi deneyin .

Fikir

Bu cevabın çoğu kısmı basittir, ancak iki düzgün numara kullanır:

  • Bunun yerine her vektörleri eşleştirme {-1, 1} , n her vektörlerle {-1, 0, 1} , n , istenen olasılıkları, bu olarak sayar vektörlerin üçlü sayısını dikkate {-1, 1} , n bu tatmin belirli bir durum.

    Üçlünün son iki vektörünü eklersek, sonuç {-2, 0, 2} n vektörü olur .

    Yana (-1) + 1 = 0 = 1 + (1) , 0 s iki kat daha fazla ortaya gibi -2 S ve 2 s.

    Her bileşenin 2'ye bölünmesi , istenen olasılıklarla bir {-1, 0, 1} n vektörü verecektir .

    Sadece skaler ürün 0 olup olmadığıyla ilgilendiğimiz için bölünmeyi 2 atlayabiliriz .

  • Sorunun durumunu ve toplam üçüz sayısını karşılayan tüm üçüzleri saydıktan sonra, ortaya çıkan kesri azaltmamız gerekir.

    Her iki sayının GCD'sini hesaplamak yerine, payda her zaman 2 gücü olacağından, her iki sayıyı da payı bölen 2'nin en yüksek gücüne bölmek yeterlidir.

    Böler o 2'nin en yüksek güç elde etmek için x , biz ikilik VE ait alabilir x ve ~ x + 1 .

    ~ x , x'in tüm bitlerini tersine çevirir , böylece arkadaki tüm 0 sn 1 sn olur. Ekleyerek 1 için ~ x , o 1 ler geri dönecek 0 s ve son 1 yılında ~ x + 1 son maç olacak 1 içinde x .

    Diğer tüm bitler ya her ikisi de 0 lojik AND son oluşan tamsayı döndürür, böylece, farklı bir 1 arasında x ve 0 takip s. Bu, x'i bölen 2'nin en yüksek gücüdür .

kod

WX]    e# Push the array [-1 1].
       e# Insert N here.
m*     e# Cartesian product: Push the array of all vectors of {-1,1}^N.
Zm*    e# Cartesian product: Push the array of all triplets of these vectors.
_      e# Copy the array.
{      e# Filter; for each triplet of vectors U, V and W in {-1,1}^N:
  ~    e#   Dump U, V and W on the stack.
  .+   e#   Compute X := V + W, a vector of {-2,0,2}^N, where each component is
       e#   zero with probability 1/2.
  2,@  e#   Push [0 1]. Rotate U on top of it.
  fm<  e#   Push [U U'], where U' is U rotated one dimension to the left.
  \f.* e#   Push [U*X and U'*X], where * denotes the vectorized product.
  ::+  e#   Add the components of both products.
  0-   e#   Remove zeroes.
       e#   Push the logical NOT of the array.
},     e#   If the array was empty, keep the triplet.
,      e# Push X, the length of the filtered array.
__~)&  e# Push X & ~X + 1.
:T     e# Save the result in T and divide X by T.
'/     e# Push a slash.
@,T/   e# Dividet he length of the unfiltered array by T.

WX]m*Zm*_{~.+2,@fm<\f.*::+0-!},,__W*&:T/'/@,T/.
jimmy23013

@ jimmy23013: Bu biraz etkileyici bir sihir. Teşekkürler!
Dennis
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.