Nomina la mano di poker - Edizione 7 carte


11

La sfida:

In questa domanda: nomina la mano di poker che hai dovuto prendere una mano di poker a cinque carte e identificala. Questa domanda è simile, con due colpi di scena:

Innanzitutto, l'output sarà in tutte le lettere minuscole. Ciò consente di giocare a più golf, poiché non devi preoccuparti della capitalizzazione di flushestraight

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

In secondo luogo, con la popolarità del Texas Hold'em e del 7 card stud, qui al code golf dovremmo essere in grado di segnare una mano di poker con sette carte , vero? Quando ottieni una mano da sette carte, usa le cinque carte migliori per la tua mano e ignora le due che non ti servono.

Riferimento:

Elenco delle mani di poker: http://en.wikipedia.org/wiki/List_of_poker_hands

Input (sollevato direttamente dal thread precedente)

7 carte da argomenti stdin o commandline. Una carta è una stringa di due lettere sul modulo RS, dove R è il rango e S è il seme. I gradi sono 2- 9(carte numeriche), T(dieci), J(Jack), Q(regina), K(re), A(asso). Gli abiti sono S, D, H, Cper picche, quadri, cuori e club rispettivamente.

Esempio di carte

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

Esempio di input => output desiderato

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

Si noti che nel secondo esempio ci sono in realtà tre coppie, ma è possibile utilizzare solo cinque carte, quindi è two pair. Nel quinto esempio, ci sono sia a three of a kindche a straightpossibili, ma a straightè migliore, quindi output straight.

punteggio

Questo è , quindi vince il codice più corto!

Errata

  1. Non è possibile utilizzare risorse esterne.
  2. L'asso è sia alto che basso per i rettilinei.

Bello; Speravo segretamente che qualcuno potesse raccogliere la palla. Volevo solo notare che non avevo alcuna restrizione sulla capitalizzazione nella domanda originale (chiarita in un commento), quindi potresti (e la maggior parte / tutti hanno fatto) output "Straight Flush". IMHO in maiuscolo sembra migliore.
daniero,

Dici input (estratto direttamente dal thread precedente) 5 carte. Penso che volevi cambiarlo in 7.
Level River St

@steveverrill Puoi modificare tu stesso i post sullo scambio di stack. Anche se l'ho fatto per te qui
durron597,

Sono consentite risorse esterne? Ci sono tabelle di ricerca che ti permetteranno semplicemente di cercare ogni carta nella mano e ottenere una forza della mano.
Kendall Frey,

L'asso può essere basso o alto per i rettilinei?
Nick T

Risposte:


4

Rubino 353

Questo si basava sulla risposta di Chron dalla domanda originale.

Questo accetta input come argomenti della riga di comando. Fondamentalmente ripetiamo tutte le combinazioni della dimensione 5 per ottenere che tipo di mano è. Ogni tipo di mano è stato modificato in modo che inizi con un numero. ("scala reale" -> "0royal 4flush", "carta alta" -> "carta 9high"). Questo ci consente di ordinare le stringhe che sono state restituite. La prima stringa dopo l'ordinamento è la migliore mano possibile. Quindi lo stampiamo dopo aver rimosso tutti i numeri dalla stringa.

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

Bello. Il gsub alla fine può essere solo un sub giusto?
bazzargh,

@bazzargh no ha bisogno di rimuovere tutti i numeri. Il codice concatena 4flush con 1straight o 0royal per ottenere "0royal 4 flush" o "1straight 4flush". Se utilizziamo solo sub il 4 non verrebbe rimosso.
FDinoff,

Fornisce il risultato sbagliato per AS QS JS TS 9S 5H 5D. Ti costerà un personaggio!

@ WumpusQ.Wumbley Hmm questo sembra essere un bug nel codice originale. Proverò a capire qual è il problema più tardi.
FDinoff,

5

Haskell 618603 598 525 512 504 480 464

Carte prese come linea di input. Penso di aver giocato a golf fino alla morte, ma sarò facilmente battuto dal rubino ecc. Usando lo stesso trucco: se generi tutte le permutazioni, ottieni i tipi in avanti che vuoi cercare rettilinei, più i tipi inversi che vuoi per testare N di un tipo.

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

Modificato per incorporare la "coppia" e utilizzare i prefissi numerici dopo aver visto la voce di @ FDinoff, ha anche composto le funzioni della mappa per radere un altro carattere.


Puoi salvarti un paio di personaggi (credo circa 5) se ti sbarazzi di te. "one pair","two pair"è più breve di allorau=" pair" ... "one"++u,"two++u
FDinoff del

sì, stavo solo apportando quel cambiamento dopo aver letto il tuo codice. Anche la tecnica del prefisso numerico mi fa risparmiare un altro 5
bazzargh

2

C ++, 622 553 caratteri

quattro righe inutili aggiunte di seguito per maggiore chiarezza.

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

