Probabilitas Semua Kombinasi Acara yang Diberikan


18

Diberikan urutan kejadian dengan probabilitas antara 0,0 dan 1,0, hasilkan dan turunkan probabilitas setiap kombinasi yang terjadi. Anda dapat menganggap bahwa urutan angka disediakan dalam bentuk apa pun yang disediakan oleh bahasa pilihan Anda.

Ini sebuah contoh; Anda dapat menganggap bahwa panjang kombinasi urutannya masuk ke dalam memori:

{ 0.55, 0.67, 0.13 }

Program harus mencetak setiap kombinasi dan probabilitas terkait dari urutan yang terjadi. A 1 harus menyatakan bahwa peristiwa dalam indeks dari urutan input terjadi dan 0 harus menyatakan bahwa peristiwa itu tidak terjadi. Output yang diinginkan di bawah ini (saya tidak peduli tentang mencetak pekerjaan, itu hanya untuk tujuan informasi dari algoritma):

[0,0,0] = (1 - 0.55) * (1-0.67) * (1-0.13) = 0.129195
[0,0,1] = (1 - 0.55) * (1-0.67) * (0.13)   = 0.019305
[0,1,0] = (1 - 0.55) * (0.67)   * (1-0.13) = 0.262305
[0,1,1] = (1 - 0.55) * (0.67)   * (0.13)   = 0.039195
[1,0,0] = (0.55)     * (1-0.67) * (1-0.13) = 0.157905
[1,0,1] = (0.55)     * (1-0.67) * (0.13)   = 0.023595
[1,1,0] = (0.55)     * (0.67)   * (1-0.13) = 0.320595
[1,1,1] = (0.55)     * (0.67)   * (0.13)   = 0.047905

Masalah ini secara tangensial terkait dengan penghitungan "produk Cartesian".

Ingat, ini adalah kode-golf, jadi kode dengan jumlah byte paling sedikit menang.


3
Selamat datang di Programming Puzzles & Code Golf, dan tantangan pertama yang menyenangkan!
Gagang Pintu

Apakah [0.129195, 0.019305, 0.262305, ..., 0.047905]cukup sebagai output atau [0,0,0], [0,0,1], ...perlu?
Laikoni

@Laikoni Outputnya baik-baik saja. Bagian output bukanlah masalah.
Mark Johnson

Bisakah output dalam urutan terbalik?
Luis Mendo

@LuisMendo Tentu, kenapa tidak.
Mark Johnson

Jawaban:


8

Haskell, 86 byte

unlines.map(\p->show(fst<$>p)++" = "++show(product$snd<$>p)).mapM(\x->[(0,1-x),(1,x)])

Contoh penggunaan:

Prelude> putStrLn $ unlines.map(\p->show(fst<$>p)++" = "++show(product$snd<$>p)).mapM(\x->[(0,1-x),(1,x)]) $ [0.55, 0.67, 0.13]
[0,0,0] = 0.12919499999999998
[0,0,1] = 1.9304999999999996e-2
[0,1,0] = 0.262305
[0,1,1] = 3.9195e-2
[1,0,0] = 0.157905
[1,0,1] = 2.3595e-2
[1,1,0] = 0.320595
[1,1,1] = 4.790500000000001e-2

Sebagian besar byte dihabiskan untuk memformat output. Jika Anda hanya tertarik pada vektor probabilitas itu hanya 29 byte:

map product.mapM(\x->[1-x,x])

Bagaimana itu bekerja:

                    mapM(\x->[(0,1-x),(1,x)])   -- for each number x in the input
                                                -- list make either the pair (0,1-x)
                                                -- or (1,x). Build a list with
                                                -- all combinations

    map(\p->                    )               -- for each such combination p
          show(fst<$>p)                         -- print the first elements
          ++" = "++                             -- then the string " = "
          show(product$snd<$>p)                 -- then the product of the second
                                                -- elements

unlines                                         -- joins with newlines

Ini rapi; Saya ingin tahu apakah akan ada cara fungsional yang benar-benar singkat untuk melakukan ini. Apakah Anda mengenal C # atau F #? Saya ingin tahu seperti apa algoritma yang sama dalam bahasa-bahasa itu karena saya sama sekali tidak terbiasa dengan sintaksis Haskell.
Mark Johnson

@ MarkJohnson: tidak, maaf saya tidak tahu C # atau F #.
nimi

5

Mathematica, 46 45 byte

