Linkedin Interview Question for Senior Software Development Engineers


Team: Mobile
Country: United States
Interview Type: Phone Interview




Comment hidden because of low score. Click to expand.
1
of 3 vote

package Linkedin;

import java.util.List;
import java.util.ArrayList;

public class The100Game{
	List<Integer> pool;
	int raceTo;
	
	The100Game(int poolMax, int finalSum){
		if(finalSum > ((poolMax*poolMax + poolMax)/2)){
			throw new IllegalArgumentException("Expected sum cannot be achieved!");
		}
		
		raceTo = finalSum;
		pool = new ArrayList<Integer>();
		
		for(int i=0;i<poolMax;i++)
			pool.add(i+1);
	}
	
	boolean canIWin(){
		int turns = 0;
		while(raceTo>0){
			turns++;
			System.out.println("Player"+( (turns%2==0)?"2":"1" )+" ==> "+pickANumber()+"   == Remaining ["+raceTo+"]");
		}
		return (turns%2==1);
	}
	
	int pickANumber(){
		int leastMax = -1;
		int len = pool.size();
		for(int i=len-1;i>=0;i--){
			int tmp = pool.get(i);
			if(tmp>=raceTo){
				pool.remove(i);
				raceTo -= tmp;
				return tmp;	
			}else{
				if(leastMax > 0){
					if(tmp < leastMax){
						pool.remove(i);
						raceTo -= tmp;
						return tmp;
					}else{
						continue;
					}
				}	
					
				if(i-1 >= 0) {
					if(tmp+pool.get(i-1) < raceTo){
						pool.remove(i);
						raceTo -= tmp;
						return tmp;
					}else{
						leastMax = raceTo - tmp;
						i--;
						continue;
					}
				}else{
					pool.remove(i);
					raceTo -= tmp;
					return tmp;
				}
			}
		}
		
		int tmp = pool.get(pool.size()-1);
		pool.remove(pool.size()-1);
		raceTo -= tmp;
		return tmp;
	}
	
	public static void main(String[] args){
		The100Game game = new The100Game(15, 100);
		System.out.println("\nPlayer-"+(game.canIWin()?"1":"2")+" wins!");
	}
}

- Harsha September 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

I pick the best number for both players in every turn. Can any of you review my code please ?

- Harsha September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
-2
of 2 votes

Your code does not work for the simple cases canIWin(1, 1) and canIWin(2, 1). It returns true, but the correct answer is false.

- gudujarlson September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@gudujarlson : is this an automated reply or what ?? The code does work for the case (2,1) and (1,1) definitely.

The code does work for canIWin(1,1)

Player1 ==> 1   == Remaining [0]
Player-1 wins!

For canIWin(2, 1)

Player1 ==> 2   == Remaining [-1]

Player-1 wins!

- Ahsrah September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

My bad. I read the problem statement backwards. I thought the goal of the game was to NOT be the player to reach the desired total. I switched my code and tests around and now both your solution and my solution pass all tests except for 15,100 where mine returns true but yours returns false. I don't have time to analyze it further at the moment.

- gudujarlson September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 2 votes

Our solutions do not agree for the input 5,12. Mine returns true and your returns false. I believe mine is correct. If player 1 starts with 3 they can always win.

3,5,4 win
3,4,5 win
3,2,1,4,5 win
3,2,1,5,4 win
3,1,2,4,5 win
3,1,2,5,4 win

- gudujarlson September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Does it have to be this complex? Question was asked in Phone interview!!

Inspired from form solution posted by @Harsha.

1. Is raceTo less than equal to Max num available in Pool
2. Is difference between raceTo and Max num available in Pool greater than 2nd largest number? If yes pick Max number else pick smallest number.

This is python code for pickNum everything else is same as @Harsha's code.

def __pick_num(self, race_to):

		if self.__pool[-1] >= race_to:
			return self.__pool.pop()
		
		if race_to - self.__pool[-1] > self.__pool[-2]:
			return self.__pool.pop()
		else:
			return self.__pool.pop(0)

I might be missing something obvious. Let me know if there are any cases which this cannot handle.

- Saurabh September 18, 2016 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Answer:
Please try to solve this by yourself before seeing my solution in 1/2 hour only.

Screwed up this one big time. No help came from interviewer for proceeding on the solution. In the interview, I was thinking that it may have some recursive / dynamic programming solution. I guess, I was stumped to even grasp it at first.

