ตั้งชื่อมือโป๊กเกอร์ - ฉบับที่ 7 บัตร


11

ความท้าทาย:

ในคำถามนี้: ตั้งชื่อมือโป๊กเกอร์ที่คุณต้องใช้ห้ามือไพ่โป๊กเกอร์และระบุ คำถามนี้คล้ายกันกับสองบิด:

ก่อนอื่นเอาต์พุตจะเป็นตัวพิมพ์เล็กทั้งหมด สิ่งนี้จะช่วยให้การตีกอล์ฟมากขึ้นเนื่องจากคุณไม่ต้องกังวลกับการใช้อักษรตัวพิมพ์ใหญ่flushและstraight

high card
one pair
two pair
three of a kind
straight
flush
full house
four of a kind
straight flush
royal flush

ประการที่สองด้วยความนิยมของ Texas Hold'em และ 7 card Stud เราที่นี่ที่ golf code ควรจะได้คะแนนไพ่โป๊กเกอร์เจ็ดใบในมือใช่ไหม? เมื่อให้คะแนนไพ่เจ็ดใบให้ใช้ไพ่ห้าใบที่ดีที่สุดสำหรับมือของคุณและไม่สนใจไพ่สองใบที่คุณไม่ต้องการ

อ้างอิง:

รายการมือโป๊กเกอร์: http://en.wikipedia.org/wiki/List_of_poker_hands

อินพุต (ยกโดยตรงจากเธรดก่อนหน้า)

ไพ่ 7 ใบจากอาร์กิวเมนต์ stdin หรือ commandline การ์ดเป็นสตริงตัวอักษรสองตัวบนแบบฟอร์มRSโดยที่ R คืออันดับและ S เป็นชุด การจัดอันดับเป็น2- 9(บัตรจำนวน) T(สิบ) J(แจ็ค) Q(ควีน) K(กิ่ง) A(ACE) ชุดมีS, D, H, Cสำหรับจอบ, เพชร, หัวใจและคลับตามลำดับ

ตัวอย่างของการ์ด

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

ตัวอย่างของอินพุต => เอาต์พุตที่ต้องการ

3H 5D JS 3C 7C AH QS => one pair
JH 4C 2C 9S 4H JD 2H => two pair
7H 3S 7S 7D AC QH 7C => four of a kind
8C 3H 8S 8H 3S 2C 5D => full house
AS KC KD KH QH TS JC => straight

แจ้งให้ทราบล่วงหน้าในตัวอย่างที่สองมีจริงสามคู่ two pairแต่คุณจะสามารถใช้บัตรห้าจึงเป็น ในตัวอย่างที่ห้ามีทั้งthree of a kindและstraightเป็นไปได้ แต่จะดีกว่าเพื่อการส่งออกstraightstraight

เกณฑ์การให้คะแนน

นี่คือดังนั้นรหัสที่สั้นที่สุดชนะ!

คหบดี

  1. คุณไม่สามารถใช้ทรัพยากรภายนอก
  2. Ace มีทั้งสูงและต่ำสำหรับ straights

นีซ; ฉันหวังว่าจะมีคนแอบมารับลูกบอล เพียงแค่ต้องการที่จะทราบว่าฉันไม่ได้มีข้อ จำกัด ใด ๆ เกี่ยวกับการใช้อักษรตัวใหญ่ในคำถามเดิม (ชี้แจงในความคิดเห็น) ดังนั้นคุณสามารถ (และส่วนใหญ่ / ทั้งหมดได้) เอาท์พุท "Straight Flush" IMHO ตัวพิมพ์ใหญ่ดูดีกว่า
daniero

คุณพูดอินพุต (ยกโดยตรงจากเธรดก่อนหน้า) 5 การ์ด ฉันคิดว่าคุณหมายถึงการเปลี่ยนเป็น 7
ระดับแม่น้ำเซนต์

@steveverrill คุณสามารถแก้ไขโพสต์ด้วยตัวคุณเองในการแลกเปลี่ยนสแต็ก แม้ว่าฉันจะทำเพื่อคุณที่นี่
durron597

