Çoklu Zar Rulolarının Frekans Dağılımı


23

İki pozitif tamsayı verilmiş ave b, bir btaraflı kalıp haddeleme ve dağılım asonuçlarının sıklık dağılımını gösterir .

Bir zar dağılımı, her olası zar zar sırası dizisi bir kez meydana gelirse, her olası toplamın sıklığını listeler. Dolayısıyla, frekanslar, toplamı eşit olan tam sayılardır b**a.

kurallar

  • Frekanslar, karşılık gelen toplamın artan sırasına göre listelenmelidir.
  • Frekansları karşılık gelen toplamlarla etiketlemeye izin verilir, ancak gerekli değildir (toplamlar istenen siparişten alınabildiği için).
  • Çıktının, diliniz için temsil edilebilir tam sayı aralığını aştığı girişleri ele almanız gerekmez.
  • Önde gelen veya sondaki sıfırlara izin verilmez. Çıktıda yalnızca pozitif frekanslar görünmelidir.

Test Kılıfları

Biçim: a b: output

1 6: [1, 1, 1, 1, 1, 1]
2 6: [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
3 6: [1, 3, 6, 10, 15, 21, 25, 27, 27, 25, 21, 15, 10, 6, 3, 1]
5 2: [1, 5, 10, 10, 5, 1]
6 4: [1, 6, 21, 56, 120, 216, 336, 456, 546, 580, 546, 456, 336, 216, 120, 56, 21, 6, 1]
10 10: [1, 10, 55, 220, 715, 2002, 5005, 11440, 24310, 48620, 92368, 167860, 293380, 495220, 810040, 1287484, 1992925, 3010150, 4443725, 6420700, 9091270, 12628000, 17223250, 23084500, 30427375, 39466306, 50402935, 63412580, 78629320, 96130540, 115921972, 137924380, 161963065, 187761310, 214938745, 243015388, 271421810, 299515480, 326602870, 351966340, 374894389, 394713550, 410820025, 422709100, 430000450, 432457640, 430000450, 422709100, 410820025, 394713550, 374894389, 351966340, 326602870, 299515480, 271421810, 243015388, 214938745, 187761310, 161963065, 137924380, 115921972, 96130540, 78629320, 63412580, 50402935, 39466306, 30427375, 23084500, 17223250, 12628000, 9091270, 6420700, 4443725, 3010150, 1992925, 1287484, 810040, 495220, 293380, 167860, 92368, 48620, 24310, 11440, 5005, 2002, 715, 220, 55, 10, 1]
5 50: [1, 5, 15, 35, 70, 126, 210, 330, 495, 715, 1001, 1365, 1820, 2380, 3060, 3876, 4845, 5985, 7315, 8855, 10626, 12650, 14950, 17550, 20475, 23751, 27405, 31465, 35960, 40920, 46376, 52360, 58905, 66045, 73815, 82251, 91390, 101270, 111930, 123410, 135751, 148995, 163185, 178365, 194580, 211876, 230300, 249900, 270725, 292825, 316246, 341030, 367215, 394835, 423920, 454496, 486585, 520205, 555370, 592090, 630371, 670215, 711620, 754580, 799085, 845121, 892670, 941710, 992215, 1044155, 1097496, 1152200, 1208225, 1265525, 1324050, 1383746, 1444555, 1506415, 1569260, 1633020, 1697621, 1762985, 1829030, 1895670, 1962815, 2030371, 2098240, 2166320, 2234505, 2302685, 2370746, 2438570, 2506035, 2573015, 2639380, 2704996, 2769725, 2833425, 2895950, 2957150, 3016881, 3075005, 3131390, 3185910, 3238445, 3288881, 3337110, 3383030, 3426545, 3467565, 3506006, 3541790, 3574845, 3605105, 3632510, 3657006, 3678545, 3697085, 3712590, 3725030, 3734381, 3740625, 3743750, 3743750, 3740625, 3734381, 3725030, 3712590, 3697085, 3678545, 3657006, 3632510, 3605105, 3574845, 3541790, 3506006, 3467565, 3426545, 3383030, 3337110, 3288881, 3238445, 3185910, 3131390, 3075005, 3016881, 2957150, 2895950, 2833425, 2769725, 2704996, 2639380, 2573015, 2506035, 2438570, 2370746, 2302685, 2234505, 2166320, 2098240, 2030371, 1962815, 1895670, 1829030, 1762985, 1697621, 1633020, 1569260, 1506415, 1444555, 1383746, 1324050, 1265525, 1208225, 1152200, 1097496, 1044155, 992215, 941710, 892670, 845121, 799085, 754580, 711620, 670215, 630371, 592090, 555370, 520205, 486585, 454496, 423920, 394835, 367215, 341030, 316246, 292825, 270725, 249900, 230300, 211876, 194580, 178365, 163185, 148995, 135751, 123410, 111930, 101270, 91390, 82251, 73815, 66045, 58905, 52360, 46376, 40920, 35960, 31465, 27405, 23751, 20475, 17550, 14950, 12650, 10626, 8855, 7315, 5985, 4845, 3876, 3060, 2380, 1820, 1365, 1001, 715, 495, 330, 210, 126, 70, 35, 15, 5, 1]

Bunun ben az 2 olduğunu varsayabilir miyiz ? (Ya da değilse, 1 taraflı kalıbın toplamları için frekans listesi neye
benzemelidir

Önde gelen veya sondaki sıfırları alabilir miyiz?
xnor

Yanıtlar:


9

Oktav , 38 bayt

@(a,b)round(ifft(fft((a:a*b<a+b)).^a))

Çevrimiçi deneyin!

açıklama

Bağımsız rastgele değişkenler eklemek, olasılık kütle işlevlerini (PMF) sarsmaya veya karakteristik işlevlerini (CF) çarpmaya karşılık gelir. Böylece, abağımsız, aynı şekilde dağıtılmış değişkenlerin toplamının toplam değeri , gücüne yükseltilmiş tek bir değişken tarafından verilir a.

CF, esas olarak PMF'nin Fourier dönüşümüdür ve bu nedenle bir FFT aracılığıyla hesaplanabilir. Tek bir PMF btaraflı kalıp üzerinde üniforma 1, 2, ..., b. Ancak, iki değişiklik gereklidir:

  • 1gerçek olasılık değerleri yerine ( 1/b) kullanılır. Bu şekilde sonuç normalleşmeyecek ve gereken tam sayıları içerecektir.
  • FFT çıktısının uygun boyuta ( a*b-a+1) sahip olması ve FFT tarafından üstlenilen örtük periyodik davranışların sonuçları etkilememesi için sıfırlarla doldurmaya ihtiyaç vardır .

Toplamın karakteristik işlevi elde edildikten sonra, nihai sonucu hesaplamak için ters bir FFT kullanılır ve kayan nokta yanlışlıklarını düzeltmek için yuvarlama uygulanır.

Örnek

Girişlerini düşünün a=2, b=6. Kod , sıfır boyutunda olanlarla a:a*b<a+bbir vektör oluşturur :b=6a*b-a+1

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

Sonra fft(...)verir

[36, -11.8-3.48i, 0.228+0.147i, -0.949-1.09i, 0.147+0.321i, -0.083-0.577i, -0.083+0.577i, 0.147-0.321i, -0.949+1.09i, 0.228-0.147i, -11.8+3.48i]

Biri buradaki sinc fonksiyonunu hemen hemen tanıyabilir (bir dikdörtgen palsın Fourier dönüşümü).

(...).^aher girişi yükseltir ave ardından ifft(...)FFT’yi ters çevirir.

[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]

Her ne kadar bu durumdaki sonuçlar tam sayı olsa da, genel olarak sırasına göre göreceli hatalar olabilir 1e-16, bu yüzden buna round(...)ihtiyaç vardır.


1
Gerçekten çok etkilendim!
rahnema1

@ rahnema1 Kazanmak için sinyal işleme!
Luis Mendo

8

Mathematica, 29 bayt

Tally[Tr/@Range@#2~Tuples~#]&

Sadece mümkün olan tüm zar rulolarını üretir, toplamlarını alır, sonra sayar. Her frekans değeri ile etiketlenmiş olarak gelir.

Mathematica, 38 bayt

CoefficientList[((x^#2-1)/(x-1))^#,x]&

(1+x+x^2+...+x^(a-1))^bKatsayılarını genişletir ve alır x. Çünkü 1+x+x^2+...+x^(a-1)tek bir kalıp rulosunun üretme işlevi ve ürünler konvolüsyonlara karşılık gelir - zar değerleri ekleyerek - sonuç frekans dağılımını verir.


6

Haskell , 90 79 77 75 bayt

Kartezyen ürün numarası için Lynn'e teşekkür ederiz . Funky Computer Man'in birçok Haskell numarası sayesinde -11 bayt, Laikoni sayesinde isimlerden -2 bayt, -2 bayt. Golf önerileri açıktır! Çevrimiçi deneyin!

import Data.List
g x=[1..x]
a!b=map length$group$sort$map sum$mapM g$b<$g a

Ungolfed

import Data.List
rangeX x = [1..x]
-- sums of all the rolls of b a-sided dice
diceRolls a b = [sum y | y <- mapM rangeX $ fmap (const b) [1..a]]
-- our dice distribution
distrib a b = [length x | x <- group(sort(diceRolls a b))]

2 bayt kaydetmek $yerine kullanın (). TIO
Buğday Sihirbazı




(map length$)=(length<$>)iki bayt için
Michael Klein

4

Pyth - 10 bayt

Sadece kartezyen ürünü alarak tüm olası zar kombinasyonları alır [1, b], a, saat toplayarak ve her toplamı grubunun uzunluğunu alma.

lM.gksM^SE

Test Takımı .


4

05AB1E , 8 bayt

LIãO{γ€g

Çevrimiçi deneyin!

Nasıl?

LIãO {γ € g - Tam program.

L - Aralık [1 ... giriş # 1]
 I - Giriş # 2.
  ã - Kartezyen Gücü.
   O - Toplamı ile eşleyin.
    { - Çeşit.
     Group - Grup ardışık eşit elemanları.
      € g - Her birinin uzunluğunu al


4

R , 52 bayt

function(a,b)Re(fft(fft(a:(a*b)<a+b)^a,T)/(a*b-a+1))

Çevrimiçi deneyin!

@Luis Mendo'nun Octave çözümünün limanı , fft(z, inverse=T)ne yazık ki normalize edilmemiş ters FFT'yi döndürür, bu yüzden uzunlukla bölmek zorundayız ve bir complexvektör döndürür , bu yüzden sadece gerçek kısmı alırız.


iyi oynadı - dünkü cmdscalerakam için geri ödeme :-)
flodel

@flodel hah! Aslında sana bunun için bir ödül vereceğim :)
Giuseppe

Şaka yapmadın! Çok cömertsin! Cevaplarını görmekten (ve öğrenmekten) hoşlanıyorum, hemen geri ödeyeceğim!
flodel

3

SageMath, 40 bayt

lambda a,b:reduce(convolution,[[1]*b]*a)

Çevrimiçi deneyin

convolutionİki listenin ayrık evrişimini hesaplar. reduceteneke ne diyor yok. s, frekans dağılımının [1]*bbir listesidir . s'nin iç içe geçmiş kopyalarını yapar .b 11db[[1]*b]*aab 1


Python 2 + NumPy , 56 bayt

lambda a,b:reduce(numpy.convolve,[[1]*b]*a)
import numpy

Çevrimiçi deneyin!

Esasen eşdeğer oldukları için bu çözümü yukarıdaki ile ekledim. Bu işlevin bir Python listesi değil bir NumPy dizisi döndürdüğünü unutmayın;print .

numpy.ones((a,b))NumPy ile kullanmak için bir dizi yapmanın "doğru" yoludur ve bu nedenle bunun yerine kullanılabilir [[1]*b]*a, ancak ne yazık ki daha uzun sürer.


3

Jöle , 5 bayt

ṗS€ĠẈ

Çevrimiçi deneyin!

Bunun argümanları ters sırada aldığını unutmayın.

Nasıl?

ṗS € ĠL € - Tam program (dyadic) | Örnek: 6, 2

Cart - Kartezyen Gücü (üstü kapalı) | [[1, 1], [1, 2], ..., [6, 6]]
 S € - Her biri topla | [2, 3, 4, ..., 12]
   Ġ - Değerlere göre grup göstergeleri | [[1], [2,7], [3, 8, 13], ..., [36]]
    L € - Her grubun uzunluğu | [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]

Alternatif çözümler:

ṗZSĠL€
ṗZSµLƙ
ṗS€µLƙ






1

JavaScript (ES6), 94 bayt

f=(n,m,a=[1],b=[])=>n?[...Array(m)].map((_,i)=>a.map((e,j)=>b[j+=i]=(b[j]|0)+e))&&f(n-1,m,b):a
<div oninput=o.textContent=f(+n.value,+m.value).join`\n`><input id=n type=number min=0 value=0><input id=m type=number min=1 value=1><pre id=o>1

32 bit tamsayı taşmasıyla sınırlıdır, ancak yüzmeler 1 baytlık bir maliyetle kullanılabilir.


Umm ... bu sadece bir girdi alır
Herman L

@HermanLauenstein Maalesef, sorunun bir kısmının kısa sürede çözüleceğini bir şekilde tamamen göz ardı ettim.
Neil

1

J , 25 24 21 20 bayt

3 :'#/.~,+//y$i.{:y'

Çevrimiçi deneyin!

Başlangıçta [1..n] 'yi elde etmek için [0..n-1] listesini arttırdım ama görünüşe göre bu gerekli değil.


Güzel cevap İşte bayt aynı sayıda zımni sürümü: #/.~@,@(+///)@$i.@{:. Fiil çekingen hale getirmek için onu biraz daha aşağı traş etmenin bir yolu olmalı gibi görünüyor, ama yapamadım.
Jonah

@Jonah'da fazladan /var+//
FrownyFrog

Aslında haklısın. Sadece iki şekilde çalışmak olur. Sanırım bu çözüm bir bayt kurtarıyor :)
Jonah

1

Javascript (ES6), 89 bayt

b=>g=a=>a?(l=[..."0".repeat(b-1),...g(a-1)]).map((_,i)=>eval(l.slice(i,i+b).join`+`)):[1]

Körleme sözdizimini ters sırada alır f(b)(a)

f=b=>g=a=>a>0?(l=[..."0".repeat(b-1),...g(a-1)]).map((_,i)=>eval(l.slice(i,i+b).join`+`)):[1]
r=_=>{o.innerText=f(+inb.value)(+ina.value)}
<input id=ina type=number min=0 onchange="r()" value=0>
<input id=inb type=number min=1 onchange="r()" value=1>
<pre id=o></pre>


1

Aslında , 13 12 bayt

Bay Xcoder sayesinde -1 bayt. Çevrimiçi deneyin!

R∙♂Σ;╗╔⌠╜c⌡M

Ungolfed

                Implicit input: b, a
R∙              ath Cartesian power of [1..b]
  ♂Σ            Get all the sums of the rolls, call them dice_rolls
    ;╗          Duplicate dice_rolls and save to register 0
      ╔         Push uniquify(dice_rolls)
       ⌠  ⌡M    Map over uniquify(dice_rolls), call the variable i
        ╜         Push dice_rolls from register 0
         c        dice_rolls.count(i)
                Implict return

Buna ihtiyacın yok, değil @mi?
Bay Xcoder

Bir yandan not olarak, ilginç bir alternatif buldum:R∙♂Σ╗╜╔⌠╜c⌡M
Bay Xcoder

1

AWK , 191 bayt

Frekansları dikey sütun olarak verir.

func p(z){for(m in z)S[z[m]]++
for(i=$1;i<=$1*$2;i++)print S[i]}func t(a,b,z,s){if(a){if(R++)for(n in z)for(i=0;i++<b;)s[n,i]=z[n]+i
else for(i=0;i++<b;)s[i]=i
t(--a,b,s)}else p(z)}{t($1,$2)}

Çevrimiçi deneyin!

6 bayt daha eklemek, birden fazla girdi kümesine izin verir.

func p(z,S){for(m in z)S[z[m]]++
for(i=$1;i<=$1*$2;i++)print S[i]}func t(a,b,z,s){if(a){if(R++)for(n in z)for(i=0;i++<b;)s[n,i]=z[n]+i
else for(i=0;i++<b;)s[i]=i
t(--a,b,s)}else p(z)}{R=0;t($1,$2)}

Çevrimiçi deneyin!


1

Clojure, 86 bayt

#(sort-by key(frequencies(reduce(fn[r i](for[y(range %2)x r](+ x y 1)))[0](range %))))

Bir örnek:

(def f #(...))
(f 5 4)

([5 1] [6 5] [7 15] [8 35] [9 65] [10 101] [11 135] [12 155] [13 155] [14 135] [15 101] [16 65] [17 35] [18 15] [19 5] [20 1])

0

C (gcc) , 142 bayt

i,j,k;int*f(a,b){int*r=malloc(sizeof(int)*(1+a*~-b));r[0]=1;for(i=1;i<=a;i++)for(j=i*~-b;j>=0;j--)for(k=1;k<b&k<=j;k++)r[j]+=r[j-k];return r;}

Çevrimiçi deneyin!


sizeof(int)? Gerçekten mi?
orlp

@orlp çevreye bağlı, biliyorsunuz
Leaky Nun

2
Bir C programının belirli bir mimariyi üstlenmesine izin verilir. En az bir makinede çalıştığı sürece. Dahası, 8herhangi bir mimari üzerinde çalışacak, birazcık özetlenecek ama sorun değil.
orlp

r[0]=1;for(i=1;i<=a;i++)for(j=i*~-b; -> for(i=r[0]=1;i<=a;)for(j=i++*~-b; -2 bayt.
Kevin Cruijssen

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.