Tried to discuss an example with interviewer.
// canIWin(2, 3)

I think I got confused by his inputs, as he suggested that optimum play by Player A not necessarily means that he will win if he chooses the highest available number.

Anyhow, I stumped and couldn't proceed much. Horrific.

Solution: Now i gave myself half an hour to solve this question by myself after the interview. Here is my approach.
According to me, The optimal play from player A will always have a first advantage of selecting the largest number
So e.g, for N = 10 , he may select 10, 8 , 6 , 4

Boolean canIWin(int maxChoosableInteger, int desiredTotal) {
  // Implementation here.

	int is_even=false;
	int optimumPossibleSum = 0;
	boolean status = false;

	int n = (maxChoosableInteger- 2)/2 + 1;

	if ( (maxChoosableInteger % 2) == 0 )
	{
		isEven = true;
	}

	if ( isEven )	
	{
		
		optimumPossibleSum = n * ( n + 1 );
	}

	else
	{
		optimumPossibleSum = n * n;
	}

	if ( optimumPossibleSum >= desiredTotal )
		status = true;

	return status;

}

- you.win September 24, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Your code does not work the cases 3,2, 3,3, and 3,5. It returns false for each, but the correct answer is true for each. Player 1 can win with perfect play in each case.

- gudujarlson September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I think the problem is that you assumed something without proof. Why is it that picking the max number first would be optimal?

- Anonymous October 18, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

I think this can be solved with a simple recursive algorithm. A cursory analysis suggests that the upper bound on complexity is O(n!) where n is the max choosable integer.

boolean canIWin(int maxChoosableInteger, int desiredTotal) {
		int[] numbers = new int[maxChoosableInteger];
		for (int i = 0; i < maxChoosableInteger; ++i) {
			numbers[i] = i + 1;
		}
		return canWin(numbers, desiredTotal);
	}

	boolean canWin(int[] numbers, int desiredTotal) {
		for(int i = 0; i < numbers.length; ++i) {
			int newTotal = desiredTotal - numbers[i];
			if (newTotal > 0) {
				if (!canWin(remove(numbers, i), newTotal)) {
					return true;
				}
			}
		}
		return false;
	}

	int[] remove(int[] a, int k) {
		int[] b = new int[a.length-1];
		for (int i = 0, j = 0; i < a.length; i++) {
			if (i != k) {
				b[j++] = a[i];
			}
		}
		return b;
	}

- gudujarlson September 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Quick note: my algorithm is based on the logic that I can always win with perfect play if my opponent can not always win with perfect play starting on the next move.

- gudujarlson September 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I misread the problem statement. I thought the goal was to NOT reach the desired total. Here is the fixed code. I also added a support for the special case that neither player can win.

boolean canIWin(int maxChoosableInteger, int desiredTotal) {
		if ((maxChoosableInteger*maxChoosableInteger + maxChoosableInteger) / 2 < desiredTotal) {
			// Neither player can win.
			return false;
		}
		int[] numbers = new int[maxChoosableInteger];
		for (int i = 0; i < maxChoosableInteger; ++i) {
			numbers[i] = i + 1;
		}
		return canWin(numbers, desiredTotal);
	}

	boolean canWin(int[] numbers, int desiredTotal) {
		if (desiredTotal <= 0) {
			return false;
		}
		for(int i = 0; i < numbers.length; ++i) {
			int newTotal = desiredTotal - numbers[i];
			if (!canWin(remove(numbers, i), newTotal)) {
				return true;
			}
		}
		return false;
	}

	int[] remove(int[] a, int k) {
		int[] b = new int[a.length-1];
		for (int i = 0, j = 0; i < a.length; i++) {
			if (i != k) {
				b[j++] = a[i];
			}
		}
		return b;
	}

- gudujarlson September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

You're missing the case of actually winning in your for-loop:

if (newTotal <= 0) {
return true;
}

- shic September 20, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

You'd probably have to do some rather advanced game theory to come up on the spot with an algorithm that better than O(n!). Either way, it's pretty well known that choosing simply the maximum number is incorrect.

This should be solvable with the following, took me closer to an hour to get it to print some valid answers despite it being 15 lines:

