#495 · Games and puzzles · Expert · 270 XP · about 55 min
Two players face several piles of stones and take turns. On each turn a player picks one pile and removes exactly t stones from it, where t is one of the numbers in the list takes and the pile has at least t stones. The player who cannot make a move loses.
Write winning_moves(piles, takes) that returns how many different first moves let the first player win, as long as they keep playing perfectly afterwards, whatever the opponent does. A move is a choice of a pile and an amount, so taking 2 stones from pile 0 and taking 2 stones from pile 1 are two different moves, even if the two piles are the same size. Return 0 when the first player loses whatever they do (or has no move at all).
winning_moves([5], [1, 2]) # returns 1 winning_moves([3], [1, 2]) # returns 0 winning_moves([4, 4], [1, 3, 4]) # returns 0 winning_moves([9, 6, 2], [1, 3, 4]) # returns 2
With one pile of 3 and takes of 1 or 2, whatever you take, your opponent takes the rest and you are stuck, so 3 is a losing pile. From 5, taking 2 leaves your opponent that losing 3, so there is exactly 1 winning move. With two equal piles, the second player can copy every move on the other pile and is never stuck first.
piles has 1 to 1,000 piles, each with 0 to 10**18 stones.takes has 1 to 6 different numbers, each from 1 to 20.First solves only, ranked by stars and then time.