我喜欢这样的挑战,希望尽快提交我的答案。
哪位玩家拥有最好的 7 张牌?
给定一个包含 9 张牌的无序列表(用空格分隔),计算出哪位玩家拥有最好的扑克牌。 这里是扑克手牌排名列表。输入示例:
2C 5H AS KS 2D 4D QD KH 3S
(ie: [[2C 5H] [AS KS] [2D 4D QD KH 3S]])
数组中的前 2 张牌代表玩家 1 的手牌,数组中的第二张牌代表玩家 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.
更多信息
感谢 mggroves 提供以下指向 Project 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 场平局。 (非实际结果)
规则
- 不必返回获胜手牌类型,只有谁赢了
- 牌列表输入没有特定顺序
- 输入中没有牌出现两次
- 输入总是大写
- 接受项目欧拉测试数据作为输入
- 输出计数,其中玩家赢得最多手牌和总平局(以上面给定的格式表示)
I love challenges like this, I'll hopefully submit my answer soon.
Which player has the best 7 card hand?
Given an unordered list of 9 cards (separated by a space), work out which player has the best poker hand. Here is a list of poker hand rankings. Example input:
2C 5H AS KS 2D 4D QD KH 3S
(ie: [[2C 5H] [AS KS] [2D 4D QD KH 3S]])
First 2 cards in the array represent player 1's hand, second 2 in the array represent player 2's hand. The last 5 cards represent the community cards, cards both players share. In effect, both players have 7 cards, and you must determine which player has the best 5 card poker hand.
A card is defined as a string, with the first character representing the card value, and the second value representing the suit. Always upper-case. No card may appear twice.
The function will calculate if the hand is a draw or a win to either player. It will ouput the totals at the end of the input. The output format is defined later on in this post.
Examples
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.
More Info
Thanks to mgroves for the following link to Project Euler which has a similar problem:
http://projecteuler.net/index.php?section=problems&id=54
Test Data
We will use the Project Euler test data:
http://projecteuler.net/project/poker.txt
Your solution should accept that text file as input, and output a total of wins and draws.
Example Output
Output must be in this format:
1: 45
2: 32
D: 12
Player 1 won 45 hands, player 2 won 32 hands, and there were 12 draws. (Not actual results)
Rules
- Doesn't have to return the winning hand type, only WHO won if anyone
- Card list input has no particular order
- No card appears twice in the input
- Input is always uppercase
- Takes the Project Euler test data as an input
- Outputs a count, of which player won the most hands and total draws in given format above
发布评论
评论(6)
Perl,
414398370/458344/416 char换行符不重要。
这解决了“10 张牌”问题(发了 10 张牌,玩家 1 拥有前 5 张牌,玩家 2 拥有后 5 张牌)。
第一部分定义了一个子例程
N
,它可以转换每张卡片,使其具有数值。对于非人脸牌,这是一个简单的映射(5H ==> 5H),但它确实会转换人脸牌(KC => 13C,AD => 14D)。最后一部分将每一行输入解析为卡片,将卡片转换为包含数值,将卡片分为两个玩家的不同手牌,并对这些手牌进行分析和比较。每手都会增加哈希
%X
的一个元素。解析所有输入后,%X
包含玩家 1 赢得的牌数、玩家 2 赢得的牌数或平局数。中间部分是一个子例程,它将一组五张卡片作为输入并生成一个
12 位数字,具有更强的扑克牌将获得更高价值的数字的特性。它的工作原理如下:
这是“成对”探测器。如果任何两张卡具有相同的数值,则增加其中一张卡的哈希元素,并将“分数”变量
$s
加 2。请注意,我们最终会将每张卡与其自身进行比较,因此每张卡$s
将至少为 10,而$p[$x]
将至少为 1 <代码>$x。如果手牌包含三张相同的牌,那么这三张牌将与另外两张牌匹配 - 就好像这三张牌中有 9 场比赛,“分数”将至少为 18。将牌按 ( 1) 该卡成为“对”的一部分的次数以及 (2) 该卡的面值。因此,在有两个 7 和两个 3 的牌局中,两个 7 将首先出现,然后是两个 3,最后是踢球者。在有两个 7 和三个 3 的牌局中,三个 3 会先出现,然后是两个 7。这种排序的目的是区分具有相同分数的两手牌——一对 8 的手牌和一对 7 的手牌都有一对,但我们需要能够分辨出一对 8更好。
这条线是“直”检测器。顺子价值 23 分,当手牌中没有对子时(
$s<11
表示仅找到 5 个“对子”——每张牌与其自身相匹配)并且 (1)最大牌的值比最小牌的值正好多四 ($_[0]-$_[4]==4
),或者 (2) 最高值的牌是一张A 和下一张最大的牌是 5 ($_[0]-$_[1]==9
),这意味着这手牌有 A-2-3-4-5 顺子。在后一种情况下,A 现在是手上最不有价值的牌,因此我们操纵@_
来反映这一点 (push@_,shift)
这一行是齐平检测器。当每张牌的最后一个字符相同时,同花可多加 14 点。第一个表达式 (
"@_"=~/.$/
) 具有将$&
设置为最后一张牌的最后一个字符(花色)的副作用在手上。当且仅当@_
的所有元素具有相同的最后一个字符时,最终表达式 (4) 才为 true。
创建并返回一个值,该值以手牌得分开始,然后包含卡牌的值(按卡牌的重要性排序)。各手牌的分数将
与扑克规则一致。得分相同的手牌可以通过该手牌的面值来区分,按照该手牌的重要性顺序,一直到该手牌中最不值钱的牌。
9 张牌问题的解决方案(玩家 1 两张牌,玩家 2 两张牌,玩家分享接下来的 5 张牌并构建他们最好的 5 张牌手牌)需要大约 70 笔以上才能从每位玩家可使用 7 张牌:
Perl,
414398370/458344/416 charLine breaks are not significant.
This solves the "10 card" problem (10 cards are dealt, player 1 has the first 5 cards and player 2 has the second 5 cards).
The first section defines a subroutine
N
that can transform each card so that it has a numerical value. For non-face cards, this is a trivial mapping (5H ==> 5H) but it does transform the face cards (KC => 13C, AD => 14D).The last section parses each line of input into cards, transforms the cards to contain numerical values, divides the cards into separate hands for the two players, and analyzes and compares those hands. Every hand increments one element of the hash
%X
. When all the input is parsed,%X
contains the number of hands won by player 1, won by player 2, or ties.The middle section is a subroutine that takes a set of five cards as input and produces a
12-digit number with the property that stronger poker hands will have higher-valued numbers. Here's how it works:
This is the "pair" detector. If any two cards have the same numerical value, increment a hash element for one of the cards and increase the "score" variable
$s
by two. Note that we will end up comparing each card to itself, so$s
will be at least 10 and$p[$x]
will be at least one for every card$x
. If the hand contains three of a kind, then those three cards will match with the other two cards -- it will be like there are 9 matches among those three cards and the "score" will be at least 18.Sort the cards by (1) the number of times that card is part of a "pair" and (2) the value of the card. Thus in a hand with two 7's and two 3's, the two 7's will appear first, followed by the two 3's, followed by the kicker. In a hand with two 7's and three 3's, the three 3's will be first followed by the two 7's. The goal of this ordering is to distinguish two hands that have the same score -- a hand with a pair of 8's and a hand with a pair of 7's both have one pair, but we need to be able to tell that a pair of 8's is better.
This line is the "straight" detector. A straight is worth 23 points and occurs when there are no pairs in the hand (
$s<11
means only 5 "pairs" - each card matching with itself - were found) and either (1) the value of the highest card is exactly four more than the value of the lowest card ($_[0]-$_[4]==4
), or (2) the highest value card is an Ace and the next highest card is a 5 ($_[0]-$_[1]==9
), which means the hand has an A-2-3-4-5 straight. In the latter case, the Ace is now the least valuable card in the hand, so we manipulate@_
to reflect that (push@_,shift
)This line is the flush detector. A flush is worth 14 more points and occurs when the last character is the same for each card. The first expression (
"@_"=~/.$/
) has the side effect of setting$&
to the last character (the suit) of the last card in the hand. The final expression (4<grep/$&/,@_
) will be true if and only if all elements of@_
have the same last character.Creates and returns a value that begins with the hand's score and then contains the values of the cards, in order of the card's importance. Scores for the various hands will be
which is consistent with the rules of poker. Hands with the same score can be distinguished by the values of the hand's cards, in order of importance to the hand, all the way down to the least valuable card in the hand.
The solution to the 9 card problem (two cards to player 1, two cards to player 2, the players share the next 5 cards and build their best 5 card hand) needs about 70 more strokes to choose the best 5 card hand out of the 7 cards available to each player:
GolfScript - 151/187 个字符
该程序适用于每行 10 张牌的输入列表,即两手 5 张牌。
该程序适用于每行 9 张卡片的输入列表,其格式在规范中描述。
GolfScript - 151/187 chars
This program works on an input list of 10 cards per line, i.e. two 5 card hands.
This program works on an input list of 9 cards per line, of the format described in the specifications.
哈斯克尔:793
796806826864904901>880863由于文本文件与 9 手牌不一致,我只是从控制台读取一行并输出谁获胜。
错误修复:
打过高尔夫球:
未打过高尔夫球:
Haskell: 793
796806826864904901880863Since the text file is inconsistent with 9 card hands, I'm just reading a line from the console and outputting who wins.
Bugfixes:
Golfed:
Ungolfed:
GolfScript
258241247/341217/299 char10 张牌问题的解决方案。只有最后几个换行符很重要:
9 卡问题目前还需要大约 80 个字符。
少打高尔夫球版本的 10 张牌问题。
GolfScript
258241247/341217/299 charSolution for the 10 card problem. Only the last couple of newlines are significant:
The 9 card problem currently needs about 80 more characters.
Less golfed version of 10 card problem.
C,665+379 个字符
这是我的回答,分为两部分。
第一个是完整的 7 张牌评估器,包括“AddCard”宏
A
。它返回一个 32 位数字,对手牌进行排名。高半字节是类型,位 13..25 指示高牌,位 0..12 指示踢脚牌。在比较结果时,更好的牌总是具有更大的价值。第二个是输入处理器。它将项目 Euler 文件解析为 2+2+5 卡(忽略第 10 张卡)。它使用 Parse 宏
P
创建代表每张卡的 32 位值。表示形式为0A0K0Q0J0T090807060504030200shdc
。一手牌存储为 5 个整数的数组。我确信还有一些字符需要修剪。我很快就会添加解释。
评估器在我的 3Ghz Core2 Duo 上以每秒 1760 万次的速度运行。这仅比 PokerSource 评估器慢 3.5 倍,后者使用至少 56K 的查找表。
C, 665+379 chars
Here's my answer in 2 parts.
The first is a complete 7 card evaluator, including the "AddCard" macro
A
. It returns a 32-bit number ranking the hand. The high nibble is the type, bits 13..25 indicate the high card(s) and bits 0..12 indicate the kicker(s). When comparing the results, the better hand will always have the larger value.The second is the input processor. It parses the project Euler file as 2+2+5 cards (ignoring the 10th card). It uses the Parse macro,
P
to create 32-bit values representing each card. The representation is0A0K0Q0J0T090807060504030200shdc
. A hand is stored as an array of 5 ints.I'm sure there are a few more characters to be trimmed off. I'll add an explanation soon.
The evaluator runs @17.6 Million hands/second on my 3Ghz Core2 Duo. That's only 3.5x slower than the PokerSource evaluator, which uses at least 56K of lookup tables.
PHP,799 个字符
换行符并不重要。这从链接的 url 获取输入,这与示例输入不同(不处理公共卡)。处理类似于 mobrule 的 perl 答案,但评分方法不同。
PHP, 799 chars
Line breaks are not significant. This takes input from the linked url, which is different from the example input (doesn't deal with community cards). Processing is similar to mobrule's perl answer, with a different scoring method.