อนุญาตทรัพยากรภายนอกหรือไม่ มีตารางการค้นหาที่จะช่วยให้คุณสามารถค้นหาไพ่แต่ละใบในมือและได้รับความแข็งแรงของมือ
เคนดัลล์เฟรย์

Ace สามารถต่ำและสูงสำหรับ straights ได้หรือไม่?
Nick T

คำตอบ:


4

ทับทิม 353

สิ่งนี้มีพื้นฐานมาจากคำตอบของ Chronจากคำถามเดิม

สิ่งนี้ใช้อินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่ง โดยพื้นฐานแล้วเราแค่วนซ้ำการรวมกันของขนาด 5 เพื่อให้ได้มือประเภทนั้น มือแต่ละประเภทได้รับการแก้ไขเพื่อให้เริ่มต้นด้วยตัวเลข ("Royal flush" -> "0royal 4flush", "high card" -> "9high card") สิ่งนี้ทำให้เราสามารถจัดเรียงสตริงที่ถูกส่งคืน สตริงแรกหลังจากเรียงลำดับเป็นมือที่ดีที่สุด ดังนั้นเราจึงพิมพ์ออกมาหลังจากลบตัวเลขทั้งหมดออกจากสตริง

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

ดี gsub ในตอนท้ายสามารถย่อยได้ใช่ไหม
bazzargh

@bazzargh ไม่จำเป็นต้องลบตัวเลขทั้งหมด รหัสเชื่อมต่อ 4flush กับ 1st straight หรือ 0royal เพื่อรับ "0royal 4 flush" หรือ "1st ตรง 4flush" หากเราใช้เฉพาะย่อย 4 จะไม่ถูกลบออก
FDinoff

AS QS JS TS 9S 5H 5Dให้ผลผิด นั่นจะทำให้คุณเสียค่าใช้จ่ายสำหรับตัวละคร!

@ WumpusQ.Wumbley อืมดูเหมือนว่าจะเป็นข้อผิดพลาดในรหัสต้นฉบับ ฉันจะลองและคิดออกว่าปัญหาคืออะไรในภายหลัง
FDinoff

5

Haskell 618 603 598 525 512 504 480 464

การ์ดที่ใช้เป็นสายอินพุต ฉันคิดว่าฉันเล่นกอล์ฟนี้จนตาย แต่จะถูกตีอย่างง่ายดายโดย ruby ​​และอื่น ๆ โดยใช้เล่ห์เหลี่ยมเดียวกัน: หากคุณสร้างการเรียงสับเปลี่ยนทั้งหมดคุณจะได้รับเรียงลำดับล่วงหน้าที่คุณต้องการมองหา straights รวมทั้งเรียงกลับที่คุณต้องการสำหรับทดสอบ N ชนิด

import Data.List
m=map
z=take 5
q=m(\x->head[n|(f,n)<-zip"A23456789TJQK"[1..],f==x!!0])
l=m length
v=" of a kind"
w="flush"
y="straight"
c f s p r|f&&r="9royal "++w|f&&s='8':y++" "++w|f='5':w|s||r='4':y|True=case p of 4:_->"7four"++v;3:2:_->"6full house";3:_->"3three"++v;2:2:_->"2two pair";2:_->"1one pair";_->"0high card"
d x=c([5]==l(group$m(!!1)x))(q x==z[head(q x)..])(l$group$q x)$q x==1:[10..13]
k h=tail$maximum$m(d.z)$permutations$words h
main=interact k

แก้ไขเป็นแบบอินไลน์ "จับคู่" และใช้หมายเลขนำหน้าหลังจากเห็นรายการของ @ FDinoff และยังมีฟังก์ชั่นแผนที่ประกอบเพื่อโกนอักขระอีกหนึ่งตัว


คุณสามารถช่วยตัวเองสองสามตัวละคร (ประมาณ 5 ฉันคิดว่า) ถ้าคุณกำจัดคุณ "one pair","two pair"สั้นลงแล้วu=" pair" ... "one"++u,"two++u
FDinoff

