Editor

Take-Away With Many Piles

#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).

Examples

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.

Constraints

  • 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.

Fastest solvers

Leaderboard

First solves only, ranked by stars and then time.