Nennen Sie die Pokerhand - 7 Karten Edition


11

Die Herausforderung:

In dieser Frage: Nennen Sie die Pokerhand , für die Sie eine Fünf-Karten-Pokerhand nehmen mussten, und identifizieren Sie sie. Diese Frage ist ähnlich, mit zwei Wendungen:

Erstens wird die Ausgabe in Kleinbuchstaben erfolgen. Dies ermöglicht mehr Golf, da Sie sich nicht um die Großschreibung von flushund kümmern müssenstraight

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

Zweitens, mit der Popularität von Texas Hold'em und 7 Card Stud sollten wir hier bei Code Golf in der Lage sein, eine 7-Karten- Pokerhand zu erzielen, stimmt's? Wenn Sie eine Hand mit sieben Karten erzielen, verwenden Sie die fünf besten Karten für Ihre Hand und ignorieren Sie die beiden, die Sie nicht benötigen.

Referenz:

Liste der Pokerhände: http://en.wikipedia.org/wiki/List_of_poker_hands

Eingabe (direkt vom vorherigen Thread abgehoben)

7 Karten aus Standard- oder Befehlszeilenargumenten. Eine Karte ist eine aus zwei Buchstaben bestehende Zeichenfolge auf dem Formular RS, wobei R der Rang und S die Farbe ist. Die Ränge sind 2- 9(Zahlenkarten), T(zehn), J(Bube), Q(Königin), K(König), A(Ass). Die Anzüge sind S, D, H, Cfür Pik, Karo, Herz und Clubs sind.

Beispiel für Karten

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

Beispiel für Eingabe => gewünschte Ausgabe

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

Beachten Sie, dass es im zweiten Beispiel tatsächlich drei Paare gibt, Sie jedoch nur fünf Karten verwenden können two pair. Im fünften Beispiel gibt es sowohl a three of a kindals auch a straightmöglich, aber a straightist besser, also Ausgabe straight.

Wertung

Dies ist , also gewinnt der kürzeste Code!

Errata

  1. Sie dürfen keine externen Ressourcen verwenden.
  2. Ace ist sowohl hoch als auch niedrig für Geraden.

Nett; Ich hoffte insgeheim, dass jemand den Ball aufheben würde. Ich wollte nur beachten, dass ich in der ursprünglichen Frage (in einem Kommentar klargestellt) keine Einschränkungen hinsichtlich der Großschreibung hatte. Sie konnten also (und die meisten / alle taten dies) "Straight Flush" ausgeben. IMHO groß geschrieben sieht besser aus.
Daniero

Sie sagen Eingabe (direkt aus dem vorherigen Thread entfernt) 5 Karten. Ich denke, Sie wollten das auf 7 ändern.
Level River St

@steveverrill Sie können Beiträge beim Stapeltausch selbst bearbeiten. Obwohl ich es hier für Sie
getan habe

Sind externe Ressourcen erlaubt? Es gibt Nachschlagetabellen, mit denen Sie einfach jede Karte in der Hand nachschlagen und eine Handstärke erhalten können.
Kendall Frey

Kann das Ass für Geraden sowohl niedrig als auch hoch sein?
Nick T

Antworten:


4

Ruby 353

Dies beruhte auf Chron 'Antwort aus der ursprünglichen Frage.

Dies nimmt Eingaben als Befehlszeilenargumente entgegen. Grundsätzlich durchlaufen wir einfach alle Kombinationen der Größe 5, um herauszufinden, um welche Art von Hand es sich handelt. Jeder Handtyp wurde so geändert, dass er mit einer Zahl beginnt. ("Royal Flush" -> "0royal 4flush", "High Card" -> "9high Card"). Auf diese Weise können wir zurückgegebene Zeichenfolgen sortieren. Die erste Zeichenfolge nach dem Sortieren ist die bestmögliche Hand. Also drucken wir das aus, nachdem wir alle Zahlen aus der Zeichenfolge entfernt haben.

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/,'')