Le cose sono cambiate nella versione golfata:

Rev 1: Modificate tutte le variabili numeriche in __int64per una singola dichiarazione.

Rev 1: Incremento golfizzato e condizione dei forloop

Rev 0: Costanti ottali modificate in decimali.

Rev 0: Modifiche ifapportate alle assegnazioni con operatore condizionale. Rev 1: Riorganizzato ulteriormente in una singola espressione per t. Ciò ha richiesto una nuova variabile vper uno dei valori intermedi

Rev 0: output dettagliato cancellato. Produce solo la migliore mano generale.

Rev 0: Mi sono arreso a comprimere il testo di output (difficile in C perché non puoi concatenare le stringhe usando l'operatore +). Scrivere "flush" solo una volta mi ha salvato 12 caratteri ma mi è costato 15, rendendomi 3 caratteri peggiori nel complesso. Quindi l'ho appena scritto 3 volte. Rev 1: usato al std::stringposto di char[]quello suggerito da FDinoff, rendendo possibile la concatenazione con +.

Versione non golfata, 714 caratteri non spazi bianchi non commentati.

Passa attraverso tutte le 21 mani possibili che possono essere fatte da 7 carte e respinge 2 carte ogni volta. Il seme e il rango delle cinque carte scelte sono sommati nelle variabili f e p con una cifra ottale diversa per ogni seme / rango. Vengono eseguite varie operazioni di bit per determinare il tipo di mano, che viene quindi memorizzato in t (tutte le 21 possibilità sono emesse nella versione non controllata.) Infine viene emessa la migliore mano possibile.

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

Uscita non golfata

inserisci qui la descrizione dell'immagine


Dal momento che dici che stai usando c ++ puoi usare <string>che supporta + per la concatenazione di stringhe. Ciò significa che probabilmente potresti usare <iostream>e usare. coutTuttavia, in realtà non so se qualcuno di questi porterebbe a un numero di caratteri inferiore.
FDinoff,

@FDinoff cosa potrei salvare: " pair flush flush straight of a kind"= 35 caratteri. Una volta aggiunti i #includerisparmi sono minimi, quindi è necessario considerare extra ",=+e dichiarazioni di costanti. Inoltre sono nuovo di C ++ e alle prese con le impostazioni IDE e del compilatore (mi costringe a usare scanf_se printf_sinvece delle vecchie versioni "non sicure" e l'aiuto per risolverlo gira in tondo.) coutPotrebbe aiutare un po ', è per me fare la lista, ma probabilmente per un altro programma. La cosa che uccide coutper me è using namespace stdche non so se c'è un modo per evitare di scrivere tutto ciò.
Level River St

Non dovresti quasi mai aver bisogno di printf e scanf poiché stai usando c ++. Ci sono altri (più sicuri) era fare la stessa cosa. Si potrebbe usare std::coutper aggirare ilusing namespace std
FDinoff il

@FDinoff grazie per il suggerimento. Nella mia ultima modifica ho salvato 18 byte con una diversa gestione delle stringhe: gets_s& puts, più std::stringper concatenare, il che significa che devo convertire char*in output. Il golf che ho pubblicato funziona solo con Bizarrely stringo iostream.devo includerli entrambi per usare gli <<>>operatori con cin/cout& std::strings. Nel complesso, usando entrambi i #includes si risolve 5 byte peggio, anche se posso dichiarare hcome un std::stringed evitare una chardichiarazione separata . Com'era prevedibile, non riesco a trovare un elenco di ciò che è in namespace stdaiuto (o una spiegazione sull'operatore.)
Level River St

@FDinoff Sono d'accordo, normalmente non userei scanfe gets, fatta eccezione per il golf, in cui i programmi sono comunque poco sicuri. Potrei accorciare di 5 byte -s,99se potessi usare al getsposto di gets_s, ma non riesco a farmi compilare il compilatore. Ciò che mi sorprende è quanto C / C ++ non sia sicuro in generale! Qualche settimana fa mi avrebbe scioccato scoprire che _int64 x=1<<ydà la risposta sbagliata per te maggiore di 31. Ma ora sono solo leggermente infastidito. Avendo visto le cose con i parametri degli array andare oltre i limiti senza alcun messaggio di errore, mi sono abituato. Esiste un modo per attivare un controllo migliore?
Level River St

2

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

Modifica : inline un sub chiamato solo una volta, risparmiando 8 caratteri.
Modifica 2 : rimosso un elemento .""rimasto da un tentativo iniziale
Modifica 3 : anziché una variabile temporanea che conserva l'originale $_, utilizzarne uno per renderlo non necessario. Guadagno netto 3 caratteri.
Modifica 4 : risolto errore nel rilevare full-over pieno (2x 3-of-a-kind). costa 3 caratteri.

Non proprio un vincitore, ma il rilevatore dritto è un concetto interessante, credo.

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"

Versione estesa:

# 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

utilizzo con 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")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.