(s=#;1##&@@Abs[#-s]&/@{1,0}~Tuples~Length@s)&

Mengambil daftar. Bahkan berfungsi untuk daftar kosong {}, yang hasilnya adalah{1} .

Kasus cobaan:

%[{0.55, 0.67, 0.13}]
{0.129195, 0.019305, 0.262305, 0.039195, 0.157905, 0.023595, 0.320595, 0.047905}

Penjelasan

Diberikan daftar probabilitas sdan daftar bit bdengan 0menunjukkan "tidak terjadi" dan 1menunjukkan "memang terjadi", daftar probabilitas yang akan dikalikan diberikan oleh

1 - b - s

untuk mendaftar. Jika sebaliknya 0menunjukkan "memang terjadi" dan 1"tidak terjadi", maka ini disederhanakan menjadi

b - s

jadi kami:

                      {1,0}~Tuples~Length@s   (* Generate all possible bit combinations *)
              (#-s)&/@{1,0}~Tuples~Length@s   (* Generate probabilities to be multiplied
                                                  up to sign *)
     1##&@@Abs[#-s]&/@{1,0}~Tuples~Length@s   (* Correct sign and multiply;
                                                 1##& is short for Times *)
(s=#;1##&@@Abs[#-s]&/@{1,0}~Tuples~Length@s)& (* Assign s to first argument of function,
                                                 done separately to avoid clash
                                                 with inner function *)

4

Perl, 42 40 byte

Termasuk +1 untuk -a

Berikan nomor pada STDIN:

perl -M5.010 combi.pl <<< "0.55 0.67 0.13"

output

0.129195
0.019305
0.262305
0.039195
0.157905
0.023595
0.320595
0.047905

combi.pl:

#!/usr/bin/perl -a
$"=")\\*({1-,}";say eval for<({1-,}@F)>

4

MATL , 12 11 byte

TF-|Z}&Z*!p

Input adalah vektor kolom, dengan format [0.55; 0.67; 0.13]

Cobalah online!

TF    % Push [1, 0]
-     % Subtract from implicit input (column array), with broadcast. Gives a 2-col
      % matrix where the first column is the input minus 1 and the second is the input
|     % Absolute value
Z}    % Split the matrix into its rows
&Z*   % Cartesian product of all resulting. This gives a matrix as result, with each
      % "combination" on a different row
!p    % Product of each row. Implicitly display

3

Perl, 116 byte

