Đây là mã mà gd047 và Marek đủ tử tế để cung cấp.
S <- 6
N <- 4
n <- choose(S+N-1,N)
outcomes <- t(combn(S+N-1,N,sort)) - matrix(rep(c(0:(N-1)),each=n),nrow=n)
Lưu ý: điều này là tối ưu theo nghĩa là nó không cố gắng tạo ra tất cả và sau đó vứt bỏ hai lần. It actually generates only those that are required
.
Giải thích về lý do tại sao nó hoạt động:
Những con số có thể trên con xúc xắc là 1 đến N.
Giả sử bạn có một sự kết hợp có thể có của những con số xúc xắc: x , x , ..., x S trong đó S là số súc sắc.
Kể từ thứ tự không quan trọng, chúng ta có thể giả định rằng
x ≤ x ≤ ..., ≤ x S.
Bây giờ xem xét các chuỗi x , x + 1, x + 2, ..., x S + S-1.
(Ví dụ: 1,1,1 trở thành 1,1 + 1,1 + 2 = 1,2,3).
Chuỗi mới này có các số từ 1 đến N + S-1 và tất cả các số đều khác nhau.
Ánh xạ này từ chuỗi xúc xắc của bạn đến chuỗi mới mà chúng tôi đã tạo là 1-1 và dễ dàng đảo ngược.
Vì vậy, để tạo ra sự kết hợp có thể của xúc xắc S với số từ 1 đến N, tất cả những gì bạn cần làm là tạo tất cả N + S-1 Chọn S kết hợp các số S từ 1, 2, ..., N + S-1. Với sự kết hợp như vậy, bạn sắp xếp nó, trừ 0 từ nhỏ nhất, 1 từ nhỏ nhất thứ hai trở lên để kết hợp số xúc xắc của bạn cho S xúc xắc được đánh số 1 đến N.
Ví dụ, giả sử N = 6 và S = 3.
Bạn tạo kết hợp 3 số từ 1 đến 6 + 3-1 = 8, tức là 3 số từ 1,2, ..., 8.
Giả sử bạn nhận được 3,6,7. Điều này dịch sang 3, 6-1, 7-2 = 3,5,5.
Nếu bạn có 1,2,8. Điều này sẽ chuyển thành 1,1,6.
Ngẫu nhiên, ánh xạ này cũng chứng minh công thức bạn có.
Được gắn thẻ lại để thêm xúc xắc và thuật toán. –