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;
using E = System.Linq.Enumerable;
using IEInt32 = System.Collections.Generic.IEnumerable<int>;

static class PokerHand
{
    static void Main()
    {
        Func<IEnumerable<IEInt32>, int[], string> combinationOf =
            (g, h) =>
                g.Any( x => x.Skip( 3 ).Any() )
                    ? "four card"
                : g.All( x => x.Skip( 1 ).Any() )
                    ? "full house"
                : new[] { 10, 11, 12, 13, 1 }.Except( h ).All( _ => false )
                    ? "straight"
                : E.Range( h.Min(), 5 ).Except( h ).All( _ => false )
                    ? "straight"
                : g.Any( x => x.Skip( 2 ).Any() )
                    ? "three card"
                : g.Where( x => x.Skip( 1 ).Any() ).Skip( 1 ).Any()
                    ? "two pair"
                : g.Any( x => x.Skip( 1 ).Any() )
                    ? "one pair"
                : "null";

        var indata = Console.In.ReadToEnd()
            .Split( 
                new[] { '\r', '\n' },
                StringSplitOptions.RemoveEmptyEntries );
        var q =
            from hand in indata
            let h = Array.ConvertAll( hand.Split( ',' ), int.Parse )
            let g = h.GroupBy( x => x ).Cast<IEInt32>()
            select combinationOf( g, h );
        foreach( var c in q )
            Console.WriteLine( c );
    }
}