ใช่ฉันแค่ทำการเปลี่ยนแปลงนั้นหลังจากอ่านรหัสของคุณ อีกทั้งเทคนิคคำนำหน้าตัวเลขช่วยให้ฉันประหยัดอีก 5
bazzargh

2

C ++, 622 553 ตัวอักษร

มีการขึ้นบรรทัดใหม่ที่ไม่จำเป็นจำนวนสี่บรรทัดด้านล่างเพื่อความชัดเจน

#include"stdafx.h"
#include"string"
std::string c=" flush",d=" of a kind",e="straight",z[10]={"high card","one pair","two pair","three"+d,e,c,"full house","four"+d,e+c,"royal"+c},
x="CDHSA23456789TJQK";char h[99];int main(){__int64 f,p,t,g,u,v,w,l=1,a=78517370881,b=a+19173960,i,j,q=0;gets_s(h,99);for(i=28;i-->7;){f=p=0;
for(j=7;j--;)if(j!=i%7&j!=(i+i/7)%7){f+=l<<x.find(h[j*3+1])*6;p+=l<<x.find(h[j*3])*3-12;}
v=p&b*2;u=v&v-1;w=p&p/2;g=p*64&p*8&p&p/8&p/64;f&=f*4;t=f&&p==a?9:f&&g?8:p&b*4?7:u&&w?6:f?5:g||p==a?4:w?3:u?2:v?1:0;
q=t>q?t:q;}puts(z[q].c_str());}

สิ่งที่เปลี่ยนไปในเวอร์ชัน golfed:

Rev 1: เปลี่ยนตัวแปรตัวเลขทั้งหมด__int64สำหรับการประกาศเดียว

Rev 1: การเพิ่มขึ้น Golfed และเงื่อนไขของforลูป

Rev 0: เปลี่ยนค่าคงที่ฐานแปดเป็นทศนิยม

Rev 0: เปลี่ยนifคำแถลงเป็นการมอบหมายด้วยโอเปอเรเตอร์ที่มีเงื่อนไข Rev 1: จัดเรียงใหม่ในนิพจน์เดียวให้tมากขึ้น ต้องการตัวแปรใหม่vสำหรับหนึ่งในค่ากลาง

Rev 0: ลบผลลัพธ์ verbose ที่ถูกลบ แสดงเฉพาะมือโดยรวมที่ดีที่สุดเท่านั้น

Rev 0: รวบรวมการบีบอัดข้อความเอาท์พุท (ยากใน C เพราะคุณไม่สามารถต่อสายอักขระโดยใช้ตัวดำเนินการ +) เขียน "flush" เพียงครั้งเดียวช่วยให้ฉันประหยัด 12 อักขระ แต่ค่าใช้จ่ายฉัน 15 ทำให้แย่ลงโดยรวม 3 ตัว ดังนั้นฉันจึงเขียนมัน 3 ครั้งแทน Rev 1: ใช้std::stringแทนการchar[]แนะนำโดย FDinoff ทำให้สามารถเชื่อมต่อ+ได้

รุ่นที่ไม่ได้บรรจุ 714 ตัวอักษรที่ไม่ใช่ข้อคิดเห็นช่องว่าง

วนมือ 21 ที่เป็นไปได้ทั้งหมดที่สามารถทำจาก 7 ใบและปฏิเสธไพ่ 2 ใบในแต่ละครั้ง ชุดไพ่และอันดับของไพ่ห้าใบที่เลือกจะถูกรวมในตัวแปร f และ p ด้วยตัวเลขฐานแปดที่แตกต่างกันสำหรับแต่ละชุด / อันดับ การดำเนินการบิตต่าง ๆ จะถูกดำเนินการเพื่อกำหนดประเภทของมือซึ่งจะถูกเก็บไว้ใน t (ทั้ง 21 ความเป็นไปได้จะถูกส่งออกในรุ่นที่ไม่ได้รับการฝึกฝน) ในที่สุดมือที่ดีที่สุดคือเอาท์พุท

#include "stdafx.h"
#include "string.h"

char x[] = "CDHSA23456789TJQK", h[99], z[10][99] = 
{ "high card", "one pair", "two pair","three of a kind", "straight","flush","full house","four of a kind","straight","royal" };