for(glob"{0,1}"x(@a=split/ /,<>)){@c=split//;$d=1;$d*=@c[$_]?$a[$_]:1-$a[$_]for 0..$#a;say"[".join(",",@c)."] = $d"}

Dapat dibaca:

for(glob"{0,1}"x(@a=split/ /,<>)){
    @c=split//;
    $d=1;$d*=@c[$_]?$a[$_]:1-$a[$_]for 0..$#a;
    say"[".join(",",@c)."] = $d"
}

Membuat daftar semua kemungkinan kombinasi panjang 0s dan 1s sama dengan jumlah parameter input (misalnya, untuk contoh di atas, itu akan menjadi panjang 3), kemudian menghitung setiap probabilitas.

Terima kasih kepada @Dada untuk menunjukkan kepada saya apa yang bisa dilakukan globfungsi , meskipun saya tidak 100% yakin saya mengerti caranya melakukannya.

Output sampel:

[0,0,0] = 0.129195
[0,0,1] = 0.019305
[0,1,0] = 0.262305
[0,1,1] = 0.039195
[1,0,0] = 0.157905
[1,0,1] = 0.023595
[1,1,0] = 0.320595
[1,1,1] = 0.047905

1
-abukannya (@a=split/ /,<>)...
Dada

3

R, 72 69 byte

Mengambil input dari stdin dan mengembalikan R-vektor probabilitas.

apply(abs(t(expand.grid(rep(list(1:0),length(x<-scan())))-x)),1,prod)

Sunting: Menghapus satu transpose yang tidak perlu, matriks permutasi sekarang adalah versi yang ditransposisikan dari yang di bawah ini dan probabilitas dihitung sebagai produk kolom-bijaksana daripada baris-bijaksana. Contoh output:

[1] 0.129195 0.157905 0.262305 0.320595 0.019305 0.023595 0.039195 0.047905

Perhatikan bahwa probabilitas berada dalam urutan yang berbeda karena fakta bahwa permutasi-matriks yang dihasilkan oleh expand.gridmenghasilkan yang berikut (generasi matriks ini mungkin dapat golf menggunakan paket eksternal):

1    1    1    1
2    0    1    1
3    1    0    1
4    0    0    1
5    1    1    0
6    0    1    0
7    1    0    0
8    0    0    0

Probabilitas pertama sesuai dengan hasil terbalik dari baris pertama dalam matriks di atas dan yang kedua ke baris kedua terbalik dll. Memformat output untuk melihat ini lebih jelas membuat program lebih lama (164 byte):

m=expand.grid(rep(list(1:0),length(x<-scan())))
cat(paste0("[",apply(abs(m-1),1,function(x)paste0(x,collapse=",")),"] = ",apply(abs(t(t(m)-x)),1,prod),"\n"),sep="")

yang sebaliknya menghasilkan:

[0,0,0] = 0.129195
[1,0,0] = 0.157905
[0,1,0] = 0.262305
[1,1,0] = 0.320595
[0,0,1] = 0.019305
[1,0,1] = 0.023595
[0,1,1] = 0.039195
[1,1,1] = 0.047905

Saya telah mengerjakan jawaban saya sendiri untuk ini, tetapi saya tidak dapat menemukan solusi yang rapi. Penggunaan hebat expand.grid! Saya pikir itu applydapat beroperasi pada frame data dan juga matriks, jadi kode Anda harus bekerja tanpa t(t(...)), yang akan menghemat 6 byte.
rturnbull

@urnurnbull Catatan yang ttidak terkait dengan kerangka data apa pun tetapi untuk memungkinkan pengurangan vektor probabilitas dari matriks permutasi (dengan dimensi yang berbeda). Setidaknya salah satu dari mereka diperlukan karena cara R menangani operasi vektor ini tetapi saya mungkin bisa menghapus transpos luar dan menerapkan produk di atas kolom sebagai gantinya. Akan diperbarui besok
Billywob


2

J, 14 byte

-.([:,*/)/@,.]

Pemakaian

   f =: -.([:,*/)/@,.]
   f 0.55 0.67 0.13
0.129195 0.019305 0.262305 0.039195 0.157905 0.023595 0.320595 0.047905

Penjelasan

-.([:,*/)/@,.]  Input: array P
-.              Complement (1-x) for each x in P
             ]  Identity, get P
           ,.   Interleave to make pairs [(1-x), x]
  (     )/@     Reduce from right-to-left by
      */          Forming the multiplication table
   [:,            Flattening the result

Bisakah Anda membuat |*//0.55 0.67 0.13-/0 1kereta api?
Adám

2

Pyth, 10 byte

*MaVLQ^U2l

Cobalah online: Demonstrasi

Penjelasan:

*MaVLQ^U2lQ   implicit Q at the end (Q = input list)
      ^U2lQ   repeated Cartesian product of [0, 1] with itself length(Q)-times
              this gives all combinations of 0s and 1s
  aVLQ        absolute difference between these 0-1-vectors with Q
*M            fold the vectors by multiplication

1

C, 110 byte

i,k;f(float* a,int n){for(k=0;k<1<<n;++k){float p=1;for(i=0;i<n;++i)p*=k&(1<<i)?a[i]:1-a[i];printf("%f,",p);}}

Tidak Disatukan:

i,k;f(float* a,int n){ 
 for(k=0; k<1<<n; ++k){
  float p=1;
  for (i=0; i<n; ++i)
   p*=k&(1<<i)?a[i]:1-a[i];
  printf("%f,",p);
 }
}

Bekerja hingga 32 item, + 5 + 1 byte untuk 64 item (menyatakan long k;dan menambahkan Lloop pertama sehingga k<1L<<N).


1
Untuk> 32 item, apakah C memerlukan literal "L" pada *1*<<natau hanya C ++ saja?
Mark Johnson

@ MarkJohnson ya saya kira itu akan membutuhkan.
Karl Napf

1

05AB1E , 8 byte

<Äæ¹æR+P

Cobalah online!

 <Äæ¹æR+P  # Main link (Input is [.1,.2])
 ###########
 <Ä        # Invert input, take the abs value.
           # Stack is [.9,.8]
   æ¹æ     # Powerset of both inverted and original arrays.
           # Stack is [[],[.1],[.2],[.1,.2]],[[],[.9],[.8],[.9,.8]]
      R+   # Reverse original array, add arrays together.
           # Stack is [.9,.8],[.1,.8],[.2,.9],[.1,.2]
        P  # For each sub array, push product.
           # Final Result: [0.02, 0.18, 0.08, 0.72]
           # E.G.          [  11,   10,   01,   00]

1

JavaScript (Firefox 30-57), 57 byte

f=([p,...a])=>1/p?[for(q of[1-p,p])for(b of f(a))q*b]:[1]

Mengembalikan array dari semua probabilitas. Jika Anda ingin array acara juga, maka untuk 86 byte:

f=([p,...a])=>1/p?[for(e of'01')for(b of f(a))[[+e,...b[0]],(+e?p:1-p)*b[1]]]:[[[],1]]

Jika Anda diizinkan acara sebagai string, maka hanya 80 byte:

f=([p,...a])=>1/p?[for(e of'01')for(b of f(a))[e+b[0],(+e?p:1-p)*b[1]]]:[['',1]]

Kurangi dua byte untuk 1/setiap solusi jika probabilitasnya tidak akan pernah menjadi nol.


Bagaimana Anda menjalankan ini di <script></script>blok? Saya mendapatkan masalah dengan "untuk" pertama yang tidak terduga?
Mark Johnson

@ MarkJohnson Selama Anda menggunakan Firefox 30 atau lebih baru, seharusnya hanya berfungsi.
Neil

0

Perl 6, 24 19 byte dari Latin-1

{[*] 1 «-»@_ «|»@_}

Kode lama:

{[*] map {1-$^a|$^a},@_}

Ini sebuah fungsi. Gunakan seperti ini:

{[*] 1 «-»@_ «|»@_}(0.55, 0.67, 0.13)

mendapatkan:

any(any(any(0.129195, 0.019305), any(0.262305, 0.039195)), any(any(0.157905, 0.023595), any(0.320595, 0.047905)))

Penjelasan kode yang lebih lama:

[*]          multiply together all array elements
map          but first transform each element via
{1-$^a|$^a}  considering both 1 minus the value and the value
,@_          of the function input

Kode yang lebih baru pada dasarnya sama, hanya menggunakan sintaks terser:

[*]          multiply together all array elements
1 «-»@_      of the array formed by subtracting the argument from 1
«|»@_        pointwise considering both that and the original array

Peta menghasilkan array yang penuh dengan anykonstruksi, yang berkembang biak menjadi anykonstruksi yang lebih besar , menyelesaikan masalah dengan rapi bahkan tanpa perlu loop.

Bukan bahasa terpendek untuk program ini, tetapi ini adalah terjemahan langsung dari masalahnya.


0

Dyalog APL , 10 byte

Solusi Baru

Asal indeks independen. Fungsi anonim. Mengambil daftar probabilitas sebagai argumen.

∘.×/⊢,¨1-⊢

∘.×/ Pengurangan produk Cartesian berakhir

nilai argumen

masing-masing dipasangkan dengan

1-⊢ nilai argumen komplemen (lit. satu dikurangi nilai argumen)

TryAPL online!


Solusi Lama

Membutuhkan ⎕IO←0yang default pada banyak sistem. Anjuran untuk daftar probabilitas.

|⎕∘.×.-⊂⍳2

Penjelasan

| nilai absolut dari

input, ɑ = [ ɑ ₁  ɑ ₂  ɑ ₃]

∘.×.-tensor dalam yang dimodifikasi dikalikan, ( ɑ ₁ - b ₁) ⊗ ( ɑ ₂ - b ₂) ⊗ ( ɑ ₃ - b ₃), dengan

⊂⍳2daftar terlampir b = [[0 1]]

Definisi matematika

Seperti b tertutup, itu skalar, dan karena itu diperluas ke panjang ɑ , yaitu 3, sehingga seluruh ekspresi adalah

A = │ ( ɑ ₁ - b ) ⊗ ( ɑ ₂ - b ) ⊗ ( ɑ ₃ - b ) │ =

 │ ( ɑ ₁ - [0,1]) ⊗ ( ɑ ₂ - [0,1]) ⊗ ( ɑ ₃ - [0,1]) │ =

 │ [ ɑ ₁, ɑ ₁ - 1] ⊗ [ ɑ ₂ , ɑ ₂ - 1] ⊗ [ ₁ ɑ ₂ ( ɑ ₃-1)  ⎤ ⎤ ⎥ ⎢ ⎢ ⎢ ⎣  ɑ ₁ ( ɑ ₂-1) ɑ ₃, ɑ ₃ - 1] │ =

 ⎢  ⎡ ⎡ ɑ ɑ ɑ ɑ ₃   ɑ
ɑ ₃  ⎦ ⎣ ɑ ₁) ɑ ₂-1) ( ɑ ₃-1)
 ⎦ ⎥ ⎥ ⎢ ⎢ ⎡ ( ɑ ₁-1) ɑ ɑ ₃⎤ ⎡( ɑ ₁-1) ɑ ₂ ( ɑ ₃-1) ⎥ ⎥ ⎤
 ⎢ ⎣ ⎣ ( ɑ ₁-1) ( ɑ ₂-1) ₂-1) ɑ ₃⎦ ⎣ ( ɑ ₁- 1) ( ɑ ₂-1) ( ɑ ₃-1) ⎦ ⎦ ⎥

