複数のサイコロの頻度分布


23

2つの正の整数aとを指定するとbbサイコロのサイコロを振っaて結果を合計する頻度分布を出力します。

頻度分布は、サイコロの各可能なシーケンスが一度発生した場合、各可能な合計の頻度をリストします。したがって、頻度は合計がに等しい整数ですb**a

ルール

  • 周波数は、周波数が対応する合計の昇順でリストする必要があります。
  • 対応する合計で頻度をラベル付けすることは許可されていますが、必須ではありません(合計は必要な順序から推測できるため)。
  • 出力が言語の表現可能な整数の範囲を超える入力を処理する必要はありません。
  • 先頭または末尾のゼロは許可されません。出力には正の周波数のみが表示されます。

テストケース

フォーマット: 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]

それbが少なくとも2 だと仮定できますか?(またはそうでない場合、片面ダイスの合計の頻度リストはどのようになりますか?)
ミシャラヴロフ

先行ゼロまたは後続ゼロを使用できますか?
-xnor

回答:


9

オクターブ、38バイト

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

オンラインでお試しください!

説明

独立したランダム変数の追加は、確率質量関数(PMF)の畳み込み、または特性関数の乗算(CF)に対応します。したがって、a独立した同一分布の変数の合計のCFは、1の累乗で累乗された単一の変数のCF によって与えられaます。

CFは基本的にPMFのフーリエ変換であるため、FFTを介して計算できます。単一のPMF b-sidedダイが上に均一です12、...、 b。ただし、2つの変更が必要です。

  • 1実際の確率値(1/b)の代わりに使用されます。これにより、結果は非正規化され、必要に応じて整数が含まれます。
  • FFT出力が適切なサイズ(a*b-a+1)になり、FFTが想定する暗黙的な周期的動作が結果に影響を与えないように、ゼロでパディングする必要があります。

合計の特性関数が取得されると、逆FFTを使用して最終結果が計算され、浮動小数点の不正確さを修正するために丸めが適用されます。

入力を考えてみましょうa=2b=6。コードa:a*b<a+bは、b=6サイズがゼロで埋め込まれた1でベクトルを構築しますa*b-a+1

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

それからfft(...)与える

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

ここで、sinc関数をほぼ認識できます(矩形パルスのフーリエ変換)。

(...).^a各エントリを上昇させa、次いでifft(...)得られる逆FFTを取ります

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

この場合の結果は正確に整数ですが、一般にの順序の相対誤差が存在する可能性があり1e-16、これround(...)が必要な理由です。


1
本当に感動しました!
rahnema1

@ rahnema1勝利のための信号処理!
ルイスメンドー

8

Mathematica、29バイト

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

可能性のあるすべてのサイコロを生成し、その合計を取得してからカウントします。各周波数には、その値のラベルが付いています。

Mathematica、38バイト

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

(1+x+x^2+...+x^(a-1))^bの係数を展開して取得しますx。以来、1+x+x^2+...+x^(a-1)単一のダイロールする生成関数であり、製品は畳み込みに対応する-サイコロの値を加算-結果は、周波数分布を与えます。


6

Haskell90 79 77 75バイト

デカルト積のトリックについてリンに感謝します。Funky Computer Manからの多くのHaskellトリックのおかげで-11バイト、ネーミングから-2バイト、Laikoniのおかげで-2バイト。ゴルフの提案は大歓迎です!オンラインでお試しください!

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

非ゴルフ

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バイトを節約します。TIO
小麦ウィザード




(map length$)=(length<$>)2バイト
マイケルクライン

4

Pyth-10バイト

のデカルト積[1, b]a時間、合計を取り、各合計グループの長さを取得することにより、可能なすべてのサイコロの組み合わせを取得します。

lM.gksM^SE

テストスイート


4

05AB1E、8バイト

