1
$\begingroup$

Which is the algorithm (the program) to count the number of ways a dice can be rolled until the sum of all outcomes be a given $n$? $n$ is in the order of 1000.

I tried with the formula of polynomial (generating function). But I was thinking to do it with a program unaware of any formula.

  • 0
    Do you consider outcomes like 162 and 126 as distinct ?2017-02-28
  • 0
    yes, the order matters2017-02-28

2 Answers 2

1

If you denote by $S(n)$ the number of possible "roll sequences" adding up to exactly $n$, using a die with $f$ faces numbered $1$ to $f$ ("standard" cubic dice have $f=6$) a recursive algorithm to return $S(n)$ is:

count_roll_sequences(n):

if $n\leq 0$ return $0$

if $1\leq n \leq f$ return $1+\sum_{i=0}^{n-1}$ count_roll_sequences$(i)$

if $n>f$ return $\sum_{i=n-f}^{n-1}$ count_roll_sequences$(i)$

Note that this does not count the possibility of rolling $0$ times to obtain $0$ as a sum (which some people may want to include).

Also note that this is not computationally efficient, in the same way as computing the $i^{th}$ Fibonacci number as Fib(i): return Fib(i)+Fib(i-1) is not computationally efficient. When computing $S(n)$ wou'd want to compute $S(1),S(2)...S(n-1)$ once each, store them into an array, and retrieve them from there when invoking count_roll_sequences$(i)$, rather than computing them anew, as follows:

count_roll_sequences(n):

if $n\leq 0$ return 0;

else:

create array of $n+f$ elements, c[0]...c[n+f-1];

c[0]=0;

for (j=1 to f) c[j] = 1 + $\sum_{i=0}^{j-1}$ c[i]

for (j=f+1 to n) c[n] = $\sum_{i=j-f}^{j-1}$ c[i]

return c[n]

  • 0
    thk.S(i) is a permutations?2017-02-28
  • 0
    No S(i) is the value returned by the algorithm with input i. If you are familiar with recursive algorithms, you know that you can write foo(x): if (x<1) return 1; else return foo(x-1). Let me edit to make it slightly clearer.2017-02-28
  • 0
    thks. it works!2017-02-28
  • 0
    @giuseppe uhm, if that works, why did you "un-accept" my answer after accepting it?2017-02-28
  • 0
    For n=550 is not efficient. Could u please more precise with what u mean "storing" S(i)?2017-02-28
  • 0
    @giuseppe Let me write an iterative algorithm for people who do not know recursive algorithms :)2017-02-28
  • 0
    @giuseppe clearer now?2017-02-28
1

These "number of ways" constitute the so-called Hexanacci numbers (https://oeis.org/A001592)

$$ 1, 2, 4, 8, 16, 32, 63, 125, 248, 492, 976, 1936, 3840, 7617, 15109, 29970, 59448, 117920,...$$

defined by recurrence relationship:

$$\tag{1}a_{n} = \sum_{k=1}^6 a_{n-k} \ \ \text{with} \ \ a_{-5}=a_{-4}=a_{-3}=a_{-2}=a_{-1}=0, \ \text{and} \ a_{0}=1.$$

NB: six artificial values have had to be introduced before the beginning of the "true" sequence with $a_1$.

let us consider now an example: let us take $n=4$; there are $a_4=8$ ways to obtain a total of 4:

$$\underbrace{(1111, 211, 121, 31)}_{a_3=4}, \underbrace{(112, 22)}_{a_2=2}, \underbrace{(13)}_{a_1=1}, \underbrace{(4)}_{a_0=1}.$$

(we have grouped them according to their last number, either 1,2,3,4, here).

The proof of (1) is easy, and can be understood as a generalization of example above.

The set $\frak{S}_n$ of sequences of numbers $\{1,2,\cdots 6\}$ whose sum is $n$ can be partitioned into at most 6 (non intersecting) classes $C_1, C_2, ... C_6$, this index being in correspondence with the last digit of the sequence. How such a sequence can be built ? By adding

  • 1 to any of the $a_{n-1}$ sequences summing to $n-1$,

  • 2 to any of the $a_{n-2}$ sequences summing to $n-2$,

...

  • 6 to any of the $a_{n-6}$ sequences summing to $n-6$.

(some of these sets being hopefully void) [end of proof].

Recurrence (1) is a very efficient way to obtain these numbers.

It is rather easy to prove that sequence $a_n$ (shown in red on the figure) is equivalent to (and bounded from above by) sequence $2^{k-1}$, $k=1\cdots (n-1)$ (in blue), with coincidence for the first 6 terms.

Here is a Matlab program implementing these ideas, generating the sequence $b_n:=a_{n+6}$

  n=1000;n1=n+6;
  b=zeros(1,n1);
  b(6)=1;
  for k=7:n1
      a(k)=sum(b(k-6:k-1));
  end
  b(n1)

For $n=1000$, one finds $b_{1006}=a_{1000}\approx 1.47 \times 10^{297}$ !

enter image description here

  • 0
    good answer! (+1)2017-02-28
  • 0
    @G Cab Thanks. Once more, EOIS is a rich source...2017-02-28
  • 0
    @giuseppe I have added a (Matlab) program which gives the value of $a_n$ almost instantaneously even for large values of $a_n$. I think that using a generating function is not adapted for as large coefficients.2017-03-01
  • 0
    @giuseppe Your reaction to my text ?2017-03-02