int main(void)
{
        int i,j,q=0;                  //i,j:loop counters. q:best possible hand of 7 card   
        scanf_s("%s/n", &h, 99); getchar();
        for (i = 7; i < 28; i++){

          //f,p: count number of cards of each suit (2 octal digits) and rank (1 octal digit.)
          //t: best hand for current 5 cards. g:straight flag. u,w: flags for pairs and 3's.   
          //l: constant 1 (64bit leftshift doesn't work on a literal.) 
          //octal bitmasks: a=ace high straight, b=general purpose

            __int64 f=0,p=0,t=0,g,u,w,l=1,a=01111000000001,b=a+0111111110;

           for (j = 0; j < 7; j++){
               if (j != i %7 & j != (i+i/7) %7){

                   f += l << (strchr(x,h[j*3+1])-x)*6;
                   p += l << (strchr(x,h[j*3])-x-4)*3;

                   printf_s("%c%c ",h[j*3], h[j*3+1]);
               }
           }

           w=p&b*2;                          //if 2nd bit set we have a pair
           if (w) t=1;
           u= w & w-1;                       //if there is only one pair w&w-1 evaluates to 0; +ve for 2 pair.
           if (u) t=2;
           w = p & p/2;                      // if 2nd and 1st bit set we have 3 of kind. 
           if (w) t=3;
           g = p*64 & p*8 & p & p/8 & p/64;  // detects all straights except ace high. pattern for ace high in a.
           if (g||p==a) t=4;
           f&=f*4;                           //for a flush we want 5 cards of the same suit, binary 101
           if (f) t=5;
           if (u&&w) t=6;                    //full house meets conditions of 2 pair and 3 of kind
           if (p & b*4) t=7;                 //four of a kind
           if (f && g) t=8;                  //straight flush
           if (f && p==a) t=9;               //royal flush
           printf_s("%s %s \n",z[t],t>7?z[5]:"");
           q=t>q?t:q;
        }   
        printf_s("%s %s",z[q],q>7?z[5]:"");
        getchar();
}

เอาท์พุท Ungolfed

ป้อนคำอธิบายรูปภาพที่นี่


เนื่องจากคุณบอกว่าคุณกำลังใช้ c ++ คุณสามารถใช้<string>ซึ่งรองรับ + ​​สำหรับการต่อข้อมูลสตริง ซึ่งหมายความว่าคุณอาจใช้<iostream>และใช้งานได้coutแต่ฉันไม่รู้จริง ๆ ว่าสิ่งเหล่านี้จะนำไปสู่การนับจำนวนตัวอักษรที่น้อย
FDinoff

@FDinoff สิ่งที่ฉันสามารถบันทึกได้: " pair flush flush straight of a kind"= 35 ตัวอักษร เมื่อคุณเพิ่มในการ#includeออมมีน้อยที่สุดแล้วคุณต้องพิจารณาพิเศษ",=+และการประกาศของค่าคงที่ นอกจากนี้ฉันยังใหม่กับ C ++ และการดิ้นรนกับการตั้งค่า IDE และคอมไพเลอร์ (มันบังคับให้ฉันใช้scanf_sและprintf_sแทนที่จะเป็นรุ่น "ไม่ปลอดภัย" แบบเก่าและความช่วยเหลือเกี่ยวกับการแก้ไขมันจะวนเป็นวงกลม) coutอาจช่วยนิดหน่อย ทำรายการ แต่อาจเป็นไปได้สำหรับโปรแกรมอื่น สิ่งที่ฆ่าcoutฉันก็คือusing namespace stdฉันไม่รู้ว่าจะมีวิธีหลีกเลี่ยงการเขียนทั้งหมดหรือไม่
เลเวลริเวอร์ St

คุณแทบไม่ควรต้องพิมพ์และ scanf เนื่องจากคุณใช้ c ++ มีอีกหลายคน (ปลอดภัยกว่า) คือการทำสิ่งเดียวกัน คุณสามารถใช้std::coutเพื่อรับรอบusing namespace std
FDinoff