def canIWin(integers, total=0, turn=0):
  possibilities = []
  for i in integers:
    if total + i >= 6: # 6 is the total sum the players are trying to get
      return turn % 2 # 0 if 1st player wins, 1 if second
    else:
      ints = integers[:]
      ints.remove(i)
      winnable = canIWin(ints, total + i, turn + 1)
      possibilities.append(winnable)
  if turn % 2 == 0:
    return min(possibilities)
  return max(possibilities)

print canIWin(range(1,5)) # give as argument the available numbers

- Anonymous September 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

im not actually sure about the first sentence anymore, it might be possible to recude the complexity of the above algorithm greatly just with simple memoization

- Anonymous September 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Yes, I think some simple memoization is possible. The brute force algo searches all permutations of the possible numbers, however some of these are redundant. For example, the permutation that starts with 1,2 will have the same result as a permutation that starts with 2,1. In both cases the next call to the canIWIn() function will have the same inputs and thus the same output. The complexity analysis requires some thought. My first impression is (n/2)!.

- gudujarlson September 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Actually, I think the complexity is way less than that, maybe even n*log(n).

- gudujarlson September 25, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

On third thought I think the complexity of the memoized algo would be 2^n because it has to visit all subsets in the worse case.

- gudujarlson September 26, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

yeah i ended up with 2^n on a third thought too, but that still better than a factorial complexity

- Anonymous September 27, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Can you explain what your'e doing?

- purpleshoes December 01, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

My solution is based on the assumption that both p1 and p2 are extremely smart and they will choose an optimal move to win whenever they have chance.

boolean canIWin(int maxChoosableInteger, int desiredTotal) { 
		
		boolean[] pool = new boolean[maxChoosableInteger];
		
		for(int i = 0; i<maxChoosableInteger; i++){
			pool[i] = true;
			if(canP1Win(i+1, desiredTotal, pool, true)) return true;
			pool[i] = false;
		}
		
		return false;
	}
	
	
	// Overall heuristics : canP1Win is a method that tells us whether by making this move p1 will win. 
	// and we assume both p1 and p2 are extremely smart and therefore will choose an optimal move to maximize their chances to win.
	
	// If the above statement is true, then the following is true:
	// 1. if p1 can find a way to win she will choose it
	// 2. if p2 can find a way to make p1 loose, she will choose it
	//   Therefore in order for p1 to win, such way must not exist.
	
	boolean canP1Win(int currentSum, int total, boolean[] pool, boolean isLastP1){
		
		//base case : someone did the final move, if it's p1 then she wins, otherwise she looses.
		if(currentSum >= total) return isLastP1;
		
		//recursion : game continues
		boolean isCurrentPlayerP1 = !isLastP1;
		for(int i = 0; i<pool.length; i++){
			
			if(pool[i]) continue;
			
			pool[i] = true;
			boolean p1CanWin = canP1Win(currentSum + (i+1), total, pool, isCurrentPlayerP1);
			
			//1. if p1 can find a way to win she will choose it
			if(isCurrentPlayerP1 && p1CanWin) return true;
			//2. if p2 can find a way to make p1 loose, she will choose it
			//   Therefore in order for p1 to win, such way must not exist.
			if(!isCurrentPlayerP1 && !p1CanWin) return false;
			
			// neither of the conditions above is satisfied, both player will try to pick another number that maximize their chances to win.
			pool[i] = false;
		}
		
		// player at this round has tried all possible moves:
		// 1.if it's p1's turn and she couldn't find any way to win, then she looses
		// 2.if it's p2's turn and she couldn't find any way to make p1 loose, p1 wins.
		return isCurrentPlayerP1? false : true;
	}

- aikqboy September 26, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Your code returns true for the case 3,4, but I believe the correct answer is false because no matter what player 1 starts with, player 2 can win.

1,3 loss
2,2 loss
3,1 loss

