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<int> 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<IEnumerable<int>> 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));
}
}
}