@FDinoff ขอบคุณสำหรับเคล็ดลับ ในการแก้ไขล่าสุดของฉันฉันบันทึก 18 ไบต์ด้วยการจัดการสตริงที่แตกต่างกัน: gets_s& puts, บวกstd::stringกับการต่อซึ่งหมายความว่าฉันต้องแปลงchar*เป็นเอาต์พุต สนามกอล์ฟที่ฉันโพสต์ทำงานด้วยเพียงstringหรืออย่างiostream.แปลกประหลาดฉันต้องมีทั้งสองอย่างเพื่อใช้<<>>ตัวดำเนินการกับcin/cout& std::strings โดยรวมแล้วการใช้งานทั้งสองอย่างนั้น#includeแย่กว่า 5 ไบต์ถึงแม้ว่าฉันสามารถประกาศhเป็นstd::stringและหลีกเลี่ยงการcharประกาศแยกต่างหาก คาดการณ์ฉันไม่สามารถหารายการของสิ่งที่อยู่namespace stdในความช่วยเหลือ (หรือคำอธิบายเกี่ยวกับผู้ประกอบการ)
ระดับแม่น้ำเซนต์

@FDinoff ฉันยอมรับว่าปกติฉันจะไม่ใช้scanfและgetsยกเว้นว่าจะเล่นกอล์ฟซึ่งมีโปรแกรมที่ไม่ปลอดภัยอยู่ดี ฉันสามารถย่น 5 ไบต์-s,99ถ้าฉันสามารถใช้getsแทนgets_sแต่ฉันไม่สามารถรับคอมไพเลอร์เพื่อให้ฉัน สิ่งที่ทำให้ฉันประหลาดใจก็คือ C / C ++ ที่ไม่ปลอดภัยนั้นโดยทั่วไปแล้ว! ไม่กี่สัปดาห์ที่ผ่านมามันจะทำให้ฉันตกใจที่พบว่า_int64 x=1<<yให้คำตอบที่ผิดสำหรับ y มากกว่า 31 แต่ตอนนี้ฉันแค่รำคาญเล็กน้อย เมื่อเห็นสิ่งต่าง ๆ ด้วยตัวห้อยของอาร์เรย์ที่ออกนอกขอบเขตโดยไม่มีข้อความแสดงข้อผิดพลาดฉันก็ชินกับมันแล้ว มีวิธีใดบ้างที่เปิดการตรวจสอบได้ดีขึ้น
เลเวลริเวอร์เซนต์

2

perl (> = 5.14), 411 403 400 397 400

แก้ไข : ทำเครื่องหมายรายการย่อยที่ถูกเรียกเพียงครั้งเดียวโดยบันทึก 8 ตัวอักษร
แก้ไข 2 : ลบ a .""ที่เหลือจากความพยายามก่อนหน้า
แก้ไข 3 : แทนตัวแปร temp ที่เก็บต้นฉบับ$_ใช้หนึ่งเพื่อทำให้ไม่จำเป็น กำไรสุทธิ 3 ตัวอักษร
แก้ไข 4 : ความล้มเหลวคงที่ในการตรวจสอบบ้านเต็มเต็มรูปแบบ (2x 3-of-a-kind) ราคา 3 ตัวอักษร

ไม่ใช่ผู้ชนะ แต่สำหรับตัวตรวจจับตรงนั้นเป็นแนวคิดที่น่าสนใจ

sub
j{join"",sort@_}sub
o{j(map{{A=>10}->{$_},11+index(j(2..9).TJQKA,$_)}$h=~/(.(?=@_))/g)=~/.*(..)(??{j
map$1+$_.'.*',1..4})/?$1:()}$h=$_=<>;if(j(/(\S)\b/g)=~/(.)\1{4}/){$w=$_==19?royal:straight
for
o$f=$1}$_=j(/\b(\S)/g)=~s/(.)\1*/length$&/rge;$k=" of a kind";print$w?"$w flush":/4/?four.$k:/3.*2|[23].*3/?"full house":$f?flush:(o".")?straight:/3/?three.$k:/2.*2/?"two pair":/2/?"one pair":"high card"

รุ่นที่ขยาย:

# We'll be doing a lot of sorting and joining
sub j {
  return join "", sort @_;
}

