- #!/usr/bin/perl
-
- use strict;
- use warnings;
-
-
- sub distinct {
- my (%h);
- return grep { not $h{$_}++ } int @_ > 1 ? @_ : split / /, shift;
- }
-
-
- sub numbers {
- my ($s) = shift;
- $s =~ s/T/10/g;
- $s =~ s/J/11/g;
- $s =~ s/Q/12/g;
- $s =~ s/K/13/g;
- $s =~ s/A/14/g;
- $s =~ s/[^0-9 ]//g;
- return join ' ', sort { $a <=> $b } split / /, $s;
- }
-
-
- sub suits {
- my ($s) = shift;
- $s =~ s/[^DHCS ]//g;
- return $s;
- }
-
-
- sub group {
- my ($s) = shift;
- my (%cards);
-
-
- $s =~ s/T/10/g;
- $s =~ s/J/11/g;
- $s =~ s/Q/12/g;
- $s =~ s/K/13/g;
- $s =~ s/A/14/g;
- $s =~ s/[^0-9 ]//g;
-
- $cards{$_}++ for split / /, $s;
-
- return %cards;
- }
-
-
- sub order {
- my ($s) = shift;
- my (%cards) = group $s;
- my (@ordered);
-
-
- for my $quantity (reverse 1..4) {
- for my $n (grep { $cards{$_} == $quantity } sort { $b <=> $a } keys %cards) {
- unshift @ordered, $n for (1..$quantity);
- }
- }
-
- return wantarray ? @ordered : join(' ', @ordered);
- }
-
-
- sub is_straight {
- my (@cards) = order shift;
- my ($c) = shift @cards;
-
- for (@cards) {
- return 0 if $c != $_ -1;
- $c = $_;
- }
-
- return 1;
- }
-
-
- sub is_boat {
- my (%grouped) = group shift;
- my ($has2, $has3);
- $has2 = 0 < int grep { $grouped{$_} == 2 } keys %grouped;
- $has3 = 0 < int grep { $grouped{$_} == 3 } keys %grouped;
- return $has2 && $has3 ? 1 : 0;
- }
-
-
- sub score {
- my ($cards) = shift;
- my (%grouped) = group $cards;
- my ($number_suits) = int distinct suits $cards;
- my ($is_straight) = is_straight($cards) ? 1 : 0;
-
- return 8 if $is_straight && $number_suits == 1;
- return 7 if grep { $grouped{$_} == 4 } keys %grouped;
- return 6 if is_boat $cards;
- return 5 if 1 == int distinct suits $cards;
- return 4 if is_straight $cards;
- return 3 if grep { $grouped{$_} == 3 } keys %grouped;
- return 2 if 2 == int grep {$grouped{$_} == 2} keys %grouped;
- return 1 if 1 == int grep {$grouped{$_} == 2} keys %grouped;
- return 0;
- }
-
-
- sub is_higher {
- my ($score1, $score2) = map { score $_ } @_;
-
- my ($a, $b) = @_;
-
- my (@p1) = order shift;
- my (@p2) = order shift;
-
-
- return 1 if ($score1 > $score2);
-
- if ($score1 == $score2) {
- for (reverse 0..@p1-1) {
- return 1 if ($p1[$_] > $p2[$_]);
- return 0 if ($p1[$_] < $p2[$_]);
- }
- }
- }
-
-
- open GAME, "cards.txt";
-
-
- my ($wins) = 0;
-
-
- for (<GAME>) {
- chomp;
-
- my ($p1, $p2) = (substr($_, 0, 14), substr($_, 15));
-
- $wins++ if (is_higher $p1, $p2);
- }
-
- print "$wins\n";
-
- close GAME;