Description

You are playing the following Nim Game with your friend:

  • Initially, there is a heap of stones on the table.
  • You and your friend will alternate taking turns, and you go first.
  • On each turn, the person whose turn it is will remove 1 to 3 stones from the heap.
  • The one who removes the last stone is the winner.

Given n, the number of stones in the heap, return true if you can win the game assuming both you and your friend play optimally, otherwise return false.

Example 1:

  • Input: n = 4
  • Output: false
  • Explanation: These are the possible outcomes:
    1. You remove 1 stone. Your friend removes 3 stones, including the last stone. Your friend wins.
    2. You remove 2 stones. Your friend removes 2 stones, including the last stone. Your friend wins.
    3. You remove 3 stones. Your friend removes the last stone. Your friend wins.
    In all outcomes, your friend wins.

Example 2:

  • Input: n = 1
  • Output: true

Example 3:

  • Input: n = 2
  • Output: true

Constraints:

  • 1 <= n <= 231 - 1

💡 Hint 1:
If there are 5 stones in the heap, could you figure out a way to remove the stones such that you will always be the winner?

Submitted Code

class Solution(object):
    def canWinNim(self, n):
        """
        :type n: int
        :rtype: bool
        """
        return n % 4 != 0

Runtime: 0 ms | Beats 100.00%
Memory: *12.43** MB | Beats 49.30%

내가 돌을 가져간 뒤 남은 돌의 개수가 1, 2 또는 3일 경우 무조건 지게 되고, 반대로 4개이면 상대방이 몇 개를 가져가든 그 다음 턴에 내가 남은 돌을 끝낼 수 있다. 때문에 필승법은 항상 내 턴이 끝난 후 남은 돌이 4의 배수가 되도록 유도하는 것이다. 더 간단히 하면 시작 시 돌의 개수가 4의 배수일 때는 상대방도 최적의 전략을 사용하기 때문에 질 수밖에 없다.

n = 10

stone    me        friend
10       2(n%4)
8                  3
5        1(4-3)        
4                  2
2        2

return True

Other Solutions

1st

from functools import lru_cache

@lru_cache(None)
def canWinNim(n):
    if n <= 3:
        return True
    return not (canWinNim(n - 1) and canWinNim(n - 2) and canWinNim(n - 3))

리트코드에서 실제로 테스트하면 functools 모듈에서 lru_cache를 가져올 수 없어서 통과할 수 없었지만, 재귀 호출을 이용한 방법이어서 참고해봤다.

Leave a comment