Nett. Das gsub am Ende kann nur ein Sub sein, oder?
Bazzargh

@bazzargh nein es muss alle Zahlen entfernen. Der Code verkettet 4flush mit 1straight oder 0royal, um "0royal 4 flush" oder "1straight 4flush" zu erhalten. Wenn wir nur Sub verwenden, werden die 4 nicht entfernt.
FDinoff

Gibt das falsche Ergebnis für AS QS JS TS 9S 5H 5D. Das kostet dich einen Charakter!

@ WumpusQ.Wumbley Hmm das scheint ein Fehler im Originalcode zu sein. Ich werde später herausfinden, wo das Problem liegt.
FDinoff

5

Haskell 618 603 598 525 512 504 480 464

Karten als Eingabezeile genommen. Ich glaube, ich habe dies zu Tode gespielt, werde aber mit demselben Trick leicht von Rubin usw. geschlagen: Wenn Sie alle Permutationen erzeugen, erhalten Sie die Vorwärtssorten, nach denen Sie suchen möchten, sowie die Rückwärtssorten, die Sie zum Testen von N benötigen von einer Art.

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

Bearbeitet, um "Paar" zu inlineieren und Nummernpräfixe zu verwenden, nachdem @ FDinoffs Eintrag angezeigt wurde. Außerdem wurden Kartenfunktionen erstellt, um ein weiteres Zeichen zu rasieren.


Sie können sich ein paar Zeichen sparen (ungefähr 5, denke ich), wenn Sie Sie loswerden. "one pair","two pair"ist kürzer alsu=" pair" ... "one"++u,"two++u
FDinoff

Ja, ich habe diese Änderung gerade vorgenommen, nachdem ich Ihren Code gelesen habe. Auch die
Zahlenpräfix-

2

C ++, 622 553 Zeichen

Zur Verdeutlichung wurden unten vier unnötige Zeilenumbrüche hinzugefügt.

#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());}

In der Golfversion haben sich die Dinge geändert:

Rev 1: Alle numerischen Variablen wurden __int64für eine einzelne Deklaration in geändert .

Rev 1: Golf Inkrement und Zustand der forLoops

Rev 0: Oktalkonstanten in Dezimal geändert.

Rev 0: Geänderte ifAnweisungen für Zuweisungen mit bedingtem Operator. Rev 1: Weiter angeordnet in einen einzigen Ausdruck für t. Dies erforderte eine neue Variable vfür einen der Zwischenwerte

Rev 0: Ausführliche Ausgabe gelöscht. Gibt nur die beste Hand aus.

Rev. 0: Ich habe auf das Komprimieren des Ausgabetextes verzichtet (schwierig in C, da Sie Zeichenfolgen mit dem Operator + nicht verketten können). Das Schreiben von "Flush" nur einmal hat mir 12 Zeichen erspart, mich aber 15 gekostet, was mich insgesamt 3 Zeichen schlechter macht. Also habe ich es stattdessen nur dreimal geschrieben. Rev. 1: Wird std::stringanstelle der char[]von FDinoff vorgeschlagenen verwendet, um eine Verkettung mit zu ermöglichen +.

Ungolfed Version, 714 nicht kommentierte Nicht-Leerzeichen.

Durchläuft alle 21 möglichen Hände, die aus 7 Karten hergestellt werden können, und lehnt jedes Mal 2 Karten ab. Die Farbe und der Rang der fünf ausgewählten Karten werden in den Variablen f und p mit einer anderen Oktalzahl für jede Farbe / jeden Rang summiert. Verschiedene Bitoperationen werden ausgeführt, um den Hand-Typ zu bestimmen, der dann in t gespeichert wird (alle 21 Möglichkeiten werden in der ungolfed-Version ausgegeben.) Schließlich wird die bestmögliche Hand ausgegeben.

#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 Ausgabe

Geben Sie hier die Bildbeschreibung ein


