Problem:
ポーカー

ポーカーの手札データを読み込んで、それぞれについてその役を出力するプログラムを作成してください。ただし、この問題では、以下のルールに従います。

ポーカーはトランプ 5 枚で行う競技です。

同じ数字のカードは 5 枚以上ありません。

ジョーカーは無いものとします。

以下のポーカーの役だけを考えるものとします。(番号が大きいほど役が高くなります。)

役なし(以下に挙げるどれにも当てはまらない)

ワンペア（2 枚の同じ数字のカードが1 組ある）

ツーペア（2 枚の同じ数字のカードが2 組ある）

スリーカード（3 枚の同じ数字のカードが1 組ある）

ストレート（5 枚のカードの数字が連続している）

ただし、A を含むストレートの場合、A で終わる並びもストレートとします。つまり、A を含むストレート
は、A 2 3 4 5 　と　10 J Q K A 　の２種類です。J Q K A 2 などのように、A をまたぐ並び
はストレートではありません。（この場合、「役なし」になります）。

フルハウス（3 枚の同じ数字のカードが1 組と、残りの2 枚が同じ数字のカード）

フォーカード（4 枚の同じ数字のカードが1 組ある）

Input

入力は複数のデータセットからなります。各データセットは以下の形式で与えられます。

手札1,手札2,手札3,手札4,手札5

手札は、トランプのJ(ジャック) を11、Q(クイーン) を12、K(キング) を13、A（エース）を 1、その他はそれぞれの数字で表すこととします。

データセットの数は 50 を超えません。

Output

データセットごとに、手札によってできる最も高い役をひとつ出力してください。役の表記については出力例に従ってください。

Sample Input

1,2,3,4,1
2,3,2,3,12
12,13,11,12,12
7,6,7,6,7
3,3,2,3,3
6,7,8,9,10
11,12,10,1,13
11,12,13,1,2

Output for the Sample Input

one pair
two pair
three card
full house
four card
straight
straight
null

3 3 2 3 3 という手札であったときは、two pair ではなく four card です。

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AOJ0038
{
    class Program
    {
        static void Main()
        {
            foreach (var hand in ReadHands())
            {
                switch (HandValidator.Validate(hand))
                {
                    case HandValidator.HandType.Null:
                        Console.WriteLine("null");
                        break;
                    case HandValidator.HandType.OnePair:
                        Console.WriteLine("one pair");
                        break;
                    case HandValidator.HandType.TwoPair:
                        Console.WriteLine("two pair");
                        break;
                    case HandValidator.HandType.ThreeCard:
                        Console.WriteLine("three card");
                        break;
                    case HandValidator.HandType.Straight:
                        Console.WriteLine("straight");
                        break;
                    case HandValidator.HandType.FullHouse:
                        Console.WriteLine("full house");
                        break;
                    case HandValidator.HandType.FourCard:
                        Console.WriteLine("four card");
                        break;
                }
            }
        }

        public static IEnumerable<int[]> ReadHands()
        {
            string line;
            while ((line = Console.ReadLine()) != null)
            {
                yield return line.Split(',').Select(int.Parse).ToArray();
            }
        }
    }

    public static class HandValidator
    {
        public static HandType Validate(int[] hand)
        {
            var handD = new Dictionary<int, int>();
            foreach (var card in hand)
            {
                if (handD.ContainsKey(card))
                {
                    handD[card]++;
                }
                else
                {
                    handD[card] = 1;
                }
            }

            return Validate(handD);
        }

        public static HandType Validate(Dictionary<int, int> hand)
        {
            if (FourCard(hand))
            {
                return HandType.FourCard;
            }
            if (FullHouse(hand))
            {
                return HandType.FullHouse;
            }
            if (Straight(hand))
            {
                return HandType.Straight;
            }
            if (ThreeCard(hand))
            {
                return HandType.ThreeCard;
            }
            if (TwoPair(hand))
            {
                return HandType.TwoPair;
            }
            if (OnePair(hand))
            {
                return HandType.OnePair;
            }
            return HandType.Null;
        }

        private static bool OnePair(Dictionary<int, int> hand)
        {
            return hand.Any(cardSet => cardSet.Value == 2);
        }

        private static bool TwoPair(Dictionary<int, int> hand)
        {
            return hand.Count(cardSet => cardSet.Value == 2) == 2;
        }

        private static bool ThreeCard(Dictionary<int, int> hand)
        {
            return hand.Any(cardSet => cardSet.Value == 3);
        }

        private static bool Straight(Dictionary<int, int> hand)
        {
            if (hand.Count() != 5) return false;
            var sortedHand = from pair in hand
                             orderby pair.Key
                             select pair.Key;

            return (from s in Enumerable.Range(1, 9)
                    let st = Enumerable.Range(s, 5)
                    where st.SequenceEqual(sortedHand)
                    select 0).Any() || sortedHand.SequenceEqual(new[] {1, 10, 11, 12, 13});
        }

        private static bool FullHouse(Dictionary<int, int> hand)
        {
            return OnePair(hand) && ThreeCard(hand);

        }

        private static bool FourCard(Dictionary<int, int> hand)
        {
            return hand.Any(cardSet => cardSet.Value == 4);
        }

        public enum HandType
        {
            Null,
            OnePair,
            TwoPair,
            ThreeCard,
            Straight,
            FullHouse,
            FourCard,
        }
    }
}