Beri nama tangan poker

22

Beri nama tangan poker

Diberikan lima kartu, keluaran nama tangan poker, yang akan menjadi salah satu dari:

High card
One pair
Two pair
Three of a kind
Straight
Flush
Full house
Four of a kind
Straight flush
Royal Flush

Jika ragu, lihat peraturan di http://en.wikipedia.org/wiki/List_of_poker_hands .

Memasukkan

5 kartu dari argumen stdin atau commandline. Kartu adalah string dua huruf pada formulir RS, di mana R adalah peringkat dan S sesuai. The jajaran yang 2- 9(kartu angka), T(sepuluh), J(Jack), Q(Queen), K(Raja), A(Ace). The jas yang S, D, H, Cuntuk sekop, berlian, hati dan klub masing-masing.

Contoh kartu

5H - five of hearts
TS - ten of spades
AD - ace of diamonds

Contoh input => output yang diinginkan

3H 5D JS 3C 7C => One pair
JH 4C 2C JD 2H => Two pair
7H 3S 7S 7D 7C => Four of a kind
8C 3H 8S 8H 3S => Full house

Aturan

Kode terpendek menang

Edit

Tampak hebat sejauh ini! Saya benar-benar tidak dapat memverifikasi semua jawaban, karena saya tidak tahu bahasa-bahasa ini dengan sangat baik dan tidak memiliki kompiler / juru bahasa untuk semuanya, tetapi saya curiga tidak semua orang berpikir bahwa Aces bisa menjadi yang tertinggi dan juga baik. kartu terendah dari Straight (flush) .

daniero
sumber
2
Ada oldie terkait samar-samar di Stack Overflow .
dmckee
Apakah kami diizinkan menggunakan huruf besar (atau tidak) nama tangan sesuka kami?
Mr.Wizard
Tuan Penyihir, tentu.
daniero

Jawaban:

3

GolfScript ( 209 208 207 206 200 199 197 196 karakter)

3/zip:^0={10,''*"TJQKA"+?}/]:?15,{?\{=}+,,}%2,-$6,14.),++@$/):|;[!!2*^1=.&,(!+5+]or{/}*'Full house
Two pair
One pair
ThreeKFourKHigh card
Flush
Straight''K'/' of a kind
'*n/~|1$"Royal"if" "+2$+](=

Saya mengeksploitasi kebebasan yang ditawarkan untuk mengubah huruf kapital: Straight Flush saya dan Royal Flush keduanya memanfaatkan Flush untuk menggunakan kembali kata dari flush yang sederhana.

Catatan: beberapa versi sebelumnya buggy: mereka hanya mendukung full house saat pasangan itu nilainya lebih rendah dari pasangan royal. Mereka dapat diperbaiki dengan mengganti ruang yang memisahkan - 0dengan a $.

Demo

Peter Taylor
sumber
Nah, itu program golf! Saya telah mencari cara untuk mempersingkatnya, tetapi tidak dapat menemukan apa pun. Menggunakan .&untuk menemukan karakter yang berbeda dalam sebuah string adalah trik yang sangat berguna.
Cristian Lupascu
@ w0lf, itu trik yang cukup standar. Howard juga menggunakannya dalam solusinya.
Peter Taylor
8

Datang dengan jawaban saya sendiri :)

Python - 312 301 298

R,K,F,S,g=' 23456789TJQKA2345A',' of a Kind','Flush','Straight ',sorted
s,r=''.join(g(raw_input(),key=R.find)).split()
n,m=g(map(r.count,set(r)))[-2:]
print[[F,[0,'High Card','TOwnoe'[n&1::2]+' Pair',['Full House','Three'+K][n&1],'Four'+K][m]],[[S,'Royal '][r[0]=='T']+F,S]][r in R][len(set(s))>1]

Membuat daftar 2x2 di mana indeks dari dua dimensi adalah boolean untuk memeriksa flush dan straight. Dalam hal keduanya, kami memeriksa apakah itu flush royal atau hanya straight flush. Untuk tidak flush dan tidak lurus, kami memeriksa tangan yang lain: mdan nmemegang kartu dengan peringkat yang sama tertinggi dan kedua; nama-nama tangan disimpan dalam daftar dengan indeks sesuai dengan m. Sub-cek dalam nilai daftar ini dilakukan dengan nmemisahkan satu pasangan dari dua pasangan, dan tiga sejenis dari rumah.

