Phân phối tần số của nhiều con xúc xắc


23

Cho hai số nguyên dương ab, đưa ra phân phối tần số của thời gian bchết có mặt avà tổng hợp kết quả.

Phân phối tần suất liệt kê tần suất của mỗi tổng có thể nếu mỗi chuỗi cuộn xúc xắc có thể xảy ra một lần. Do đó, tần số là các số nguyên có tổng bằng b**a.

Quy tắc

  • Các tần số phải được liệt kê theo thứ tự tăng dần của tổng mà tần số tương ứng.
  • Ghi nhãn tần số với các khoản tiền tương ứng được cho phép, nhưng không bắt buộc (vì các khoản tiền có thể được suy ra từ thứ tự yêu cầu).
  • Bạn không phải xử lý các đầu vào trong đó đầu ra vượt quá phạm vi số nguyên có thể biểu thị cho ngôn ngữ của bạn.
  • Các số 0 đứng đầu hoặc dấu không được phép. Chỉ có tần số dương sẽ xuất hiện ở đầu ra.

Các trường hợp thử nghiệm

Định dạng: 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]

Chúng ta có thể cho rằng đó blà ít nhất 2? (Hoặc nếu không, danh sách tần suất cho các khoản tiền của một cái chết 1 mặt trông như thế nào?)
Misha Lavrov

Chúng ta có thể có số 0 đầu hay không?
xnor

Câu trả lời:


9

Octave , 38 byte

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

Hãy thử trực tuyến!

Giải trình

Thêm các biến ngẫu nhiên độc lập tương ứng với việc tạo các hàm khối xác suất (PMF) hoặc nhân các hàm đặc trưng của chúng (CF). Do đó, CF của tổng các biến ađộc lập, phân phối giống hệt nhau được đưa ra bằng giá trị của một biến duy nhất được nâng lên thành lũy thừa của a.

CF về cơ bản là biến đổi Fourier của PMF và do đó có thể được tính toán thông qua FFT. Các PMF của một đơn bchết -sided là thống nhất trên 1, 2, ..., b. Tuy nhiên, hai sửa đổi là bắt buộc:

  • 1được sử dụng thay cho các giá trị xác suất thực tế ( 1/b). Bằng cách này, kết quả sẽ được khử chuẩn hóa và sẽ chứa các số nguyên theo yêu cầu.
  • Việc đệm với các số 0 là cần thiết để đầu ra FFT có kích thước phù hợp ( a*b-a+1) và hành vi định kỳ ngầm định được giả định bởi FFT không ảnh hưởng đến kết quả.

Khi đã thu được hàm đặc trưng của tổng, một FFT nghịch đảo được sử dụng để tính kết quả cuối cùng và làm tròn được áp dụng để sửa cho các điểm không chính xác của dấu phẩy động.

Thí dụ

Xem xét đầu vào a=2, b=6. Mã a:a*b<a+bxây dựng một vectơ với các vectơ b=6, không đệm đến kích thước a*b-a+1:

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

Sau đó fft(...)cho

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

Người ta gần như có thể nhận ra hàm chân tại đây (biến đổi Fourier của xung hình chữ nhật).

(...).^atăng mỗi mục nhập avà sau đó ifft(...)lấy FFT nghịch đảo, cung cấp cho

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

Mặc dù kết quả trong trường hợp này là số nguyên chính xác, nhưng nhìn chung có thể có các lỗi tương đối của thứ tự 1e-16, đó là lý do round(...)cần thiết.


1
Tôi thực sự ấn tượng!
rahnema1

@ rahnema1 Xử lý tín hiệu cho chiến thắng!
Luis Mendo

8

Toán học, 29 byte

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

Chỉ cần tạo ra tất cả các cuộn súc sắc có thể, lấy tổng của họ, sau đó đếm. Mỗi tần số được dán nhãn với giá trị của nó.

Toán học, 38 byte

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

Mở rộng (1+x+x^2+...+x^(a-1))^bvà lấy các hệ số của x. Vì 1+x+x^2+...+x^(a-1)là hàm tạo cho một cuộn chết và các sản phẩm tương ứng với các kết quả - thêm giá trị của súc sắc - kết quả cho phân phối tần số.


6

Haskell , 90 79 77 75 byte

Cảm ơn Lynn cho thủ thuật sản phẩm của Cartesian . -11 byte nhờ nhiều thủ thuật Haskell từ Funky Computer Man, -2 byte từ đặt tên, -2 byte nhờ Laikoni. Đề nghị chơi golf được chào đón! Hãy thử trực tuyến!

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

Bị đánh cắp

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

Sử dụng $thay vì ()để lưu 2 byte. TIO
Thuật sĩ lúa mì




(map length$)=(length<$>)cho hai byte
Michael Klein

4

Pyth - 10 byte

Chỉ mất tất cả kết hợp xúc xắc có thể bằng cách lấy sản phẩm Cartesian của [1, b], athời gian, tổng hợp, và nhận được độ dài của mỗi nhóm sum.

lM.gksM^SE

Phòng thử nghiệm .


4

05AB1E , 8 byte

