Locked. This question and its answers are locked因为该问题是题外话,但具有历史意义。它目前不接受新的答案或互动。









我喜欢这样的挑战,希望我会尽快提交答案。

哪个玩家拥有7张最佳手牌?

给定9张纸牌的无序列表(以空格隔开),计算出哪个牌手的手牌最好。 Here is a list of poker hand rankings。输入示例:

2C 5H AS KS 2D 4D QD KH 3S
(ie: [[2C 5H] [AS KS] [2D 4D QD KH 3S]])


阵列中的前2张牌代表玩家1的手,阵列中的第二张2代表玩家2的手。最后5张卡代表社区卡,双方都共享。实际上,两个玩家都有7张牌,您必须确定哪个玩家的5张牌手牌最好。

卡定义为字符串,第一个字符代表卡值,第二个值代表西服。始终为大写。没有卡可能会出现两次。

该函数将计算该手牌是平局还是对任一玩家的胜利。它将在输入末尾输出总计。输出格式将在本文后面定义。

例子

2C 5H AS KS 2D 4D QD KH 3S
(ie: [[2C 5H] [AS KS] [2D 4D QD KH 3S]])
Player 2 wins this hand.  Player 1 has a pair of 2's, player 2 has a pair of kings.

5S 6S 8H 9D 7S 8S JH TS 2H
(ie: [[5S 6S] [8H 9D] [7S 8S JH TS 2H]])
Player 1 wins this hand  Player 1 has a flush, player 2 has a straight.

2S 2H AC AS 2C AH 9H TS 2D
(ie: [[2S 2H] [AC AS] [2C AH 9H TS 2D]])
Player 1 wins this hand.  Player 1 has quads, player 2 has a full house

5S 6S 2D 4D 9S AS KD JC 9D
(ie: [[5S 6S] [2D 4D] [9S AS KD JC 9D]])
A draw.  Both players have Ace high.


更多信息

感谢mgroves为以下链接到具有类似问题的Euler项目提供的链接:
http://projecteuler.net/index.php?section=problems&id=54

测试数据

我们将使用Project Euler测试数据:

http://projecteuler.net/project/poker.txt

您的解决方案应接受该文本文件作为输入,并输出总的赢和平局。

示例输出

输出必须采用以下格式:

1: 45
2: 32
D: 12


玩家1赢得45局,玩家2赢得32局,并且有12局。 (不是实际结果)

规则


不必返回胜出手的类型,只有WHO可以赢得
卡列表输入没有特定顺序
没有卡两次出现在输入中
输入始终为大写
将项目Euler测试数据作为输入
以上面给定的格式输出一个计数,其中哪个玩家赢得了最多的手牌和总平局

最佳答案

Perl,414398370/458 344/416字符

换行符并不重要。