TryAPL online!

Catatan (berlaku untuk solusi lama dan baru)

Program dan rumus berfungsi untuk sejumlah ( n ) variabel, dan mengembalikan array n- dimensi dengan panjang 2 di setiap dimensi. Dengan tiga variabel, probabilitas hasil
P spesifik ( p , q , r ) = A p , q , r
yang dapat dengan mudah dipilih dari array dengan (⊃A)[p;q;r]diekstraksi denganp q r⌷⊃A

Misalnya 1 1 0⌷⊃|0.55 0.67 0.13∘.×.-⊂⍳2memberi P (55%, 67%, ¬13%) = 1,9305%


0

PHP, 105 97 94 93 87 byte

for(;$i<2**$c=count($a=$argv)-$p=1;$i+=print-abs($p))for(;$c;)$p*=$a[$c--]-!($i>>$c&1);

Jalankan seperti ini:

php -r 'for(;$i<2**$c=count($a=$argv)-$p=1;$i+=print-abs($p))for(;$c;)$p*=$a[$c--]-!($i>>$c&1);' -- .55 .67 .13 2>/dev/null;echo
> -0.129195-0.157905-0.262305-0.320595-0.019305-0.023595-0.039195-0.047905

Perhatikan bahwa outputnya sedikit endian:

[0,0,0]
[1,0,0]
[0,1,0]
[1,1,0]
[0,0,1]
[1,0,1]
[0,1,1]
[1,1,1]