Sunting: Terima kasih Nolen Royality untuk total 20 karakter yang disimpan!

daniero
sumber
1
... dan mengalahkan milikku.
Mr.Wizard
Suka solusi baru, 312 karakter cukup kecil. Metode yang sangat pintar dalam berurusan dengan satu vs dua pasangan: D
Nolen Royalty
Terima kasih :) Anda dapat mencobanya jika Anda mau. Tapi Anda mungkin tidak menggunakan variabel serupa dengan saya dan m. Memeriksa ini dan menonton kode Anda lagi, saya baru sadar saya bisa mencukur lagi yang asli ^^
daniero
1
Tidak bisakah Anda kehilangan 8 karakter lagi dengan beralih m,n=g([c.count(x)for x in set(r)])ke m,n=g(map(c.count,set(r)))?
Nolen Royalty
Woah, kau benar sekali, aku bisa: D Tidak tahu mengapa itu menyelinap di pikiranku. Tangkapan yang bagus, terima kasih!
daniero
5

Ruby 1.9 (427 359 348 338 296 292)

EDIT : Tetap bekerja dengan ace rendah.

o,p=%w(flush straight)
f=/1{5}|1{4}0+1$/
s=[0]*13
puts Hash[*$*.map{|c|s['23456789TJQKA'.index c[0]]+=1;c[1]}.uniq[1]?[f,p,?4,'four'+a=' of a kind',/3.*2|2.*3/,'full house',?3,'three'+a,/2.*2/,'two pair',?2,'one pair',0,'high card']:[/1{5}$/,'royal '+o,f,p+' '+o,0,o]].find{|r,y|s.join[r]}[1]

Ide dasarnya adalah untuk membangun susunan jumlah kartu di setiap peringkat, menggabungkan angka menjadi string, dan kemudian menjalankan ekspresi reguler untuk melihat bentuk tangan mana yang cocok. Kami menghitung jumlah pakaian yang berbeda untuk menentukan apakah akan mengeceknya terhadap flushes yang berbeda (flush, straight flush, royal flush) atau ke bentuk lain (semuanya).

Mengambil kartu sebagai argumen baris perintah yang terpisah, seperti:

>ruby poker-hand-golf.rb 3H 5D JS 3C 7C
one pair
Paul Prestidge
sumber
4

C, 454 karakter

#define L for(a=1;a<6;a++)for(b=0;b<13;b++)
#define U u[b+6]
#define R(x,y) if(x)puts(#y);else
b,f,r,h=0,s=0,u[20]={0};main(int a,char**v){L U+=v[a][0]=="23456789TJQKA"[b];f=v[1][1];L{if(v[a][1]!=f)f=0;u[a]+=a==U;if(b>7)h+=U;if(a*13+b<64||!U)r=0;else if(++r==5)s=1;}R(f&&h==25,Royal flush)R(f&&s,Straight flush)R(u[4],Four of a kind)R(u[3]&&u[2],Full house)R(f,Flush)R(s,Straight)R(u[3],Three of a kind)R(u[2]==2,Two pair)R(u[2],One pair)R(h,High card);}

Jalankan dari baris perintah dengan kartu sebagai argumen, misalnya ./a.out 8C 3H 8S 8H 3S

Versi diperluas, dengan komentar:

#define L for(a=1;a<6;a++)for(b=0;b<13;b++)
#define R(x,y) if(x)puts(#y);else
#define U u[b+6]
b,f,r,h=0,s=0,u[20]={0};
main(int a,char**v){
    // card usage - u[6..]
    L U+=v[a][0]=="23456789TJQKA"[b];
    // NOTE: lets expand the inner body of the loop in the answer so this looks more sane:
    // flush
    f=v[1][1];L if(v[a][1]!=f)f=0;
    // count of usages - u[0..5] 
    L u[a]+=a==U;
    // high cards x5
    L if(b>7)h+=U;
    // straights
    L if(a*13+b<64||!U)r=0;else if(++r==5)s=1;        
    // display
    R(f&&h==25,Royal flush)
    R(f&&s,Straight flush)
    R(u[4],Four of a kind)
    R(u[3]&&u[2],Full house)
    R(f,Flush)
    R(s,Straight)
    R(u[3],Three of a kind)
    R(u[2]==2,Two pair)
    R(u[2],One pair)
    R(h,High card);    
}

