use strict;
use warnings;
use List::Util qw( shuffle );
####
{
my %val; @val{2..10,qw(J Q K A)} = (2..14);
my @hand_names = (
[ 'Straight Flush' => qr/^<(.)xxxx((?>x*))><\1\2xxx><\1\2xx><\1\2x><\1\2>/ ],
[ 'Straight Flush' => qr/^<(.)x{14}><\1x{5}><\1x{4}><\1x{3}><\1x{2}>/ ],
[ 'Four of a Kind' => qr/<.((?>x*))>(?:.*<.\1>){3}/ ],
[ 'Full House' => qr/^<.((?>x*))>(?>(?:<.\1>){1,2})<.((?>x*))>(?>(?:<.\2>)*)\z/ ],
[ 'Flush' => qr/^<(.)(?>x*)>(?:<\1(?>x*)>){4}\z/ ],
[ 'Straight' => qr/^<.xxxx((?>x*))><.\1xxx><.\1xx><.\1x><.\1>/ ],
[ 'Straight' => qr/^<.x{14}><.x{5}><.x{4}><.x{3}><.x{2}>/ ],
[ 'Three of a Kind' => qr/<.((?>x*))>(?:.*<.\1>){2}/ ],
[ 'Two Pair' => qr/<.((?>x*))><.\1>.*<.((?>x*))><.\2>/ ],
[ 'One Pair' => qr/<.((?>x*))><.\1>/ ],
);
sub hand_name {
my $hand = join '',
sort { length($b) <=> length($a) }
map { /^(.+)(.)/; "<$2".("x" x $val{$1}).">" }
@_;
for (@hand_names) {
my ($hn, $re) = @$_;
return $hn if $hand =~ $re;
}
return 'High Card';
}
}
####
{
my @hand = (@ARGV
? @ARGV
: ( shuffle map { $_.'H', $_.'S', $_.'D', $_.'C' } 2..10,qw(J Q K A) )[0..4]
);
print join(', ', @hand) . ' is a ' . hand_name(@hand) . "\n";
}