use strict; use warnings; use utf8; print "P3\n".(13*13)." ".(13*13*13)."\n".(10*2)."\n"; my @HIGH = (0, 5); # or flush my @PAIR = (1, 1); my @TWO_PAIR = (2, 2); my @THREE = (3, 3); my @STRAIGHT = (4, 8); # or straight flush my @FULL_HOUSE = (6, 6); my @FOUR = (7, 7); my @ROYAL = (4, 9); my @CARD_NAMES = split '', ' 23456789TJQKA'; sub do_hand { my @cards = @_; @cards = sort {$a <=> $b} @cards; local $_ = join '', map {$CARD_NAMES[$_]} @cards; #print STDERR "$_\n"; if($_ eq 'TJQKA') { return @ROYAL; } elsif($cards[0]+1 == $cards[1] && $cards[1]+1 == $cards[2] && $cards[2]+1 == $cards[3] && $cards[3]+1 == $cards[4]) { return @STRAIGHT; } elsif(/(.)\1{3}/) { return @FOUR; } elsif(/(.)\1{2}(.)\2/ || /(.)\1(.)\2{2}/) { return @FULL_HOUSE; } elsif(/(.)\1{2}/) { return @THREE; } elsif(/(.)\1.?(.)\2/) { return @TWO_PAIR; } elsif(/(.)\1/) { return @PAIR; } else { return @HIGH; } } sub check_hand { my ($expected, $max_expected, @cards) = @_; my ($score, $max_score) = do_hand(@cards); print STDERR "$score!=$expected $max_score!=$max_expected: @cards\n" unless $score == $expected && $max_score == $max_expected; } check_hand(@HIGH, 8, 9, 10, 12, 13); check_hand(@HIGH, 7, 9, 10, 11, 13); check_hand(@HIGH, 8, 9, 11, 12, 13); check_hand(@PAIR, 1, 1, 2, 3, 5); check_hand(@PAIR, 1, 10, 10, 11, 12); check_hand(@PAIR, 1, 10, 11, 11, 12); check_hand(@PAIR, 1, 10, 11, 12, 12); check_hand(@PAIR, 13, 8, 8, 9, 10); check_hand(@PAIR, 13, 8, 9, 9, 10); check_hand(@PAIR, 13, 8, 9, 10, 10); check_hand(@PAIR, 13, 7, 7, 8, 9); check_hand(@PAIR, 13, 7, 8, 8, 9); check_hand(@PAIR, 13, 7, 8, 9, 9); check_hand(@HIGH, 1, 10, 11, 12, 13); check_hand(@PAIR, 10, 10, 11, 12, 13); check_hand(@PAIR, 11, 10, 11, 12, 13); check_hand(@PAIR, 12, 10, 11, 12, 13); check_hand(@PAIR, 13, 10, 11, 12, 13); check_hand(@ROYAL, 9, 10, 11, 12, 13); check_hand(@FOUR, 5, 5, 5, 11, 5); check_hand(@FULL_HOUSE, 5, 5, 5, 11, 11); check_hand(@FULL_HOUSE, 5, 5, 11, 11, 11); check_hand(@THREE, 5, 5, 5, 11, 10); check_hand(@TWO_PAIR, 2,3,3,4,4); check_hand(@TWO_PAIR, 2,2,3,4,4); check_hand(@TWO_PAIR, 2,2,3,3,4); check_hand(@STRAIGHT, 8,9,10,11,12); for $_ (0..13**5-1) { my @cards; for my $i (0..4) { push @cards, (int($_/13**$i) % 13) + 1; } #@cards = sort @cards; if($cards[0] == $cards[1] && $cards[1] == $cards[2] && $cards[2] == $cards[3] && $cards[3] == $cards[4]) { print "19 0 0\n"; next; } my ($score, $max_score) = do_hand(@cards); print +($score*2).' '.($score+$max_score).' '.($max_score*2)."\n"; }