Suntingan:

  1. Menyimpan 12 karakter dengan menggabungkan dan menggunakan kembali loop.
  2. Disimpan 9 karakter dengan menggarisbawahi konstanta string.
  3. Disimpan 19 karakter dengan menggunakan pengetatan di makro, buruk ..
bayi-kelinci
sumber
3

Mathematica , 365

Ini jawaban saya atas jawaban David Carraher.

Ditampilkan dengan ruang putih untuk keterbacaan tertentu.

If[
  a = Characters;
  x = Thread;
  r = Range;
  d = Sort[a@StringSplit@# /. x[a@"23456789TJQKA" -> 2~r~14]];
  {t, u} = Sort[Last /@ Tally@#] & /@ x@d;
  c = First /@ d;
  f = u == {5};
  S = "Straight";
  c == r[b = d[[1, 1]], b + 4],
  If[f,
   If[c == 10~r~14, "Royal Flush", S <> " flush"], S],
  If[f, "Flush",
   Switch[t,
    {_, 4},    "Four of a kind",
    {2, 3},    "Full house",
    {__, 3},   "Three of a kind",
    {_, 2, 2}, "Two pair",
    {__, 2},   "One pair",
    _,         "High card"]
  ]
] &

Versi satu baris:

If[a=Characters;x=Thread;r=Range;d=Sort[a@StringSplit@#/.x[a@"23456789TJQKA"->2~r~14]];{t,u}=Sort[Last/@Tally@#]&/@x@d;c=First/@d;f=u=={5};S="Straight";c==r[b=d[[1,1]],b+4],If[f,If[c==10~r~14,"Royal Flush",S<>" flush"],S],If[f,"Flush",Switch[t,{_,4},"Four of a kind",{2,3},"Full house",{__,3},"Three of a kind",{_,2,2},"Two pair",{__,2},"One pair",_,"High card"]]]&
Tuan Wisaya
sumber
Bagus. Anda bahkan menemukan ruang untuk menyimpan dalam pencocokan pola. Misalnya _bukannya{_,_,_,_}
DavidC
Solusi yang bagus, kalian berdua. Demi jumlah karakter, saya pikir "Pasangan" harus dinamai "Satu Pasangan", meskipun kedengarannya agak buruk, karena itulah yang saya posting dan yang lainnya telah terapkan.
daniero
@ Dariero Terima kasih. Saya akan memperbaiki namanya.
Mr.Wizard
3

K, 294 295

d:{F:"Flush";S:"Straight ";P:" Pair";K:" of a kind";$[(f:1=#?,/-1#'c)&("AJKQT")~a@<a:,/j:1#'c:" "\:x;"Royal ",F;f&s:(4#1)~1_-':a@<a:,/(("A23456789TJQKA")!1+!14)@j;S,F;4=p:|/#:'=j;"Four",K;(2;3)~u:a@<a:,/#:'=j;"Full House";f;F;s;S;3=p;"Three",K;(1;2;2)~u;"Two",P;(1;1;1;2)~u;"One",P;"High Card"]}

.

k)d'("TS JS QS KS AS";"3S 4S 5S 7S 6S";"JC JH KS JD JS";"JC JH 2S JD 2C";"2C 9C TC QC 6C";"8C 5D 9H 6C 7D";"8C 8D 9H 8S 7D";"8C 8D 9H 2S 9D";"8C 8D 4H 2S 9D";"3C 8D 4H 2S 9D")
"Royal Flush"
"Straight Flush"
"Four of a kind"
"Full House"
"Flush"
"Straight "
"Three of a kind"
"Two Pair"
"One Pair"
"High Card"

sunting: Menambahkan 1 karakter untuk lurus rendah Ace

tmartin
sumber
3

Python 334 , 326 322 Karakter

p,f,l,t,o=" pair"," of a kind"," Flush","Straight","A23456789TJQK"
v,u=zip(*raw_input().split())
s=''.join(sorted(v,key=o.find))
print{5:"High card",7:"One"+p,9:"Two"+p,11:"Three"+f,13:"Full house",17:"Four"+f,23:t,24:l[1:],25:t,42:t+l,44:"Royal"+l}[(sum(map(v.count,v)),24)[len(set(u))<2]+((0,20)[s=="ATJQK"],18)[s in o]]

Saya tahu bahwa liner terakhir semakin tidak dapat dibaca, saya akan membuat versi non-golf ketika saya senang dengan solusi saya.

Royalti yang Dicuri
sumber
2

GolfScript, 258 250 karakter

3/zip~;.&,(!\{"23456789TJQKA"?}%$.(\{.@- 8%}%\;"\1"-!\.1/.&{1$\-,}%1.$?)"Four"" of a kind":k+{.,2="Full house"{.2\?)"Three"k+{.3-,({.3\?)"One pair"{;"Straight":?;2$2$&{(8="Royal"?if" flush"+}{;?{"Flush""High card"if}if}if}if}"Two pair"if}if}if}if])\;

Program mengharapkan input pada STDIN seperti yang diberikan di atas dan output ke STDOUT. Anda dapat menguji kode sendiri .

> 8C 3H 8S 8H 3S
Full house

> 8C 7H 6S TH 9S
Straight

> AH 3H 4S 2H 6S
High card

Sunting: Saran w0lf yang dimasukkan.

Howard
sumber
Solusi bagus! Anda dapat menyimpan 3 karakter dengan memasukkan " of a kind"variabel, karena itu digunakan dua kali.
Cristian Lupascu
itu juga bekerja dengan"Straight"
Cristian Lupascu
@ w0lf Terima kasih. Saya menambahkan saran Anda ke kode.
Howard
Saya pikir ada bug halus dengan deteksi Straights: AH KH 2C 3H 4Hdianggap sebagai kartu Straight, tetapi harus High.
Cristian Lupascu
@ w0lf Hmmm, saya harus memikirkan yang itu ...
Howard
2

Mathematica - 500 494 465 karakter

Solusi ini didasarkan pada demonstrasi poker oleh Ed Pegg, Jr. Dalam versi ini, kartu diperlakukan secara internal sebagai angka dalamRange[2,14]

v[x_] := Block[{d, t, c, f, s},
 d = Sort@ToExpression[Characters[ImportString[x, "Table"][[1]]] /. {"T" -> 10, "J" -> 11, "Q" -> 12, "K" -> 13, "A" -> 14}];t = Sort /@ Map[Length, Split /@ Sort /@ Transpose@d, {2}];c = d[[All, 1]];f = (t[[2]] == {5});s = c == Range[b = d[[1, 1]], b + 4];
If[s,
 If[f, If[c == 10~Range~14, "royal flush", "straight flush"],"straight"],
 If[ f, "flush",
Switch[t[[1]],
 {1, 4}, "four of a kind",
 {2, 3}, "full house",
 {1, 1, 3}, "three of a kind",
 {1, 2, 2}, "two pair",
 {1, 1, 1, 2}, "one pair",
 {1, 1, 1, 1, 1}, "high card"]]]]

Input sampel, output:

data

Catatan:

f: siram

c: kartu (tanpa pakaian)

s: lurus

t: {kartu, suite}

d:

DavidC
sumber
Bagus, tapi bagaimana Anda mendapatkan dua pasangan JH 4C 2C JD TH?
daniero
Anda benar. Ada kesalahan yang muncul ketika saya menggabungkan beberapa komponen menjadi fungsi murni. Saya akan melacaknya.
DavidC
@ Dariero Masalah yang Anda ajukan telah diatasi.
DavidC
David, ada banyak ruang untuk mengompres ini. Bolehkah saya
Mr.Wizard
@ Mr.Wizard Jadilah tamuku. Saya akan menonton dan belajar.
DavidC