Penjelasan

for(
  ;
  $i<2**$c=                 # Iterate over possible combinations: 2^c,
    count($a=$argv)-$p=1;   #   where c is input length -p (set p to 1)
  $i+=print-abs($p)         # Increment i and print product after each
)                           #   iteration, dash separated
  for(
     ;
     $c;                    # Iterate over input ($c..0)
  )
    $p*=                    # Multiply the product by difference between:
      $a[$c--]-             # - The $c-th item of the input.
      !($i>>$c&1);          # - The $c-th bit of `$i`, negated (1 or 0)

Tweaks

  • Disimpan 8 byte dengan menggunakan logika biner untuk mendapatkan bit alih-alih mengkonversi ke string
  • Menyimpan byte dengan menggabungkan pengaturan ulang $pke 1 dengan perhitungan$c
  • Menyimpan byte dengan menambahkan hasil cetak (1) ke $i alih-alih bertambah
  • Menyimpan byte dengan menggunakan garis bawah sebagai pembatas output
  • Menyimpan byte dengan menggunakan tanda minus sebagai pembatas (tidak ada peluang negatif).
  • Disimpan 6 byte dengan menggunakan $cbukan$$i

0

C ++ 17, 137 131 129 byte

Menyimpan 6 byte dengan mendeklarasikan #define A auto, pertama kali makro sekecil itu menyimpan apa pun. -2 byte untuk menggunakan #importdan menghapus spasi sebelumnya<

#import<iostream>
#define A auto
A g(A r){std::cout<<r<<",";}A g(A r,A x,A...p){g(x*r,p...);g(r-x*r,p...);}A f(A...p){g(1,p...);}

Memunculkan semua kemungkinan kombinasi.

Tidak Disatukan:

//base case to print the result
int g(auto r){std::cout << r << ",";}

//extract item from parameter pack
int g(auto r, auto x, auto... p) {
 g(x*r,p...);    //multiply with temp result and call with tail
 g(r-x*r,p...);  //same as above for (1-x)
}

//start of recursion, setting temp result to 1
int f(auto...p){g(1,p...);}

Pemakaian:

f(0.55, 0.67, 0.13);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.