ホールデムまたはフォールドエム?


17

あなたの友人が土壇場でハイステークスポーカーゲームに招待しました。コンピューター科学者として、あなたは自分のスキルを使ってゲームで優位に立つことにしました。あなたの仕事は、2 cards(あなたの手)と0, 3, 4 or 5 cards(配られたカード)を与えられ、あなたが得ることができる最高の手が何であるかを決める必要があります。7枚すべてのカードが引数として与えられた場合、答えはかなり明確です。与えられない場合、問題はより複雑になります。しかし、これはあなたが探している優位性を得るのに十分ではありません。また、残りのカードから可能な限り最高のハンドを計算して、対戦相手が持っているものを理解する必要もあります。


ホールデムリフレッシャー

ホールデムについて知らない場合、ゲームの各プレイヤーは、自分の「手」として2枚のカードから始めます。3回の「ターン」の過程で、追加のカードがすべてのプレイヤー間で共有されることが明らかになります。最初のターン、3枚のカードが公開されます。2回目、さらに1回、3回目に最終カードが公開されます。最初に与えられた2枚のカードは手札を表し、後者は連続したターンで与えられた0、3、4、または5枚のカードを表します。


可能な数:

[2,3,4,5,6,7,8,9,T(10),J,Q,K,A]

可能なスーツ:

[S,C,H,D]

フルデッキ:

[2S,3S,4S,5S,6S,7S,8S,9S,TS,JS,QS,KS,AS, # Spades.
 2C,3C,4C,5C,6C,7C,8C,9C,TC,JC,QC,KC,AC, # Clubs.
 2H,3H,4H,5H,6H,7H,8H,9H,TH,JH,QH,KH,AH, # Hearts.
 2D,3D,4D,5D,6D,7D,8D,9D,TD,JD,QD,KD,AD] # Diamonds.

ハンドランキング:

1:Royal Flush    (A-K-Q-J-10, all from the same suit).
2:Straight Flush (Sequential cards, all from the same suit).
3:Four-of-a-Kind (Self explanatory).
4:Full House     (3-of-a-kind and a 2-of-a-kind).
5:Flush          (All cards are from the same suit).
6:Straight       (Sequential Cards, any suits).
7:3-of-a-Kind    (Self explanatory).
8:2-Pair         (Double 2-of-a-Kind).
9:Pair           (2-of-a-Kind).
10:High Card     (You have absolutely nothing except a single card).

1つまたは2つの例を見て、それらを見ていきましょう。

簡単な例:

[AS, AC],[AH,AD,9S,9C,9H]-> 3(4つの種類)、3(4つの種類)

このセットアップで可能な最高のハンドは、4種類のハンドです。あなたの対戦相手が持っている可能性のある最高のハンドは、2枚のカードの手にはKQJ10を持てないので、4-of-a-Kindです。


[5C,2C],[6C,4C,JH,JD]-> 2(ストレートフラッシュ)、3(4-of-a-Kind)

ストレートフラッシュのリスクがありますが、2 / 5Cを手に持っているため、両方のミドルカードを持っていることに起因するものは誰もいません。彼らが期待できる最善の方法は、ポケットジャックを2つ持ち、フロップでジャックを獲得することです。


[JS,JC],[]-> 1(ロイヤルフラッシュ)、1(ロイヤルフラッシュ)

それらに対して使用できる情報は提供されていません。現時点でわかるのは、ダイヤモンド/ハートにロイヤルフラッシュしか持てないということだけです。実際、フロップがまだ発生していないすべての入力は、1-1の答えになるはずです。


[2C,4S],[3C,7S,9D,AH,JD]-> 10(ハイカード)、7(3-of-a-Kind)

これは、あなたが絶対にねじ込まれている場所の例であり、川が与えられた場合、ストレートまたはフラッシュの可能性はありません。ここでベストハンドを意味するのは、ポケットエースであり、3種類のカードをもたらします。


I / O要件

  • 入力は、あなたの手元にあるものと、公に知られているものとの間で分けられなければなりません。実装に関係なく、この方法のほうが簡単です。
    • カードは、タプルまたは文字列にすることができます。
    • 手と競技場は、配列または区切り文字列にすることができます。
  • 出力は、私が提供したハンドのリストからの2つのインデックスでなければなりません(EG [2,1])。
    • 関数の一部として返され、コンソールに出力されるか、適切な方法で出力されます。
    • 2つの異なる値が必要です。1つは最高のハンド、もう1つは最高のハンドです。
  • 10は、Tまたはの10いずれかで表されます。
  • 標準の抜け穴は許可されていません。

受賞基準

  • これは、ポスト日付のタイブレーカーを伴う最小バイト数です。