%M=map{$_,$Z++}0..9,T,J,Q,K,A;sub N{/.$/;$M{$`}.$&}

sub B{$s=@p=();
for$m(@_){$m-$_||($s+=2,++$p[$m])for@_}
@_=sort{$p[$b]-$p[$a]||$b-$a}@_;
$s=23 if$s<11&&($_[0]-$_[4]<5||$_[0]-$_[1]>8&&push@_,shift);
"@_"=~/.$/;$s+=14*(4<grep/$&/,@_);
$s=100*$s+$_ for@_;$s}

++$X{B((@c=map{N}split)[0..4])<=>B(@c[5..9])}for<>;
printf"1: %d\n2: %d\nD: %d\n",@X{1,-1,0}


这解决了“ 10张牌”的问题(发出10张牌,玩家1拥有前5张牌,玩家2具有第二张5张牌)。

第一部分定义了一个子例程N,该例程可以转换每个卡,使其具有数值。对于非人脸卡,这是一个简单的映射(5H ==> 5H),但它确实转换了人脸卡(KC => 13C,AD => 14D)。

最后一部分将输入的每一行解析为纸牌,将纸牌转换为包含数字的值,将纸牌分成两个玩家的不同手牌,然后分析并比较这些手牌。每手增加哈希值%X的一个元素。解析完所有输入后,%X包含玩家1赢得的手数,玩家2赢得的手数或平局。

中间部分是一个子例程,该例程将一组五张卡作为输入并产生一个
12位数字,具有较强的扑克手将具有更高价值的数字的属性。运作方式如下:

    for$m(@_){$m-$_||($s+=2,++$p[$m])for@_}


这是“对”检测器。如果任意两张卡具有相同的数值,则为其中一张卡增加一个哈希元素,并将“得分”变量$s加2。请注意,我们最终将每张卡与其自身进行比较,因此每张卡$s$p[$x]至少为10,而$x至少为1。如果该手牌包含三张相同的牌,则这三张牌将与其他两张牌匹配-就像那三张牌中有9个匹配项,“得分”至少为18。

    @_=sort{$p[$b]-$p[$a]||$b-$a}@_;


按(1)卡作为“对”的一部分的次数和(2)卡的值对卡进行排序。因此,在有两个7和两个3的手中,两个7将首先出现,然后是两个3,然后是踢球者。在有两个7和三个3的一手牌中,首先是三个3,然后是两个7。该排序的目的是区分得分相同的两只手-一对8的手和一对7的手都有一对,但是我们必须能够分辨出一对8的手。更好。

    $s=23 if$s<11&&($_[0]-$_[4]<5||$_[0]-$_[1]>8&&push@_,shift);


这条线是“直线”检测器。一条平局价值23分,当手牌中没有对时(出现$s<11表示只有5对“-每张与自己匹配的牌”)并且其中任一(1)最高牌的值正好为四大于最低牌($_[0]-$_[4]==4)的值,或(2)最高牌为A,第二高牌为5($_[0]-$_[1]==9),这意味着手牌为A-2-3 -4-5直在后一种情况下,王牌现在是手牌中价值最低的牌,因此我们操纵@_来反映该(push@_,shift

    "@_"=~/.$/;$s+=14*(4<grep/$&/,@_);


这条线是冲洗检测器。当每张纸牌的最后一个字符相同时,同花值得14分。第一个表达式("@_"=~/.$/)具有将$&设置为手中最后一张牌的最后一个字符(西服)的副作用。当且仅当4<grep/$&/,@_的所有元素具有相同的最后一个字符时,最终表达式(@_)才为true。

    $s=100*$s+$_ for@_;$s}


创建并返回一个值,该值以手的得分开始,然后按卡的重要性顺序包含卡的值。各种手的分数将是

Hand           Score
----------    ------
High card       10     (each card matches itself for two points)
One pair        14     (2 additional matches)
Two pair        18     (4 additional matches)
Three of a kind 22     (6 additional matches)
Straight        23     (no pair, but 23 points for straight)
Flush           24     (no pair, but 14 additional points for the flush)
Full house      26     (8 additional matches)
4 of a kind     34     (12 additional matches)
Straight flush  37     (23 + 14 points)


这与扑克规则是一致的。得分相同的手可以通过手牌的值来区分,从手的重要性顺序到手牌中价值最低的手牌。

解决9张牌问题(两张牌给玩家1,两张牌给玩家2,玩家共享接下来的5张牌并建立自己的最佳5张牌手)需要大约70笔以上的笔划才能从中选择最佳5张牌手每个玩家可使用7张卡:

%M=map{$_,$Z++}0..9,T,J,Q,K,A;sub N{/./;$M{$&}.$'}

sub A{my$I;
for$k(0..41){@d=@_;splice@d,$_,1for$k%7,$k/7;$s=@p=();
for$m(grep$_=N,@d){$m-$_||($s+=2,$p[$m]++)for@d}
@d=sort{$p[$b]-$p[$a]||$b-$a}@d;
$s=23 if$s<11&&($d[0]-$d[4]<5||$d[0]-$d[1]>8&&push@d,shift@d);
"@d"=~/.$/;$s+=14*(4<grep/$&/,@d);
$s=100*$s+$_ for@d;
$I=$s if$s>$I}$I}

++$X{A((@c=split)[0,1,4..8])<=>A(@c[2..8])}for<>;
printf"1: %d\n2: %d\nD: %d\n",@X{1,-1,0}

08-26 11:40