Google Interview Question for SDE1s


Country: India




Comment hidden because of low score. Click to expand.
7
of 7 vote

Dynamic Programming solution:
Let Nways(s, n) - number of ways to make sum s with n dices.
Nways(s, n) = Summation{1..a} Nways(s-i, n-1)
Base case:
Nways(s, 1) = 1 if (s<= a && s>0), 0 otherwise.


Edit:
I see lot of new solutions posted are using only recursion. Memoization should be used otherwise the algorithm is very slow.
Recursion with a lookup table for already computed values is the right way to go.

- Vinay April 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Here is the c++ code, using DP.

#include <iostream>
#include <vector>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)n; i++)
#define rep2(i,m,n) for(int i=m;i<(int)n; i++)

int PossibleDiceRolls(int S, int A, int N) {
	vector< vector<int> > sum;
	sum.resize(S+1);
	rep(i,S+1)
		sum[i].assign(N+1,0);
	rep(i,min(A+1,S+1))
		sum[i][1] = 1;

	rep2(n,2,N+1)
		rep2(i,1,S+1)
			rep2(j,1,A+1)
				if(i-j>0)
					sum[i][n]+=sum[i-j][n-1];
									 
	return sum[S][N];
}

int main()
{
	cout << PossibleDiceRolls(6, 6, 3) << endl;
	return 0;
}

- chetan.j9 May 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

O(N*S*A) time i think

- Anonymous May 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

hey ANON please share your complete interview experience.

what is your email id?

- Anonymous March 17, 2014 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

good point, I should take 'a' out from the recursive function, thanks

- Lu April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

Same solution as described by Vinay:

#include <iostream>
#include <string>
#include <map>
#include <vector>

using namespace std;

int NoOfSol(int A, int N, int S, map<pair<int, int>, int>& m, vector<int>& vs)
{
        if (S < 0) return 0;

        if (N==1) {
                if (S >= 1 && S<= A) {
                        for (int i=0; i<vs.size(); i++) {
                                cout << vs[i] << ", " ;
                        }
                        cout << S << endl;
                        return 1;
                }
                return 0;
        }
        if (m.count(make_pair(N,S)) != 0)
        {
                int cnt = m.at(make_pair(N,S));
                if (cnt < 1) return cnt;
                cout << "[";
                for (int i=0; i<vs.size(); i++) {
                        cout << vs[i] << ", " ;
                }
                cout << " <sols> : "<< cnt << "]"<<endl;
                return cnt;
        }
        int sol = 0;
        for (int i=1; i<=A; i++) {
                vs.push_back(i);
                sol += NoOfSol(A, N-1, S-i, m, vs);
                vs.pop_back();
        }
        m.insert(make_pair(make_pair(N,S), sol));
        return sol;

}

int main(int argv, char** argc[])
{
        int A = 6;
        int N = 5;
        int S = 10;
        map<pair<int, int>, int> m;
        vector<int> vs;
        cout << "Solutions : " << NoOfSol(A, N, S, m, vs) << endl;
        return 0;
}

- SD : April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I can only think of a recursive solution wherein you every permutation of the dices which will give me time complexity of A^A. There will be better solution than this.

- DashDash April 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1. 2 <= S <= 2A
2. Total number of variations of dice thrown together: A*A
3. Hence 1/(A*A) <= P(S) <= 1/A

- Sumeet April 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I use JavaScript
function get_dice(s,n,a){
var method = 0;
if(n===1){
if(s>0&&s<=a)
return 1;
else
return 0;
}
for(var i =1;i<=a;i++){
method+=get_dice(s-i,n-1,a);
}
return method;
}

- Lu April 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

a does not need to be part of recursive call.

- Vinay April 28, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

noOfWays(N,S) = sum ( noOfWays(N-1,S-i) ) // where i ranges from [1 ,A]

This can be optimized using DP , ill come up with a working code in some time.

- krbchd April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I am sorry but it seems like I got this question in different way and I could only get this in Polynomial time.
I mean using binomial theorem it get ( N is a variable number of Die and F is a variable number of faces of each die) so

