Interview Question
Country: United States
To solve this problem we can use recursion, which will assign the highest face value to a dice, and recursively call itself, with m-1 faces (as well as lower total x-m, and n-1 dice).
#!/usr/bin/env python3
def dice(m, x, n):
def _dice(m, x, n):
if x==0 and n==0:
yield curr_dice
elif m>0:
while x>=0 and n>=0:
yield from _dice(m-1, x, n)
curr_dice[m-1] += 1
x-=m
n-=1
curr_dice[m-1] = 0
curr_dice = [ 0 for i in range(m) ]
yield from _dice(m, x, n)
return
def main():
m=6
x=7
n=2
print(m,x,n)
for a in dice(m,x,n):
print(a)
if __name__ == "__main__":
main()
As it was mentioned above there is recursive dependancy:
number of ways sum X could be calculated from n dice with m face is equal to
number of ways sum X - 1 could be calculated from n - 1 dice with m face +
number of ways sum X - 2 could be calculated from n - 1dice with m face +...
number of ways sum X - m could be calculated from n - 1 dice with m face
We use dymamic programming because of overlapping subproblems and optimal substructure.
int numberOfWays(int n, int m, int sum) {
int[][] ways = new int[n + 1][sum + 1];
int min = Math.min(sum,m);
for(int i = 1; i<= min; i++) {
ways[1][i] = 1;
}
for (int i = 2; i <= n ;i++) {
for (int j = 1; j <= sum ; j++)
for (int k = 1; k <= m && k < j; k++)
ways[i][j] += ways[i-1][j - k];
}
return ways[n][sum];
}
Time complexity is O(sum*m*n)
// C#, O(NumOfDice * NumOfDice * Total)
<code><pre class="language-java">
public static string GetMutation(int[] arr, int total)
{
var sum = 0;
var str = "";
foreach (var n in arr)
{
str = str + ", " + n;
sum += n;
}
if (total == sum)
{
return str;
}
return "";
}
public static List<string> GetMutations(int NumOfFace, int NumOfDice, int Sum)
{
var permuation = new List<string>();
//no permuation
if (Sum < NumOfDice || Sum > NumOfFace*NumOfDice)
{
return permuation;
}
var getMin = Sum > NumOfFace? NumOfFace: (Sum-NumOfDice+1) ;
// var dir = new Dictionary<int, int>();
var list = new int[NumOfDice];
for (int j = 0; NumOfDice > j; j++)
{
list[j] = 1;
}
var aaa = GetMutation(list, Sum);
if (!string.IsNullOrEmpty(aaa) )
{
permuation.Add(aaa);
return permuation;
}
bool isoverFlow = false;
while (!isoverFlow)
{
aaa = GetMutation(list, Sum);
if (!string.IsNullOrEmpty(aaa))
{
permuation.Add(aaa);
}
for (int j = 0; j < NumOfDice; j++)
{
if (list[j] == getMin )
{
if (j + 1 == NumOfDice)
{
isoverFlow = true;
break;
}
list[j] = 1;
}
else
{
list[j]++;
for (int k = 0; k < j; k++)
{
list[k] = list[j];
}
break;
}
}
}
return permuation;
}
</code> </pre>
- Sumeet Singhal March 10, 2016