LIãO{γ€g

オンラインでお試しください!

どうやって?

LIãO{γ€g-完全なプログラム。

L-範囲[1 ...入力#1]
 I-入力#2。
  ã-デカルトパワー。
   O-合計付きのマップ。
    {-並べ替え。
     γ-連続する等しい要素をグループ化します。
      €g-それぞれの長さを取得


4

R、52バイト

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

オンラインでお試しください!

@Luis MendoのOctaveソリューションのポートは、fft(z, inverse=T)残念ながら非正規化逆FFTを返すため、長さで除算する必要があり、complexベクトルを返すため、実数部のみを取得します。


よくプレイ-昨日のcmdscaleIフィギュアの回収:
flodel

@flodelハァッ!実際にその賞金を授与します:)
ジュゼッペ

あなたは冗談ではありませんでした!とても寛大です!私はあなたの答えを見る(そして学ぶ)のが好きです。すぐに返済します!
flodel

3

SageMath、40バイト

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

オンラインで試す

convolution2つのリストの離散畳み込みを計算します。reduceそれは錫で言うことをします。[1]*bはのリストでありb 1、の頻度分布です1db[[1]*b]*aaコピーのネストされたリストを作成しb 1ます。


Python 2 + NumPy、56バイト

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

オンラインでお試しください!

これらは本質的に同等なので、このソリューションを上記のソリューションに含めました。この関数はPythonリストではなくNumPy配列を返すため、出力は少し異なって見えることに注意してくださいprint

numpy.ones((a,b))は、NumPyで使用する配列を作成する「正しい」方法です。したがって、の代わりに使用できますが[[1]*b]*a、残念ながら長くなります。


3

ゼリー、5 バイト

ṗS€ĠẈ

オンラインでお試しください!

これは、逆の順序で引数を取ることに注意してください。

どうやって?

ṗS€ĠL€-フルプログラム(ダイアディック)| 例:6、2

ṗ-デカルトパワー(暗黙的範囲付き)| [[1、1]、[1、2]、...、[6、6]]
 S€-それぞれ合計| [2、3、4、...、12]
   Ġ-値によるインデックスのグループ化| [[1]、[2、7]、[3、8、13]、...、[36]]
    L€-各グループの長さ| [1、2、3、4、5、6、5、4、3、2、2、1]

代替ソリューション:

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






1

JavaScript(ES6)、94バイト

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ビット整数のオーバーフローによって制限されますが、代わりに1バイトのコストでフロートを使用できます。


うーん...これは1つの入力のみを取ります
ハーマンL

@HermanLauenstein申し訳ありませんが、質問のその部分をどういうわけか見落としていました...まもなく修正されます。
ニール

1

J25 24 21 20バイト

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

オンラインでお試しください!

最初は[0..n-1]リストをインクリメントして[1..n]を取得しましたが、どうやらそれは必要ないようです。


いい答えだ。同じバイト数の暗黙バージョンを次に示します#/.~@,@(+///)@$i.@{:。動詞を二項的なものにするためにもう少し削る方法があるべきだと思われますが、私はそれをすることができませんでした。
ジョナ

@Jonahあなたは余分を持っている/+//
FrownyFrog

実際、あなたは正しい。両方の方法で機能するだけです。私はその解決策がバイトを節約すると思います:)
ジョナ

1

Javascript(ES6)、89バイト

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

カリー化構文の入力を逆順で受け取ります 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

実際には13 12バイト

Xcoder氏のおかげで-1バイト。オンラインでお試しください!

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

非ゴルフ

                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

あなたは必要ありません@、あなたは?
ミスターXcoder

サイドノートとして、私は興味深い代替案を見つけました:R∙♂Σ╗╜╔⌠╜c⌡M
Mr Xcoder

1

AWK、191バイト

周波数を垂直列として出力します。

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)}

オンラインでお試しください!

さらに6バイトを追加すると、複数の入力セットが可能になります。

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)}

オンラインでお試しください!


1

Clojure、86バイト

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

例:

(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バイト

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;}

オンラインでお試しください!


sizeof(int)?本当に?
-orlp

@orlp環境に依存、あなたは知っている
リーキー修道女

2
Cプログラムが特定のアーキテクチャを想定することは許可されています。少なくとも1台のマシンで動作する限り。さらに、8すべてのアーキテクチャで動作し、全体的に少しだけですが、それでも大丈夫です。
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バイト。
ケビンCruijssen

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.