N1(F)+N2(F)......N(n-1)(F)+N(n)(F)=S

Which clearly frames polynomial expression.

Any Pointers??

- hprem991 April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

char * and void *

HAHAHAHA.

- Anonymous May 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

@lru_cache(maxsize = None)
def numOfWays(max_dice_value, base_sum):
    
    if base_sum <= 1: 
        return 1
    
    total = 0
    
    for val in range(1, max_dice_value+1):
        if val > base_sum:
            break        
        total += numOfWays(max_dice_value, base_sum - val)

    return total

- m@}{ April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote
{{{ @lru_cache(maxsize = None) def numOfWays(dices, max_dice_value, base_sum): if base_sum == 0 or (dices == 1 and base_sum > max_dice_value): return 0 if base_sum == dices or (dices == 1 and base_sum < max_dice_value): return 1 total = 0 for val in range(1, min(max_dice_value, base_sum) + 1): curWaysCount = numOfWays(dices-1, max_dice_value, base_sum - val) total += curWaysCount return total }}] - m@}{ April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

@lru_cache(maxsize = None)
def numOfWays(dices, max_dice_value, base_sum):       

    if base_sum == 0 or (dices == 1 and base_sum > max_dice_value):
        return 0
    
    if base_sum == dices or (dices == 1 and base_sum < max_dice_value):
        return 1
  
    total = 0
    
    for val in range(1, min(max_dice_value, base_sum) + 1):               
        
        curWaysCount = numOfWays(dices-1, max_dice_value, base_sum - val)
        
        total += curWaysCount

    return total

- m@}{ April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

@lru_cache(maxsize = None)
def numOfWays(dices, max_dice_value, base_sum):  
    
    if base_sum == 0:
        return 0
    
    if base_sum > max_dice_value * dices:
        return 0 
    
    if base_sum == dices or (dices == 1 and base_sum < max_dice_value):
        return 1
  
    total = 0
    
    for val in range(1, min(max_dice_value, base_sum) + 1): 
        
        if val > base_sum:
            break
                 
        if (base_sum - val) == 0 and dices == 1:
            total += 1        
        else:        
            total += numOfWays(dices-1, max_dice_value, base_sum - val)

    return total

- m@}{ April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public static int sum(int[] atp) {
		int sum = 0;
		for (int i = 0; i < atp.length; ++i) {
			sum += atp[i];
		}
		return sum;
	}

	public static void tryDice(final int[] atp, final int F, final int N, final int count, final int S) {
		if (count > N - 1) {
			int sum = sum(atp);
			if(sum == S){
				for (int i = 0; i < atp.length; i++) {
					System.out.print(atp[i] + " ");
				}
				System.out.println();
				
			}
			return;
		}
		int cnt = count + 1;
		for (int i = 1; i <= F; ++i) {
			int[] newAtp = new int[atp.length];
			System.arraycopy(atp, 0, newAtp, 0, atp.length);
			newAtp[count] = i;
			tryDice(newAtp, F, N, cnt, S);
		}
	}

	public static void main(String args[]) {
		int F = 3;
		int D = 6;
		int[] atp = new int[D];
		int S = 10;
		tryDice(atp, F, atp.length, 0, S);
	}

- jaebal April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

public static void main(String[] args) {
		
		for( int i = 2; i<= 12; i++){
		System.out.println(i + " " + solutions(i,0,2, 6));
		}

	}
	
	public static int solutions(int sum, int accum, int n, int A){
		
		if( n == 0){
			return 0;
		}
		
		int solutions = 0;
		for( int i = 1; i<= A; i++){
			int newAccum  = accum +i; 
			if( n==1){
				if( newAccum == sum){
					solutions += 1;
					break;
				}
			} else if( newAccum >= sum){
				break;
			} else {
				solutions += solutions( sum, newAccum, n-1, A);
			}
		}
		
		return solutions;
	}

- grumpy April 29, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Here is a solution with DP and recursion. At each level of the recursion, fix the value of one dice.

UINT NumWays(UINT N, UINT A, UINT SUM)
{
    INT_PAIR index;
    static unordered_map<INT_PAIR, INT, Compare> lookup;
    if (N==1)
    {
        if ( (SUM>0) && (A>= SUM))
        { 
            return 1;
        }
        else
        {
            return 0;
        }
    }
    index.first = N;
    index.second = SUM;
    unordered_map<INT_PAIR, INT>::iterator it;
    it = lookup.find(index);
    if (it != lookup.end())
    {
        return it->second;
    }
    UINT count = 0;
    for (UINT i=1; i <=A; i++)
    {
        if (SUM >= i)
        {
            count += NumWays(N-1, A, SUM-i);
        }
    }
    lookup[index]=count;
    return count;
}

- sameerBandla April 29, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

if this is just finding number of ways,then here is the answer :
1.This is equivalent to x1+x2+x3+...+xn=S where 1<=x1,x2,x3,..xn<=A where x1,x2,..xn are variables whose values are specified on each dice respectively
2.so now let t1=x1-1,t2=x2-1,t3=x3-1,...so now we have (x1-1)+(x2-1)+..+(xn-1)=S-(1+1+..1)=S-n
3.so now we have t1+t2+t3+..+tn=S-n where 0<=t1,t2,..tn<=A-1
4.The number of ways of forming x1+x2+..xr=n where x1,is (n+r-1)C(r-1)(there is a proof :))
5.so now the number of ways = (S-n+n-1)C(n-1)=(S-1)C(n-1) (where nCr=n!/(n-r)!(r!) )

