Task

Create a program to parse a single five card poker hand and rank it according to this list of poker hands.



A poker hand is specified as a space separated list of five playing cards.

Each input card has two characters indicating face and suit.



Example

2d       (two of diamonds).


Faces are:    a, 2, 3, 4, 5, 6, 7, 8, 9, 10, j, q, k

Suits are:    h (hearts),   d (diamonds),   c (clubs),   and   s (spades),   or

alternatively,   the unicode card-suit characters:     ♥ ♦ ♣ ♠ 



Duplicate cards are illegal.

The program should analyze a single hand and produce one of the following outputs:

 straight-flush
 four-of-a-kind
 full-house
 flush
 straight
 three-of-a-kind
 two-pair
 one-pair
 high-card
 invalid



Examples

   2♥ 2♦ 2♣ k♣ q♦:   three-of-a-kind
   2♥ 5♥ 7♦ 8♣ 9♠:   high-card
   a♥ 2♦ 3♣ 4♣ 5♦:   straight
   2♥ 3♥ 2♦ 3♣ 3♦:   full-house
   2♥ 7♥ 2♦ 3♣ 3♦:   two-pair
   2♥ 7♥ 7♦ 7♣ 7♠:   four-of-a-kind 
   10♥ j♥ q♥ k♥ a♥:  straight-flush
   4♥ 4♠ k♠ 5♦ 10♠:  one-pair
   q♣ 10♣ 7♣ 6♣ q♣:  invalid

The programs output for the above examples should be displayed here on this page.



Extra credit

 use the playing card characters introduced with Unicode 6.0 (U+1F0A1 - U+1F0DE).
 allow two jokers
 use the symbol   joker
 duplicates would be allowed (for jokers only)
 five-of-a-kind would then be the highest hand


More extra credit examples

   joker  2♦  2♠  k♠  q♦:     three-of-a-kind
   joker  5♥  7♦  8♠  9♦:     straight
   joker  2♦  3♠  4♠  5♠:     straight
   joker  3♥  2♦  3♠  3♦:     four-of-a-kind
   joker  7♥  2♦  3♠  3♦:     three-of-a-kind
   joker  7♥  7♦  7♠  7♣:     five-of-a-kind
   joker  j♥  q♥  k♥  A♥:     straight-flush
   joker  4♣  k♣  5♦ 10♠:     one-pair
   joker  k♣  7♣  6♣  4♣:     flush
   joker  2♦  joker  4♠  5♠:  straight
   joker  Q♦  joker  A♠ 10♠:  straight
   joker  Q♦  joker  A♦ 10♦:  straight-flush
   joker  2♦  2♠  joker  q♦:  four-of-a-kind



Related tasks

 Playing cards
 Card shuffles
 Deal cards_for_FreeCell
 War Card_Game
 Go Fish


$ include "seed7_05.s7i";
  include "console.s7i";
 
const string: face is "A23456789TJQK";
const string: suit is "♥♦♣♠";
 
const func string: analyzeHand (in array integer: faceCnt, in array integer: suitCnt) is func
  result
    var string: handValue is "";
  local
    var boolean: pair1 is FALSE;
    var boolean: pair2 is FALSE;
    var boolean: three is FALSE;
    var boolean: four is FALSE;
    var boolean: flush is FALSE;
    var boolean: straight is FALSE;
    var integer: sequence is 0;
    var integer: x is 0;
  begin
    for x range 1 to 13 do
      case faceCnt[x] of
        when {2}: if pair1 then pair2 := TRUE; else pair1 := TRUE; end if;
        when {3}: three := TRUE;
        when {4}: four := TRUE;
      end case;
    end for;
    for x range 1 to 4 until flush do
      if suitCnt[x] = 5 then
        flush := TRUE;
      end if;
    end for;
    if not pair1 and not three and not four then
      for x range 1 to 13 until sequence = 5 do
        if faceCnt[x] <> 0 then incr(sequence); else sequence := 0; end if;
      end for;
      straight := sequence = 5 or (sequence = 4 and faceCnt[1] <> 0);
    end if;
    if straight and flush then handValue := "straight-flush";
    elsif four            then handValue := "four-of-a-kind"; 
    elsif pair1 and three then handValue := "full-house";
    elsif flush           then handValue := "flush";
    elsif straight        then handValue := "straight";
    elsif three           then handValue := "three-of-a-kind";
    elsif pair1 and pair2 then handValue := "two-pair";
    elsif pair1           then handValue := "one-pair";
    else                       handValue := "high-card";
    end if;
  end func;
 
const proc: analyze (in string: cards) is func
  local
    var array integer: faceCnt is 13 times 0;
    var array integer: suitCnt is 4 times 0;
    var string: card is "";
  begin
    for card range split(upper(cards), ' ') do
      incr(faceCnt[pos(face, card[1])]);
      incr(suitCnt[pos(suit, card[2])]);
    end for;
    writeln(cards <& ": " <& analyzeHand(faceCnt, suitCnt));
  end func;
 
const proc: main is func
  begin
    OUT := STD_CONSOLE;
    analyze("2♥ 2♦ 2♠ k♠ q♦");
    analyze("2♥ 5♥ 7♦ 8♠ 9♦");
    analyze("a♥ 2♦ 3♠ 4♠ 5♠");
    analyze("2♥ 3♥ 2♦ 3♠ 3♦");
    analyze("2♥ 7♥ 2♦ 3♠ 3♦");
    analyze("2♥ 7♥ 7♦ 7♠ 7♣");
    analyze("t♥ j♥ q♥ k♥ a♥");
    analyze("4♥ 4♣ k♣ 5♦ t♣");
    analyze("q♣ t♣ 7♣ 6♣ 4♣");
  end func;