- gudujarlson September 30, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class pickNumber {
public static boolean canIWin (int maxNumber, int target) {
return canIWin(maxNumber, target, new int[2], 0, new boolean[maxNumber]);
}
public static boolean canIWin(int maxNumber, int target, int[] players, int times, boolean[] visited) {
int count = 0;
for(boolean b : visited) {
if(!b) count++;
}
if(count == 0) return false;
if(times % 2 == 0) {
for(int i = 1; i <= maxNumber; i++) {
if(!visited[i - 1]) {
visited[i - 1] = true;
players[0] += i;
if(players[0] >= target || canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[0] -= i;
}
}
}
else {
for(int i = 1; i <= maxNumber; i++) {
boolean b = false;
if(!visited[i - 1] && players[1] + i < target) {
b = true;
visited[i - 1] = true;
players[1] += i;
if(canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[1] -= i;
}
if(!b) return false;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(canIWin(3, 3));
System.out.println(canIWin(3, 4));
System.out.println(canIWin(3, 5));
System.out.println(canIWin(3, 6));
}
}

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

public class pickNumber {
public static boolean canIWin (int maxNumber, int target) {
return canIWin(maxNumber, target, new int[2], 0, new boolean[maxNumber]);
}
public static boolean canIWin(int maxNumber, int target, int[] players, int times, boolean[] visited) {
int count = 0;
for(boolean b : visited) {
if(!b) count++;
}
if(count == 0) return false;
if(times % 2 == 0) {
for(int i = 1; i <= maxNumber; i++) {
if(!visited[i - 1]) {
visited[i - 1] = true;
players[0] += i;
if(players[0] >= target || canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[0] -= i;
}
}
}
else {
for(int i = 1; i <= maxNumber; i++) {
boolean b = false;
if(!visited[i - 1] && players[1] + i < target) {
b = true;
visited[i - 1] = true;
players[1] += i;
if(canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[1] -= i;
}
if(!b) return false;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(canIWin(3, 3));
System.out.println(canIWin(3, 4));
System.out.println(canIWin(3, 5));
System.out.println(canIWin(3, 6));
}
}

- Xinlu September 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class pickNumber {
public static boolean canIWin (int maxNumber, int target) {
return canIWin(maxNumber, target, new int[2], 0, new boolean[maxNumber]);
}
public static boolean canIWin(int maxNumber, int target, int[] players, int times, boolean[] visited) {
int count = 0;
for(boolean b : visited) {
if(!b) count++;
}
if(count == 0) return false;
if(times % 2 == 0) {
for(int i = 1; i <= maxNumber; i++) {
if(!visited[i - 1]) {
visited[i - 1] = true;
players[0] += i;
if(players[0] >= target || canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[0] -= i;
}
}
}
else {
for(int i = 1; i <= maxNumber; i++) {
boolean b = false;
if(!visited[i - 1] && players[1] + i < target) {
b = true;
visited[i - 1] = true;
players[1] += i;
if(canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[1] -= i;
}
if(!b) return false;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(canIWin(3, 3));
System.out.println(canIWin(3, 4));
System.out.println(canIWin(3, 5));
System.out.println(canIWin(3, 6));
}
}

- Xinlu September 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class pickNumber {
public static boolean canIWin (int maxNumber, int target) {
return canIWin(maxNumber, target, new int[2], 0, new boolean[maxNumber]);
}
public static boolean canIWin(int maxNumber, int target, int[] players, int times, boolean[] visited) {
int count = 0;
for(boolean b : visited) {
if(!b) count++;
}
if(count == 0) return false;
if(times % 2 == 0) {
for(int i = 1; i <= maxNumber; i++) {
if(!visited[i - 1]) {
visited[i - 1] = true;
players[0] += i;
if(players[0] >= target || canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[0] -= i;
}
}
}
else {
for(int i = 1; i <= maxNumber; i++) {
boolean b = false;
if(!visited[i - 1] && players[1] + i < target) {
b = true;
visited[i - 1] = true;
players[1] += i;
if(canIWin(maxNumber, target, players, times + 1, visited)) return true;
visited[i - 1] = false;
players[1] -= i;
}
if(!b) return false;
}
}
return false;
}
public static void main(String[] args) {
System.out.println(canIWin(3, 3));
System.out.println(canIWin(3, 4));
System.out.println(canIWin(3, 5));
System.out.println(canIWin(3, 6));
}
}

- Xinlu September 30, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

A similar version is the "100 game": two players start from 0 and alternatively add a number from 1 to 10 to the sum. The player who reaches 100 wins. The winning strategy is to reach a number in which the digits are subsequent (e.g. 01, 12, 23, 34,...) and control the game by jumping through all the numbers of this sequence. Once reached 89, the opponent has lost (he can only tell numbers from 90 to 99, and the next answer can in any case be 100).

- pee October 01, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

What about such approach:
As the main constraint is a programmer efficiency, we could just estimate for an each choice of the next number the probability of win, i.e. count the number of ways through recursion leading to our win (A) and to our fail (B). The estimation would be A/(A+B). So the optimal strategy by definition is to choose the next number with the highest probability of winning. Then we just calculate who will win with such strategy (who will pick the last possible number) and return True if the winner is the first player.
Basically it's just super-mega-bruteforce with factorial complexity but it's relatively easy to code. Just a thought, maybe will code it some time. :)

- andreytim October 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Wouldn't the player 1 always win if he picks the highest available no in the pool. Am i missing something here?

- Ands October 27, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

Nope. Take 5,12 for example. Player 1 can always win if they start with 3.

3,5,4 win
3,4,5 win
3,2,1,4,5 win
3,2,1,5,4 win
3,1,2,4,5 win
3,1,2,5,4 win

- gudujarlson October 27, 2014 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

public boolean canIWin(int maxChoosableInteger, int desiredTotal) {

		boolean candidates[] = new boolean[maxChoosableInteger];
		for (int i = 0; i < candidates.length; ++i) {
			candidates[i] = true;
		}

		return canWinHelper(candidates, desiredTotal);
	}

	private boolean canWinHelper(boolean candidates[], int total) {

		if (total <= 0) {
			return false;
		}

		boolean result = false;
		for (int i = 0; i < candidates.length; ++i) {
			// I pick, just win one
			if (candidates[i]) {
				candidates[i] = false;
				int curTotal = total - i - 1;
				if(curTotal == 0) {
					System.out.println("return");
					return true;
				}
				// the other player pick: any possibility
				// need to win all these
				boolean cur = true;
				for(int j = 0; j < candidates.length; ++j) {
					if(candidates[j]) {
					
						candidates[j] = false;
						cur = cur && canWinHelper(candidates, curTotal - j - 1);
						candidates[j] = true;
						
					}
				}
				result = result || cur;
				candidates[i] = true;
			}
		}
		return result;
	}

- Carotene November 19, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

In this problem three results are possible:
(1) First player wins.
(2) Second player wins.
(3) No winner.

Lets define two recursive functions:
(1) CanWin(int destNumber)
(2) IsLost(int destNumber)

Also because numbers in range 1-N are not re-usable we should hold boolean array with states. From here implementation in very simple. I coded it in C++.

bool CanWin(int destNumber);
bool IsLost(int destNumber);

vector<bool> isAvailable;
bool CanIWin(int maxChoosableInteger, int desiredTotal)
{
	//Initially all integers are available.
	isAvailable.resize(maxChoosableInteger, true);
	return CanWin(desiredTotal);
}

bool CanWin(int destNumber)
{
	for (int i=isAvailable.size()-1; i>=0; i--)
	{
		int num = i+1;

		if (!isAvailable.at(i))
			continue;

		if (destNumber <= num)
			return true;

		isAvailable.at(i) = false;
		bool isOpponentLost = IsLost(destNumber - num);
		isAvailable.at(i) = true;

		if (isOpponentLost)
			return true;
	}

	return false;
}

bool IsLost(int destNumber)
{
	for (int i=isAvailable.size()-1; i>=0; i--)
	{
		int num = i+1;

		if (!isAvailable.at(i))
			continue;

		if (destNumber <= num)
			return false;

		isAvailable.at(i) = false;
		bool canOpponentWin = CanWin(destNumber - num);
		isAvailable.at(i) = true;

		if (canOpponentWin)
			return true;
	}

	return false;
}

- pavel.kogan January 11, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Is this correct simple solution? Please help explain

#include <iostream>
using namespace std;


bool canIWin(int maxChoosableInteger, int desiredTotal);

int main() {
	// your code goes here
	bool result = false;
	

	cout<<"canIwin(3,2) : "<<canIWin(3, 2)<<endl;
	cout<<"canIwin(3,3) : "<<canIWin(3, 3)<<endl;
	cout<<"canIwin(3,5) : "<<canIWin(3, 5)<<endl;
	
	return 0;
}


bool canIWin(int maxChoosableInteger, int desiredTotal) {
  // Implementation here.

	bool isEven=false;
	int optimumPossibleSum = 0;
	bool status = false;

	int n = (maxChoosableInteger + 1 - 2)/2 + 1;

	if ( (maxChoosableInteger % 2) == 0 )
	{
		isEven = true;
	}

	if ( isEven )	
	{
		
		optimumPossibleSum = n * ( n + 1 );
	}

	else
	{
		optimumPossibleSum = n * n;
	}

	if ( optimumPossibleSum >= desiredTotal )
		status = true;

	return status;

}

- youin January 27, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

In 100 game, the player add number from 1... 10. the first player can force to win by always be the one reach number 1, 12, 23, 34, 45, 56, 67, 78, 89, 100.
The first player can pick 1 first. and whatever number n second player picked, the first player always pick 11-n next. That will guarantee first player to win.
So the function canIWin() shall return true as long as the 1...n can sum up to desired total.

In the modified game that number can not be reused. then there is not guarantee first player to win. But there still strategy allow the first player to win in OPTIMAL play.
for example, 1...15 and desired total is 100. In an optimal play, the first player can be the one reach 4, 20, 36, 52, 68, 84, 100.
the first player can pick 4 first. And then second player always pick the number n satisfy (n != 8 && n != 12) in an optimal play. Which give a chance for first player to pick 16-n next and eventually first player win.
for this game canIWin() can return true when following 2 conditions are satisfied:
1. 1..n can sum up to desire total.
2. desire total / (1+n) < (n/2 - 1).
after first player pick the necessary number (4), there is enough pairs (n and 16-n) left to build the desire total.

- ABCD February 11, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is basically brute force, but perhaps the algorithm is clear.

using System;
using System.Collections.Generic;

namespace SumGame
{
	class Program
	{
		static void Main()
		{
		}
	}

	static class WinComputer
	{
		static bool canIWin(int maxChoice, int winTotal)
		{
			Scenario.maxChoice = maxChoice;
			Scenario.winTotal = winTotal;

			return recursiveCanPlayerAWin(new Scenario(0,0));
		}

		static bool recursiveCanPlayerAWin(Scenario scenario)
		{
			if(scenario.PlayerAHasWinningChoice())
				return true;

			for(int i = 0; i <= maxChoice; i++)
			{
				if(scenario.IsInvalidChoice(i))
					continue;

				scenario.PlayerAChoose(i);

				if(scenario.PlayerBHasWinningChoice())
					return false;

				for(int j = 0; j <= maxChoice; j++)
				{
					if(scenario.IsInvalidChoice(j))
						continue;

					Scenario branch = scenario.Clone();
					branch.PlayerBChoose(j);
					scenario.PlayerAHasWinningStrategy |= recursiveCanPlayerAWin(branch);
				}
			}

			return scenario.PlayerAHasWinningStrategy;
		}
	}

	class Scenario
	{
		public int PlayerATotal;
		public int PlayerBTotal;
		public HashSet<int> InvalidChoices;
		public bool PlayerAHasWinningStrategy;

		private static int maxChoice;
		private static int winTotal;

		public Scenario(int a, int b, HashSet<int> h = null)
		{
			PlayerATotal = a;
			PlayerBTotal = b;
			InvalidChoices = h ?? new HashSet<int>();
			PlayerAHasWinningStrategy = false;
		}

		public Scenario Clone()
		{
			return new Scenario(PlayerATotal, PlayerBTotal, InvalidChoices);
		}

		public void PlayerAChoose(int x)
		{
			PlayerATotal += x;
			InvalidChoices.Add(x);
		}

		public void PlayerBChoose(int x)
		{
			PlayerBTotal += x;
			InvalidChoices.Add(x);
		}

		public bool PlayerAHasWinningChoice()
		{
			return PlayerHasWinningChoice(PlayerATotal);
		}

		public bool PlayerBHasWinningChoice()
		{
			return PlayerHasWinningChoice(PlayerBTotal);
		}

		public bool IsInvalidChoice(int x)
		{
			return InvalidChoices.Contains(x);
		}

		public bool PlayerHasWinningChoice(int playerTotal)
		{
			for(int i = 0; i <= Scenario.maxChoice; i++)
			{
				if(!IsInvalidChoice(i) && (playerTotal + i >= Scenario.winTotal))
					return true;
			}

			return false;
		}
	}
}

- jayflo March 29, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sorry for multiple posts...if someone can remove the others, please do!

Also, after thinking a little longer, there is symmetry within the sub-problems and you would be able to cache their solution. For instance, if the series of choices (1,2,3,4) would produce a "game" with the same "state" as (3,2,1,4), (1,4,3,2), and (3,4,1,2). Then change

scenario.PlayerAHasWinningStrategy |= recursiveCanPlayerAWin(branch);

to

if(ScenarioCache.HasDetermined(branch))
    scenario.PlayerAHasWinningStrategy = ScenarioCache.GetOutcome(branch);
else
    scenario.PlayerAHasWinningStrategy |= recursiveCanPlayerAWin(branch);

The ScenarioCache is just a HashSet whose members are Scenario instances. You must override Equals and GetHashCode so that two scenarios are equivalent only when PlayerATotal, PlayerBTotal and InvalidChoices are all equal (by value). The HasDeteremined(branch) method simply checks if the dictionary has branch as a member (as determined by Equals). The GetOutcome(branch) method simply returns PlayerAHasWinningStrategy for that member.

- jarflores March 29, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is basically brute force, but the algorithm should be clear.

using System;
using System.Collections.Generic;

namespace SumGame
{
	class Program
	{
		static void Main()
		{
		}
	}

	static class WinComputer
	{
		static bool canIWin(int maxChoice, int winTotal)
		{
			Scenario.maxChoice = maxChoice;
			Scenario.winTotal = winTotal;

			return recursiveCanPlayerAWin(new Scenario(0,0));
		}

		static bool recursiveCanPlayerAWin(Scenario scenario)
		{
			if(scenario.PlayerAHasWinningChoice())
				return true;

			for(int i = 0; i <= maxChoice; i++)
			{
				if(scenario.IsInvalidChoice(i))
					continue;

				scenario.PlayerAChoose(i);

				if(scenario.PlayerBHasWinningChoice())
					return false;

				for(int j = 0; j <= maxChoice; j++)
				{
					if(scenario.IsInvalidChoice(j))
						continue;

					Scenario branch = scenario.Clone();
					branch.PlayerBChoose(j);
					scenario.PlayerAHasWinningStrategy |= recursiveCanPlayerAWin(branch);
				}
			}

			return scenario.PlayerAHasWinningStrategy;
		}
	}

	class Scenario
	{
		public int PlayerATotal;
		public int PlayerBTotal;
		public HashSet<int> InvalidChoices;
		public bool PlayerAHasWinningStrategy;

		private static int maxChoice;
		private static int winTotal;

		public Scenario(int a, int b, HashSet<int> h = null)
		{
			PlayerATotal = a;
			PlayerBTotal = b;
			InvalidChoices = h ?? new HashSet<int>();
			PlayerAHasWinningStrategy = false;
		}

		public Scenario Clone()
		{
			return new Scenario(PlayerATotal, PlayerBTotal, InvalidChoices);
		}

		public void PlayerAChoose(int x)
		{
			PlayerATotal += x;
			InvalidChoices.Add(x);
		}

		public void PlayerBChoose(int x)
		{
			PlayerBTotal += x;
			InvalidChoices.Add(x);
		}

		public bool PlayerAHasWinningChoice()
		{
			return PlayerHasWinningChoice(PlayerATotal);
		}

		public bool PlayerBHasWinningChoice()
		{
			return PlayerHasWinningChoice(PlayerBTotal);
		}

		public bool IsInvalidChoice(int x)
		{
			return InvalidChoices.Contains(x);
		}

		public bool PlayerHasWinningChoice(int playerTotal)
		{
			for(int i = 0; i <= Scenario.maxChoice; i++)
			{
				if(!IsInvalidChoice(i) && (playerTotal + i >= Scenario.winTotal))
					return true;
			}

			return false;
		}
	}
}

- jayflo March 29, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

This is basically brute force, but the algorithm should be clear.

using System;
using System.Collections.Generic;

namespace SumGame
{
	class Program
	{
		static void Main()
		{
		}
	}

	static class WinComputer
	{
		static bool canIWin(int maxChoice, int winTotal)
		{
			Scenario.maxChoice = maxChoice;
			Scenario.winTotal = winTotal;

			return recursiveCanPlayerAWin(new Scenario(0,0));
		}

		static bool recursiveCanPlayerAWin(Scenario scenario)
		{
			if(scenario.PlayerAHasWinningChoice())
				return true;

			for(int i = 0; i <= maxChoice; i++)
			{
				if(scenario.IsInvalidChoice(i))
					continue;

				scenario.PlayerAChoose(i);

				if(scenario.PlayerBHasWinningChoice())
					return false;

				for(int j = 0; j <= maxChoice; j++)
				{
					if(scenario.IsInvalidChoice(j))
						continue;

					Scenario branch = scenario.Clone();
					branch.PlayerBChoose(j);
					scenario.PlayerAHasWinningStrategy |= recursiveCanPlayerAWin(branch);
				}
			}

			return scenario.PlayerAHasWinningStrategy;
		}
	}

	class Scenario
	{
		public int PlayerATotal;
		public int PlayerBTotal;
		public HashSet<int> InvalidChoices;
		public bool PlayerAHasWinningStrategy;

		private static int maxChoice;
		private static int winTotal;

		public Scenario(int a, int b, HashSet<int> h = null)
		{
			PlayerATotal = a;
			PlayerBTotal = b;
			InvalidChoices = h ?? new HashSet<int>();
			PlayerAHasWinningStrategy = false;
		}

		public Scenario Clone()
		{
			return new Scenario(PlayerATotal, PlayerBTotal, InvalidChoices);
		}

		public void PlayerAChoose(int x)
		{
			PlayerATotal += x;
			InvalidChoices.Add(x);
		}

		public void PlayerBChoose(int x)
		{
			PlayerBTotal += x;
			InvalidChoices.Add(x);
		}

		public bool PlayerAHasWinningChoice()
		{
			return PlayerHasWinningChoice(PlayerATotal);
		}

		public bool PlayerBHasWinningChoice()
		{
			return PlayerHasWinningChoice(PlayerBTotal);
		}

		public bool IsInvalidChoice(int x)
		{
			return InvalidChoices.Contains(x);
		}

		public bool PlayerHasWinningChoice(int playerTotal)
		{
			for(int i = 0; i <= Scenario.maxChoice; i++)
			{
				if(!IsInvalidChoice(i) && (playerTotal + i >= Scenario.winTotal))
					return true;
			}

			return false;
		}
	}
}

- jarflores March 29, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

woops

- jarflores March 29, 2015 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Bool canwin(int n, int Max)
{
int m = n+1;
int rem = max%m;

if (rem == 0) {
// if m is odd and rem is 0, then we are loosing for sure..
if (m &1 )
return false;
// Rem is 0 but m is even, then we are winning.
return true;
}

if (rem <= (m+1)/2)
return true;

return false;
}

- Punit July 01, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Bool canwin(int n, int Max)
{
	int m = n+1;
	int rem = max%m;

	if (rem == 0) {
		// if m is odd and rem is 0, then we are loosing for sure..
		if (m &1 )
			return false;
		// Rem is 0 but m is even, then we are winning.
		return true;
	}

           if (rem <= (m+1)/2)
		return true;

	return false;
}

- Punit July 01, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

- Punit July 01, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Bool canwin(int n, int Max)
{
	int m = n+1;
	int rem = max%m;

	if (rem == 0) {
		// if m is odd and rem is 0, then we are loosing for sure..
		if (m &1 )
			return false;
		// Rem is 0 but m is even, then we are winning.
		return true;
	}

           if (rem <= (m+1)/2)
		return true;

	return false;
}

- Punit July 01, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Boolean canIWin(int maxChoosableInteger, int desiredTotal) { 
    
   return canIWin(max, -1, desiredTOtal, true);

}


canIWin(max, chosen, desired, isPlayerOne){

    for(int j = 1 ; j <= max; j++)
        if (j != chosen && j>=desired)
            return isPlayerOne;
    
    boolean result = false;
    for(int i = 1; i <= max; i++)
        if (i != chosen && desired -i > 0)
            result = result || canIWin(max, i, desiredTOtal-i, !isPlayerOne);
        
    return result;
    
}

- Anonymous September 28, 2015 | Flag Reply
Comment hidden because of low score. Click to expand.
-1
of 1 vote

static boolean canIWin(int max, int total) {
		while (total > 0) {
		  	if (max <= 0) return false;
		  	total -=  max;
		  	max -= 2;
		}
		return true;
	}

- jack September 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 2 vote

while(number){
number = number % maxChoosableInteger;
if(number.ischoosable()){ // This has to remove the number once its got choosen
player.value =- number;
if(player.value<=0)
return player;
}
remove number;
}

- hprem991 September 25, 2014 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

what does this have any thing to do with this question ??

- you.win September 28, 2014 | 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