- Karthik Vvs April 30, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

You are right, except you don't account the fact that the xi <= A.
The formula (S-1)C(n-1) gives you the number of combinations to get the sum S from n values xi with 1 <= xi <= S-n+1. But unfortunately S-n+1 might be larger than A.
Example: S = 6, N = 3 and A = 3
Above formula leads to 5C2 = 5!/(3!*2!) = 10
explicitely these combinations:
1+1+4
1+2+3
1+3+2
1+4+1
2+1+3
2+2+2
2+3+1
3+1+2
3+2+1
4+1+1

but in fact we can't draw a 4 if A = 3. Thus the total number of combinatiosn is 7 and not 10.

- Suat G. May 13, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

A simple DP approach:
The function can be written as:
F(N, A, S) = F(N - 1, A, S - 1) + F(N - 1, A, S - 2) +........+ F(N - 1, A, S - A)
Where, The F(N, A, S) represents the number of ways of getting S with N dice each with A faces, numbered from 1 to A.
Explaining the above equation in words,
Find the number of ways of getting Sum (S - 1) from (N - 1) dice +
Find the number of ways of getting Sum (S - 2) from (N - 1) dice +
.................
..................
Find the number of ways of getting Sum (S - A) from (N - 1) dice

Carefully handle the base cases like:
1. N = 1, S > A
2. S < 1

- Aashish May 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

a simple implementation is given below which can be memo-ed of course

int foo(int N, int A, int S){

	if(N<=0)
		return 0;

	if(N==1){
		if(S>=1 && S<=A)
			return 1;
		else
			return 0;
	}

	int sol = 0;
	for(int i=1; i<=A; ++i){
		sol += foo(N-1, A, S-i);
	}

	return sol;
}


int main(){
	int A = 6;
    int N = 2;
    int S = 10;
    cout<<foo(N, A, S)<<endl;
    return 1;
}

- Raullen May 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

what about printing all the possible solutions?

- googlybhai May 11, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Feel free to correct my answer: the base case is where we roll one dice (N = 1). If number of faces (A) is greater than the sum (S), there is always one possible way.

Other cases: F(n, s, a) = Sum of F(n - 1, s - i, i) where i is 1 to number of faces (A).

def count(n, s, a):
  if n < 0 or s < 0 or a < 0:
    return 0

  if n == 0 and s == 0:
    return 1

  if n == 1:
    return a >= s ? 1 : 0

  if n > s:
    return 0

  ret = 0
  for i in xrange(1, a + 1):
    ret += count(n - 1, s - i, i)
  return ret