# r() expects $_ to contain a rank, and converts it to a numeric code. The
# code starts at 10 so the numbers will sort correctly as strings, and a list
# of 2 values is returned because A is both 10 and 23. All other ranks have
# undef as the first value and their proper 11..22 value as the second value.
sub r {
  return ({A=>10}->{$_}, 11+index(j(2..9).TJQKA,$_));
}

# Sequence-detector. Factored into a sub because it's run twice; once over
# the ranks in the flush suit to find a straight flush and once over all the
# ranks to find a straight. On successful match, returns the lowest rank of
# the straight (in the 10..23 representation).
# Required parameter: the suit to search, or "." for all suits.
sub o {
  j(map r,$h=~/(.(?=@_))/g)          # The list of ranks, in increasing order,
                                     # with ace included at both ends...
    =~                               # ...is matched against...
  /.*(..)(??{j map$1+$_.'.*',1..4})/ # ...a pattern requiring 5 consecutive
                                     # numbers.
  ?$1:()
  # A note about this regexp. The string we're matching is a bunch of numbers
  # in the range 10..23 crammed together like "121314151619" so you might
  # worry about a misaligned match starting on the second digit of one of the
  # original numbers. But since that would make every pair of digits in the
  # match end with a 1 or a 2, there's no way 5 of them will be consecutive.
  # There are no false matches.
  # Another note: if we have a royal flush and also have a 9 in the same
  # suit, we need to return the T rank, not the 9, which is why the regexp
  # starts with a .*
}

# Read a line into $_ for immediate matching with /.../ and also save it into
# $h because $_ will be clobbered later and we'll need the original string
# afterwards.
$h = $_ = <>;

if(j(/(\S)\b/g) =~ /(.)\1{4}/) { # flush detector: sorted list of all suits
                                 # contains 5 consecutive identical chars
  # $f=$1 comes first, so $f will be true later if there's a flush.
  # Then o() is called with the flush suit as arg to detect straight flush.
  # If there's no straight flush, o() returns the empty list and for loop
  # runs 0 times, so $w is not set. If there is a straight flush, the return
  # value of o() is compared to 19 to detect royal flush.
  $w = ($_==19 ? "royal" : "straight")
    for o($f=$1);
}

$_ =
  j(/\b(\S)/g)                 # Get the sorted+joined list of ranks...
    =~ s/(.)\1*/length $&/rge; # ... and turn it into a list of sizes of
                               # groups of the same rank. The /r flag
                               # requires perl 5.14 or newer.

print
  $w             ? "$w flush" :
  /4/            ? "four of a kind" :
  /3.*2|[23].*3/ ? "full house" :
  $f             ? "flush" :
  (o".")         ? "straight" :
  /3/            ? "three of a kind" :
  /2.*2/         ? "two pair" :
  /2/            ? "one pair" :
                   "high card"

1

JavaScript 600

การใช้งานกับ nodeJS: node code.js "7H 3S 7S 7D AC QH 7C"

function a(o){s="";for(k in o)s+=o[k];return s}
b=process.argv[2]
c={S:0,H:0,D:0,C:0}
v={A:0,K:0,Q:0,J:0,T:0,"9":0,"8":0,"7":0,"6":0,"5":0,"4":0,"3":0,"2":0}
d=b.split(" ")
for(i=d.length;i--;){e=d[i];c[e[1]]++;v[e[0]]++}
c=a(c);v=a(v)
f=g=h=j=k=l=m=false
if((st=c.indexOf(5))!=-1)g=!g
if(v.match(/[1-9]{5}/))h=!h
if(st==0)f=!f
if(v.indexOf(4)!=-1)j=!j
if(v.indexOf(3)!=-1)k=!k
if(n=v.match(/2/g))if(n)if(n.length>=2)m=!m;else l=!l
p=" of a kind"
q="Flush"
r="Straight"
console.log(f&&g?"Royal "+q:h&&g?r+" "+q:j?"Four"+p:k&&(l||m)?"Full House":g?q:h?r:k?"Three"+p:m?"Two pairs":l?"Pair":"High card")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.