using System; using System.Collections; using System.Collections.Generic; using System.Linq; public class Test { enum Player { None = -1, FirstPlayer = 0, SecondPlayer = 1 }; public static bool CheckWin(int n, IEnumerable coinSequence) { if (coinSequence == null || coinSequence.Count() != 2 * n) throw new ArgumentException("coinSequence size must be equal 2*n"); var forcePlayer = Player.None; var currentPlayer = Player.None; var playerCoins = new int[2] { n, 0 }; var playerMoved = new int[2] { 0, 0 }; var coinsOnDesk = 0; foreach (var coin in coinSequence) { currentPlayer = (Player)(coin == 1 ? 0 : 1); // force player { if (playerMoved[(int)currentPlayer] > n) { switch (currentPlayer) { case Player.FirstPlayer: forcePlayer = Player.SecondPlayer; break; case Player.SecondPlayer: forcePlayer = Player.FirstPlayer; break; default: throw new Exception("Alg fail"); break; } } if (forcePlayer != Player.None) currentPlayer = forcePlayer; } switch (currentPlayer) { case Player.FirstPlayer: if (playerCoins[0] != 0) { playerCoins[0]--; coinsOnDesk++; } break; case Player.SecondPlayer: if (coinsOnDesk != 0) { coinsOnDesk--; playerCoins[1]++; } break; default: throw new Exception("Alg fail"); break; } playerMoved[(int)currentPlayer]++; } return (playerCoins[1] == n); } public static IEnumerable> GenerateCoins(int n) { if (n == 1) { yield return new int[] { 1 }; yield return new int[] { 2 }; yield break; } var smallerVariants = GenerateCoins(n - 1); foreach (var smallerVariant in smallerVariants) { yield return smallerVariant.Concat(new int[] { 1 }); yield return smallerVariant.Concat(new int[] { 2 }); } yield break; } public static int CountWinsSequences(int n) { return GenerateCoins(2 * n).Count(coinSequence => CheckWin(n, coinSequence)); } public static void Main() { for (int n = 1; n <= 5; n++) { Console.WriteLine("n = {0}, wins = {1}", n, CountWinsSequences(n)); } } }