Da Sie sagen, dass Sie C ++ verwenden, können Sie verwenden, <string>was + für die Verkettung von Zeichenfolgen unterstützt. Was dann bedeutet, dass Sie wahrscheinlich verwenden <iostream>und verwenden könnten. coutIch weiß jedoch nicht, ob eines davon zu einer geringeren Anzahl von Zeichen führen würde.
FDinoff

@FDinoff was ich sparen könnte: " pair flush flush straight of a kind"= 35 Zeichen. Wenn Sie #includenur minimale Einsparungen erzielen, müssen Sie zusätzliche Einsparungen ",=+und Deklarationen von Konstanten berücksichtigen . Außerdem bin ich neu in C ++ und habe Probleme mit IDE- und Compiler-Einstellungen (es zwingt mich, diese zu verwenden, scanf_sund printf_sanstelle der alten "unsicheren" Versionen und der Hilfe zur Behebung geht es in Kreisen um.) coutKönnte ein wenig helfen, es liegt an mir Liste auflisten, aber wahrscheinlich für ein anderes Programm. Was coutmich umbringt , ist, dass using namespace stdich nicht weiß, ob es einen Weg gibt, das alles nicht zu schreiben.
Level River St

Sie sollten printf und scanf fast nie benötigen, da Sie c ++ verwenden. Es gibt andere (sicherere), die das Gleiche tun sollten. Sie könnten verwenden std::cout, um dieusing namespace std
FDinoff

@FDinoff Danke für den Tipp. In meiner letzten Bearbeitung habe ich 18 Bytes mit unterschiedlicher Zeichenfolgenbehandlung gespeichert: gets_s& puts, plus std::stringzum Verketten, was bedeutet, dass ich char*in Ausgabe konvertieren muss . Der Golf, den ich gepostet habe, funktioniert nur stringoder nur iostream.bizarr. Ich muss beide einbeziehen, um <<>>Operatoren mit cin/cout& std::strings zu verwenden. Insgesamt #includefunktioniert die Verwendung beider s um 5 Bytes schlechter, obwohl ich hals deklarieren std::stringund eine separate charDeklaration vermeiden kann . Vorhersehbar kann ich keine Liste der namespace stdHilfeleistungen finden (oder eine Erklärung zum Betreiber).
Level River St

@FDinoff Ich stimme zu, ich würde es normalerweise nicht verwenden scanfund getsaußer beim Golfen, wo Programme sowieso ziemlich unsicher sind. Ich könnte um 5 Bytes verkürzen, -s,99wenn ich getsstattdessen verwenden könnte gets_s, aber ich kann den Compiler nicht dazu bringen, mich zuzulassen. Was mich überrascht ist, wie unsicher C / C ++ im Allgemeinen ist! Vor ein paar Wochen hätte es mich schockiert zu finden, dass _int64 x=1<<ydie falsche Antwort für y größer als 31 ist. Aber jetzt bin ich nur leicht verärgert. Nachdem ich gesehen habe, dass Array-Indizes ohne Fehlermeldung außerhalb der Grenzen liegen, habe ich mich daran gewöhnt. Gibt es eine Möglichkeit, die Überprüfung besser einzuschalten?
Level River St

2

Perl (> = 5,14), 411 403 400 397 400

Bearbeiten : Inline ein Sub, das nur einmal aufgerufen wurde und 8 Zeichen spart.
Bearbeiten 2 : Entfernte ein Element, das .""bei einem frühen Versuch übrig geblieben war.
Bearbeiten 3 : $_Verwenden Sie anstelle einer temporären Variablen, die das Original beibehält , eine, um es unnötig zu machen. Nettogewinn 3 Zeichen.
Bearbeiten 4 : Fehler beim Erkennen eines überfüllten Hauses behoben (2x 3-of-a-kind). kostet 3 Zeichen.

Nicht ganz ein Gewinner, aber der gerade Detektor ist ein interessantes Konzept, denke ich.

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"

Erweiterte Version:

# 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

Verwendung mit 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")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.