2
そこだけの一つであってはならないA1可能性許さカードで?また、のような数値に対して顔の略語を必要とする説得力のある理由はないと思います11
FryAmTheEggman


9
私はとデッキ見たことがないA1。他のすべてがよさそうだ。
isaacg

1
ポーカー以外のプレイヤーの場合、2番目のグループのカードはあなたと対戦相手の間で共有されますが、彼らには見えない2枚のカードがあります。pocketflop、およびriverという用語を定義した簡単な用語集が役立ちます。
DLosc

1
また役立つ:ラウンドのシーケンス全体を説明します。(各プレイヤーは自分だけが知っている2枚のカードで始まり、3枚のカードが表向きに配られ、4枚目、5枚目で、各プレイヤーは目に見える7枚のうち5枚のカードから「手」を形成します。)なぜ7枚のカードが存在するのに5枚の手で構成されるのかは、誰かには明らかでないかもしれません。
DLosc

回答:


3

Haskell433430425バイト

@Laikoniのおかげで-5バイト

import Data.List
q="23456789TJQKA"
e=elem
l=length
b=map
r p|z,elem 'A'u,elem 'K'u=1|z=2|e 4t=3|v<3=4|w=5|y=6|e 3t=7|v<4=8|v<5=9|1>0=10where u=[n!!0|n<-p];v=l$nub u;t=b(\n->l[x |x<-u,x==n])q;w=all(==(last$p!!0))[last s|s<-p];y=elem""[u\\s|s<-b(take 5.flip drop('A':q))[0..10]];z=y&&w
0%_=[[]]
n%(x:y)=b(x:)((n-1)%y)++n%y
_%_=[]
h#t|let p=h++t;c i=minimum$b r$concat$b(5%)$b(++i)((7-l i)%([n:[s]|n<-q,s<-"SCHD"]\\p))=(c p,c t)

オンラインでお試しください!

Ungolfed(同じ考え、わずかに異なる構造):

import Data.List -- for (\\)
numbers = "23456789TJQKA"

e=elem

rank_hand hand
    |royal_flush=1
    |straight_flush=2
    |four_of_a_kind=3
    |full_house=4
    |flush=5
    |straight=6
    |three_kind=7
    |two_pair=8
    |pair=9
    |1>0=10
    where nums = [head n | n<-hand]
          unique = length $ nub nums
          counts = map (\n->length [x | x<-nums, x==n]) numbers
          pair = unique < 5
          two_pair = unique < 4 -- could also be 3 of a kind, but that's ok
          three_kind = e 3 counts
          flush = all (==(last$hand!!0)) [last s|s<-hand]
          straight = elem "" [nums\\s | s <- map (take 5.flip drop ('A':numbers))[0..10]]
          full_house = unique < 3
          four_of_a_kind = e 4 counts
          straight_flush = straight && flush
          royal_flush = straight_flush && elem 'A' nums && elem 'K' nums

-- taken from /codegolf//a/34496/66460
-- k%l finds combinations of size k from a list l
0%_=[[]]
n%(x:y)=map(x:)((n-1)%y)++n%y
_%_=[]

-- find every combination available to each player, and rank each one. 
-- could be golfed a lot more.
h#t=let p=h++t
        a=[n:[s]|n<-numbers,s<-"SCHD"]\\p
        c i=minimum $ map rank_hand $ concat $ map (5%) $ map (++i) ((7-length i)%a)
    in(c p,c t)

非常に遅い。特別なケースがまったくないので(たとえば、カードが表示されていない場合、ロイヤルフラッシュは常に可能です)rank_hand#地図などを組み合わせることで、より多くのゴ​​ルフを楽しむことができます。

hand#tableあなたとあなたの対戦相手に最適なスコアを計算します。エラーチェックを行いません。


s/elem/e/g定義した後に忘れたと思うe=elemので、9バイト節約できます。私はあなたにも識別子が直接数字をたどる特にいくつかのスペース、削除することができると思う
ジュリアン・ウルフを

@JulianWolf私はまだHaskellに慣れていませんが、何らかの理由でe=elemInt-> Bool型のように見えるため、非整数のelem呼び出しにeを使用したときにコンパイルされませんでした。なぜだったのかを解明しようとしています。スペースのヒントをありがとう!
vroomfondel

ああ、あなたは正しい。Haskellは柔軟なタイプフラグの追加を超えて、簡単に修正があるのかどうか、私の頭の上から、時には-ないように注意してください多型の種類を推定するトラブルがある
ジュリアン・ウルフ

1
h#t=let[...]in[...]に短縮できますh#t|let[...]=[...]。もhead nですn!!0。ガードで&&単にすることができます,
ライコニ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.