Open sx349 opened 4 years ago
#include <stdio.h>
#include <ctype.h>
int cd[21];
int vs(void);
int vs2(int *arr1, int *arr2, int x);
int num(int x);
int main()
{
FILE *fp = NULL;
fp = fopen("e54.txt", "r");
if (!fp) {
printf("can't fine file!");
return 1;
}
int c , cnt = 0, win = 0;
while (++cnt <= 1000) {
for (int i = 0; i < 20; ++i) {
while (isspace(c = fgetc(fp)))
;
cd[i] = num(c);
}
if (vs())
++win;
}
printf("%d\n", win);
fclose(fp);
return 0;
}
int vs(void)
{
int sc1[25] = {0}, sc2[25] = {0}, s, cnt;
for (int i = 0; i < 10; i += 2) {
++sc1[cd[i]];
}
for (int i = 1; i<= 14; ++i) {
switch (sc1[i]) {
case 2:
sc1[0] += 3;
break;
case 3:
sc1[0] += 7;
sc1[21] = i; //三条
break;
case 4:
sc1[0] += 11;
sc1[17] = i; //四条
break;
}
}
for (int i = 10; i < 21; i += 2) {
++sc2[cd[i]];
}
for (int i = 1; i<= 14; ++i) {
switch (sc2[i]) {
case 2:
sc2[0] += 3;
break;
case 3:
sc2[0] += 7;
sc2[21] = i; //三条
break;
case 4:
sc2[0] += 11;
sc2[17] = i; //四条
break;
}
}
//同花
if ((cd[1]==cd[3]) && (cd[3]==cd[5]) && (cd[5]==cd[7]) && (cd[7]==cd[9])) {
s = 0;
for (int i = 1; i <= 14; ++i) {
if (sc1[i]) {
if (i > s)
s = i;
}
}
sc1[19] = s;
sc1[0] = 9;
}
if ((cd[11]==cd[13]) && (cd[13]==cd[15]) && (cd[15]==cd[17]) && (cd[17]==cd[19])) {
s = 0;
for (int i = 1; i <= 14; ++i) {
if (sc2[i]) {
if (i > s)
s = i;
}
}
sc2[19] = s;
sc2[0] = 9;
}
//顺子
cnt = 0, s = 0;
for (int i = 1; i <= 14; ++i) {
if (sc1[i]) {
++cnt;
s = i;
if (cnt == 5)
sc1[20] = s; //顺子
}
else{
cnt = 0;
}
}
sc1[0] = 8;
cnt = 0, s = 0;
for (int i = 1; i <= 14; ++i) {
if (sc2[i]) {
++cnt;
s = i;
if (cnt == 5)
sc2[20] = s; //顺子
}
else{
cnt = 0;
}
}
sc2[0] = 8;
//大同花顺
if (sc1[19] && sc1[10] && sc1[11] && sc1[12] && sc1[13] && sc1[14]) {
sc1[0] = 12;
sc1[15] = 1;
}
if (sc2[19] && sc2[10] && sc2[11] && sc2[12] && sc2[13] && sc2[14]) {
sc2[0] = 12;
sc2[15] = 1;
}
//同花顺
if (sc1[19] && sc1[20]) {
sc1[16] = sc1[19];
sc1[0] = 11;
}
if (sc2[19] && sc2[20]) {
sc2[16] = sc2[19];
sc2[0] = 11;
}
//对子
if (sc1[0] = 3)
for (int i = 1; i <= 14; ++i) {
if (sc1[i] > sc1[23])
sc1[23] = sc1[i];
}
if (sc2[0] = 3)
for (int i = 1; i <= 14; ++i) {
if (sc2[i] > sc2[23])
sc2[23] = sc2[i];
}
//单张
if (!sc1[0])
for (int i = 1; i <= 14; ++i) {
if (sc1[i] == 1)
sc1[24] = i;
}
if (!sc2[0])
for (int i = 1; i <= 14; ++i) {
if (sc2[i] == 1)
sc2[24] = i;
}
//葫芦
if (sc1[0] == 10)
sc1[18] = sc1[21] * 16 + sc1[22];
if (sc2[0] == 10)
sc2[18] = sc2[21] * 16 + sc2[22];
//两对
if (sc1[0] == 6) {
int v1 = 0, v2 = 0;
for (int i = 1; i <= 14; ++i) {
if (sc1[i] == 2)
if (i > v1)
v1 = i;
else
v2 = i;
}
sc1[22] = v1 * 16 + v1;
}
if (sc2[0] == 6) {
int v1 = 0, v2 = 0;
for (int i = 1; i <= 14; ++i) {
if (sc2[i] == 2)
if (i > v1)
v1 = i;
else
v2 = i;
}
sc2[22] = v1 * 16 + v1;
}
if (sc1[0] > sc2[0])
return 1;
else if (sc1[0] < sc2[0])
return 0;
else
return vs2(sc1, sc2, 16);
}
int num(int x)
{
switch (x) {
case 'T':
return 10;
case 'J':
return 11;
case 'Q':
return 12;
case 'K':
return 13;
case 'A':
return 14;
default :
return (x - '0');
}
}
int vs2(int *arr1, int *arr2, int x)
{
if (arr1[x] > arr2[x])
return 1;
else if (arr1[x] < arr2[x])
return 0;
else
return vs2(arr1, arr2, x - 1);
}
...................................................................................................
432
楼上什么玩意儿,答案是 376🤣
感觉这题就是写个处理表格的程序,跟数论不太沾边。这个 10% 难度不太有含金量。
use v5.38;
use List::Util qw(zip);
my %ranks = (
# note that full house = pair + 3kind;
# pair + pair = 2pairs;
# straight flush = straight + flush
"high" => 0,
"pair" => 1,
"2pairs" => 2,
"3kind" => 3.5,
"straight" => 4,
"flush" => 4.25,
"fullh" => 4.5,
"4kind" => 7,
"sflush" => 8.25,
);
sub card_info($card) {
my($val, $suit)=(split "", $card);
if ($val =~ /[A-Z]/) {
if ($val eq "T") {
$val = 10;
} elsif ($val eq "J") {
$val = 11;
} elsif ($val eq "Q") {
$val = 12;
} elsif ($val eq "K") {
$val = 13;
} elsif ($val eq "A") {
$val = 14;
}
}
[$val, $suit];
}
sub get_hand_vals($hand) {
#sort numerically ascending:
[ sort {$a <=> $b} map { $_->[0] } @$hand ];
}
sub get_hand_suits($hand) {
[ map { $_->[1] } @$hand ];
}
sub is_flush($suits) {
my $suit = shift @{$suits};
for (@{$suits}) {
return 0 unless $_ eq $suit;
}
return 1;
}
sub is_straight($vals) {
# vals should get sorted ascending previously.
my $n = $vals->[0];
foreach (@$vals[1..4]) {
return 0 unless $_ == $n+1;
$n = $_;
}
return 1;
}
sub hand_info($hand) {
# hand: [ [$val, $suit] x5 ]
my ( $rank, $vals, $suits ) = ( 0, get_hand_vals($hand), get_hand_suits($hand) );
my ( $rank_vals, $high_vals ) = ( [], [] );
if (is_flush($suits)) {
$rank += $ranks{"flush"};
push @$rank_vals, reverse @$vals;
}
if (is_straight($vals)) {
$rank += $ranks{"straight"};
push @$rank_vals, $vals->[-1] unless 0 != scalar @$rank_vals;
} elsif($rank != $ranks{"flush"}) {
my %vals_hash = ();
foreach my $val (@$vals) {
if (exists $vals_hash{$val}) {
$vals_hash{$val} ++;
} else {
$vals_hash{$val} = 1;
}
}
foreach my $key_val (sort {$b<=>$a} keys %vals_hash) {
my $val_count = $vals_hash{$key_val};
if (4 == $val_count) {
$rank += $ranks{"4kind"};
unshift @$rank_vals, $key_val;
} elsif (3 == $val_count) {
$rank += $ranks{"3kind"};
unshift @$rank_vals, $key_val;
} elsif (2 == $val_count) {
$rank += $ranks{"pair"};
push @$rank_vals, $key_val;
} else {
push @$high_vals, $key_val;
}
}
}
# vals should be sorted from high to low correctly.
[ $rank, @$rank_vals, sort {$b<=>$a} @$high_vals ];
}
sub parse($cards) {
foreach (@{$cards}) {
$_ = card_info($_);
}
my $p1hands = hand_info [@{$cards}[0..4]];
my $p2hands = hand_info [@{$cards}[5..9]];
#pxhands: [ rank, rank val, high cards' val ]
[ $p1hands, $p2hands ];
}
sub who_will_win ($two_hands) {
#p1p2: [ [rank1, rank2] [rank_val1, rank_val2] ... ]
foreach my $p1p2 (zip $two_hands->[0], $two_hands->[1]) {
for ($p1p2->[0] <=> $p1p2->[1]) {
return 1 if $_ == 1;
return 2 if $_ == -1;
}
}
die "You shouldn't get here.\n" . join " ", map { ("HAND:", @$_ , ";") } @$two_hands;
}
my $count = 0;
# read the file line by line.
while(<>) {
chop;
$count++ if 1 == who_will_win(parse([split " ", $_]));
}
say $count;
https://pe-cn.github.io/54/
Problem 54 Poker hands In the card game poker, a hand consists of five cards and are ranked, from lowest to highest, in the following way: High Card: Highest value card. One Pair: Two cards of the s