One source of ennui in tabletop role-playing games is dealing with rolls involving many dice. Casting a Disintegration spell may be instantaneous, but rolling and adding together 40 dice certainly isn't!
A number of suggestions for handling this are discussed at rpg.stackexchange.com. Some of them, however, such as using a roller program or averaging dice, take away some of the fun and sense of control from the players. Others, such as rolling 4 dice and multiplying the total by 10, make the results far more swingy (while averaging dice acts in the opposite direction).
This question concerns a method of reducing the number of dice rolls without changing either the average result (mean) or its swinginess (variance).
Notation and math
In this question, we'll use the following notation to represent dice rolls:
- ndk (e.g. 40d6) refers to the sum of n rolls of a k-sided die.
- ndk*c (e.g. 4d6*10) describes multiplying the result by a constant c.
- We can also add rolls (e.g. 4d6*10 + 40d6) and constants (e.g. 4d6 + 10).
For a single die roll, we can show that:
- Mean: E[1dk] = (k+1)/2
- Variance: Var(1dk) = (k-1)(k+1)/12
Using the basic properties of mean and variance, we can furthermore infer that:
- Mean: E[mdk*a + ndl*b + c] = a.m.E[1dk] + b.n.[1dl] + c
- Variance: Var(mdk*a + ndl*b + c] = a².m.Var(1dk) + b².n.Var(1dl)
Given three integers n, k and r, your program should output a way of approximating ndk in at most r rolls, with the following constraints:
- The solution should have the same mean and variance as ndk.
- The solution should contain the largest possible number of rolls less than or equal to r, as more rolls produces a smoother distribution.
- You should restrict your solutions to only using k-sided dice, unless you're aiming for the Bonus (see below).
- If there is no solution (as r is too small), the program should output the string "I AM A SEXY SHOELESS GOD OF WAR!".
- The parameters are passed in as a single space-separated string.
- You may assume that 1 ≤ n ≤ 100, 1 ≤ r ≤ n and that k is one of 4, 6, 8, 10, 12 and 20 (the standard dice used in tabletops).
- The output should be in the format described in Notation (e.g. 4d6*10+5), with optional spaces around +s but nowhere else. Unit multipliers are also optional: both 4d6*1 and 4d6 are valid.
You may write a program or function, taking input via STDIN (or closest alternative), command-line argument or function argument. Results should be printed to STDOUT (or closest alternative) or returned as a string.
>> "10 6 10" 10d6 >> "10 6 4" 2d6*2+2d6+14 >> "10 6 3" 1d6*3+1d6+21 >> "10 6 2" 1d6*3+1d6+21 >> "10 6 1" I AM A SEXY SHOELESS GOD OF WAR!
Shortest code wins. Standard rules apply.
-33% (rounded down before subtraction) if your program also return solutions that include valid dice other than k (where the valid values, as mentioned above, are 4, 6, 8, 10, 12 and 20). If you choose to do so, then you should always return such solutions when appropriate, and handle solutions that use multiple types of die. Example:
>> "7 4 3" 3d6+7