- DBX May 12, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Only one way. All the dice must add up to S.

- Anonymous June 05, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Correct me if I'm wrong, but the question does not ask how many permutations of the dice (BTW dice is plural for dice). The question simply asked how many ways the dice sum to S. There is only one way; the dice must add up to S.

- native english speaker June 06, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

One of these random objects is called a die. The plural is dice. "Dices" is not an English word and shows ignorance. It is difficult for me to believe that Google would make such obvious English errors in one of their questions.

- native english speaker June 06, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Oh wait! I'm on an Indian site? How did I arrive here? How do we lose so many jobs to this counry if, not only can they not conjugate Engish correctly, they can't even figure out a simple probibliy/permutation problem? So sad for everybody.

- native english speaker June 06, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@native english speaker: Morons like you is why the world hates America.

Now, go ahead, correct me, and say, "Morons like you _are_ why the word hates America".

- Anonymous June 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Anonymous: It is obvious that he (native english speaker #1) is a total idiot, given his answer of "just one way". Sad that such people don't even have the brains to realize how stupid they actually are. Being a racist on top of that, is just pitiable, and I just hope that he is just a benign one, restricted to making idiotic comments on the internet.

- Another native english speaker June 07, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Attack me if you want; the truth must hurt.

- native english speaker June 09, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

True. The truth sometimes hurts, and it is human nature to blame someone else for your troubles. For instance, it is probably your incompetence and stupidy which is preventing you from getting a job, and not the fact that someone else "took" it from you.

- Another native english speaker June 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Guys correct me, if I am wrong. The question in non polynomial (NP) problem. Given N dices and 1...A faces. Therefore the combinations can be A*A*A.......A = A^N. I think all the guys are in right direction sloving by dynamic programming. But need to add distributed computing based on N. Divide the work and add it like map reduce

- Sri Ram Kishore Vemulpali June 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class DiceProblem {

	public static void waysToFindSum(int sum, int remainingDices,int[] faces, int[] output,int numberOfDices,int numberOffaces){
		if(remainingDices == 0 && sum ==0){
			System.out.println("");
			for(int i = 0; i < numberOfDices; i++){
				System.out.print(output[i]+" ");				
			}
			return;
		}
		if(remainingDices == 0)
			return;
		if(sum == 0)
			return;
		for(int j =0; j< numberOffaces;j++){
			if(faces[j] <= sum){
				output[remainingDices-1] = faces[j];
				waysToFindSum(sum-faces[j], remainingDices-1, faces, output, numberOfDices, numberOffaces);
			}
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int numberOfDices = 3;
		int numberOfFaces = 6;
		int sum = 5;
		int[] faces = {1,2,3,4,5,6};
		int[] output = new int[numberOfDices];
		waysToFindSum(sum, numberOfDices, faces, output, numberOfDices,numberOfFaces);
	}

}

- gaurav June 10, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Recursive solution:

public static int nDiceASum(int N, int A, int S){
                if(N<=0) return 0;
                if(N==1){
                        if(S >= 1 && S <= A)
                                return 1;
                        else
                                return 0;
                }

                int result = 0;
                for(int i=1; i<=A; ++i){
                        result += nDiceASum(N-1, A, S-i);
                }

                return result;
        }

Dynamic Program:
Create 2D matrix with numOfDice, sum on 2 dimensions.
So Matrix[s][n] = Sum( Matrix[s-i][n-1]) for i = 1->A

Initialize first row, first column

Matrix[1][1] = 1;
for(int numDice=2; numDice<n; ++numDice)
 	Matrix[1][numDice] = 0;
for(int sum=2; sum<S; sum++){
	if(sum <= A) Matrix[sum][1] = 1;
	else	Matrix[sum][1] = 0;
}

Now compute Matrix[Sum][NumDice] to get the result using below loop

for(int s=2; s<=Sum; s++)
		for(int n=2; n<=NumDice; n++)
			Matrix[s][n] = Sum(Matrix[s-i][n-1]) with i from 1->A;

- X June 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

hi i wrote the below code for this, can anyone please verify this if it fails in any conditionsor any modifications that should be made

public class abs {
	private static int[] combos; 
	
	public static int sumCombos(int currDice,int faces,int sum){
		
		if(sum > faces && currDice==1){

			return -1;
		}
		if(sum <= faces){
			combos[currDice]=sum;
			printCombo();
			return 0;
		}
		for(int i=1;i<=faces;i++){
			combos[currDice]=i;
			sumCombos(currDice-1,faces,(sum-i));
		}
		 
		return 0;
	}

	private static void printCombo(){
		for(int i=1;i<combos.length;i++){
			System.out.print(combos[i]+",");
		}
		System.out.println();
	}
	
	public static void main (String... a){
		int noOfDices=4;	
		int noOfFaces=2;
		int totalSum=5;
		combos=new  int[noOfDices+1];
		sumCombos(noOfDices,noOfFaces,totalSum);
		
	}
}

- Ambuj June 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

A C# implementation of the recursive solution described in above posts.

public static int DifferentWays(int diceFace, int diceCount, int sum)
        {
            if (diceCount == 0)
                return 0;

            if (sum < diceCount) // * 1
                return 0;

            if (sum > diceCount * diceFace)
                return 0;

            if (diceCount == 1)
                return 1;

            int count = 0;
            for (int x = 1; x <= diceFace; x++)
            {
                count += DifferentWays(diceFace, diceCount - 1, sum - x);
            }
            
            return count;
        }

- impala July 18, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Central limit theorem is for i.i.d random variables, here the probabilities are different for each RV.

- Anonymous September 04, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

I got half a solution so far. Let me know if you can get the other half before I do or I give up.
Say you want 13 for a total
And you have 6 dice we won’t worry about the number of faces just yet
If you know that you role 3 ones 2 twos and 1 six you
3 * 1 + 2 * 2 + 1 * 6 = 13 (can I still add?)
We can easily calculate that there are (3+2+1)!/(3!*2!*1!) ways to get it
So we added 60 to the count in one step

If we can quickly iterate through all the combinations of counts of each type of face rather than all the actual sets of roles we might come out ahead.
Know any good algorithm for this
Find all sets of X such that
Such that s is the number of faces

X1* 1 + X2*2 + X3*3 …… Xs * s = total we want
And
X1 + X2 + X3 …… Xs = total number of dice

We could start with X1 as large as possible and then try to make up the difference buy putting values into Xs X(s-1), X(s-2). Then we need some way of transferring value from the high side to the low side without repeating any combinations and without missing any. Probably some loops some recursion and or some dynamic programming as in the solutions above. I think my approach makes the problem smaller in some ways but I am not convinced it really has any advantage when all is told.
If you did a brute force search it would cost O(s^n) perhaps even O(s^(1+n)) if you are lazy about how you calculate the totals to check. This is pretty bad. The complexity of the nice simple naive algorithm is O(n^s) so if n and s are reasonably large and s < n the naïve direct counting is better than the brute force iteration. Dynamic programming is beginning to look very attractive indeed. I think I will try a direct recursive method with dynamic programming.

Any thoughts, you think there is hope for getting through the counts quickly?

I expect that they will ask a different question that needs my half of the answer in combination with some other solution and another question that needs the fast iteration algorithm in combination with yet some other idea: if that makes any sense.

- Dr A' October 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

The probability of Occurrence of a sum while throwing a number of dices can be thought of normal distribution.
the probability function would be p(sum). I forgot the formula, article about normal distribution in Wikipedia might help.
After calculating the p(sum), we can multiply the p(sum) by the number of sides power the number of dices

- Prithvi April 28, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Actually it does. Have a look at the central limit theorem.

- Anonymous April 30, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sorry, actually it doesn't. This is an approximation.

- Anonymous April 30, 2013 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More