LIãO{γ€g

Hãy thử trực tuyến!

Làm sao?

LIãO {€ g - Chương trình đầy đủ.

L - Phạm vi [1 ... đầu vào # 1]
 I - Đầu vào số 2.
  ã - Sức mạnh của Cartesian.
   O - Bản đồ với tổng.
    {- Sắp xếp.
     γ - Nhóm các phần tử bằng nhau liên tiếp.
      € g - Lấy chiều dài của mỗi


4

R , 52 byte

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

Hãy thử trực tuyến!

Một cổng của giải pháp Octave của @Luis Mendo , fft(z, inverse=T)không may trả về FFT nghịch đảo không chuẩn hóa, vì vậy chúng ta phải chia theo chiều dài và nó trả về một complexvectơ, vì vậy chúng ta chỉ lấy phần thực.


chơi tốt - hoàn vốn cho ngày hôm qua cmdscaletôi hình :-)
flodel

@flodel hah! Tôi thực sự sẽ trao cho bạn một tiền thưởng cho cái đó :)
Giuseppe

Bạn không đùa đâu! Thật hào phóng của bạn! Tôi thích nhìn thấy (và học hỏi từ) câu trả lời của bạn, tôi sẽ trả lại nó nhanh chóng!
flodel

3

SageMath, 40 byte

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

Dùng thử trực tuyến

convolutiontính tích chập rời rạc của hai danh sách. reduceLiệu những gì nó nói trên tin. [1]*blà một danh sách của b 1s, phân phối tần số của 1db. [[1]*b]*alàm cho một danh sách lồng nhau của các abản sao của b 1s.


Python 2 + NumPy , 56 byte

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

Hãy thử trực tuyến!

Tôi đã bao gồm giải pháp này với giải pháp trên, vì về cơ bản chúng tương đương nhau. Lưu ý rằng hàm này trả về một mảng NumPy chứ không phải danh sách Python, vì vậy đầu ra trông hơi khác nếu bạn làm printnhư vậy.

numpy.ones((a,b))là cách "chính xác" để tạo một mảng để sử dụng với NumPy, và do đó nó có thể được sử dụng thay thế [[1]*b]*a, nhưng thật không may là lâu hơn.


3

Thạch , 5 byte

ṗS€ĠẈ

Hãy thử trực tuyến!

Lưu ý rằng điều này có các đối số theo thứ tự ngược lại.

Làm sao?

ṗS € L € - Chương trình đầy đủ (dyadic) | Ví dụ: 6, 2

- Sức mạnh của Cartesian (với phạm vi ngầm) | [[1, 1], [1, 2], ..., [6, 6]]
 S € - Tổng mỗi | [2, 3, 4, ..., 12]
   - Chỉ số nhóm theo giá trị | [[1], [2, 7], [3, 8, 13], ..., [36]]
    L € - Chiều dài của mỗi nhóm | [1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]

Các giải pháp thay thế:

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






1

JavaScript (ES6), 94 byte

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

Bị giới hạn bởi tràn số nguyên 32 bit, nhưng có thể sử dụng số float thay thế với chi phí 1 byte.


Umm ... việc này chỉ mất một đầu vào
Herman L

@HermanLauenstein Xin lỗi, bằng cách nào đó tôi đã hoàn toàn bỏ qua rằng một phần của câu hỏi ... sẽ khắc phục trong thời gian ngắn.
Neil

1

J , 25 24 21 20 byte

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

Hãy thử trực tuyến!

Ban đầu, tôi đã tăng danh sách [0..n-1] để nhận [1..n] nhưng dường như không cần thiết.


Câu trả lời tốt đẹp. Đây là phiên bản ngầm cho cùng số byte : #/.~@,@(+///)@$i.@{:. Có vẻ như nên có một cách để cạo nó xuống một chút để tạo ra động từ dyadic, nhưng tôi đã không thể làm điều đó.
Giô-na

@Jonah bạn có thêm một /trong+//
FrownyFrog

Thật ra, bạn đã đúng. Nó chỉ xảy ra để làm việc cả hai cách. Tôi đoán rằng giải pháp đó tiết kiệm một byte sau đó :)
Jonah

1

Javascript (ES6), 89 byte

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

Đưa đầu vào theo cú pháp currying theo thứ tự ngược lại 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

Trên thực tế , 13 12 byte

-1 byte nhờ ông Xcoder. Hãy thử trực tuyến!

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

Bị đánh cắp

                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

Bạn không cần @, phải không?
Ông Xcoder

Một ghi chú bên lề, tôi đã tìm thấy một sự thay thế thú vị:R∙♂Σ╗╜╔⌠╜c⌡M
Ông Xcoder

1

AWK , 191 byte

Xuất ra tần số dưới dạng cột dọc.

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

Hãy thử trực tuyến!

Thêm 6 byte nữa cho phép nhiều bộ đầu vào.

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

Hãy thử trực tuyến!


1

Clojure, 86 byte

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

Một ví dụ:

(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 byte

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

Hãy thử trực tuyến!


sizeof(int)? Có thật không?
orlp

@orlp phụ thuộc vào môi trường, bạn biết đấy
Leaky Nun

2
Nó được phép cho một chương trình C đảm nhận một kiến ​​trúc cụ thể. Miễn là nó hoạt động trên ít nhất một máy. Hơn nữa, 8sẽ làm việc trên bất kỳ kiến ​​trúc nào, tổng thể một chút nhưng không sao.
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;cho -2 byte.
Kevin Cruijssen

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.