1
+ """
2
+ Project Euler Problem 301: https://projecteuler.net/problem=301
3
+
4
+ Problem Statement:
5
+ Nim is a game played with heaps of stones, where two players take
6
+ it in turn to remove any number of stones from any heap until no stones remain.
7
+
8
+ We'll consider the three-heap normal-play version of
9
+ Nim, which works as follows:
10
+ - At the start of the game there are three heaps of stones.
11
+ - On each player's turn, the player may remove any positive
12
+ number of stones from any single heap.
13
+ - The first player unable to move (because no stones remain) loses.
14
+
15
+ If (n1, n2, n3) indicates a Nim position consisting of heaps of size
16
+ n1, n2, and n3, then there is a simple function, which you may look up
17
+ or attempt to deduce for yourself, X(n1, n2, n3) that returns:
18
+ - zero if, with perfect strategy, the player about to
19
+ move will eventually lose; or
20
+ - non-zero if, with perfect strategy, the player about
21
+ to move will eventually win.
22
+
23
+ For example X(1,2,3) = 0 because, no matter what the current player does,
24
+ the opponent can respond with a move that leaves two heaps of equal size,
25
+ at which point every move by the current player can be mirrored by the
26
+ opponent until no stones remain; so the current player loses. To illustrate:
27
+ - current player moves to (1,2,1)
28
+ - opponent moves to (1,0,1)
29
+ - current player moves to (0,0,1)
30
+ - opponent moves to (0,0,0), and so wins.
31
+
32
+ For how many positive integers n <= 2^30 does X(n,2n,3n) = 0?
33
+ """
34
+
35
+ def X (n : int , n2 : int , n3 : int ) -> int :
36
+ """
37
+ Returns:
38
+ - zero if, with perfect strategy, the player about to
39
+ move will eventually lose; or
40
+ - non-zero if, with perfect strategy, the player about
41
+ to move will eventually win.
42
+
43
+ >>> X(1)
44
+ 0
45
+ >>> X(3)
46
+ 12
47
+ >>> X(8)
48
+ 0
49
+ >>> X(11)
50
+ 60
51
+ >>> X(1000)
52
+ 3968
53
+ """
54
+ return n ^ n2 ^ n3
55
+
56
+ def solution (n : int = 2 ** 30 ) -> int :
57
+ """
58
+ For a given integer n <= 2^30, returns how many Nim games are lost.
59
+ >>> solution(2)
60
+ 2
61
+ >>> solution(10)
62
+ 144
63
+ >>> solution(30)
64
+ 2178309
65
+ """
66
+ lossCount = 0
67
+ for i in range (1 ,n + 1 ):
68
+ if X (i ,2 * i ,3 * i ) == 0 :
69
+ lossCount += 1
70
+
71
+ return lossCount
72
+
73
+ if __name__ == "__main__" :
74
+ print (solution ())
0 commit comments