Nazwij rękę pokera - edycja 7 kart


11

Wyzwanie:

W tym pytaniu: Wymień rękę pokera, którą musiałeś wziąć z pięciokartowym układem pokera i określ ją. To pytanie jest podobne, z dwoma zwrotami akcji:

Po pierwsze, wynik będzie zapisany małymi literami. Pozwala to na więcej golfa, ponieważ nie musisz się martwić o wielkie litery flushistraight

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

Po drugie, mając popularność Texas Hold'em i 7-kartowego studa, my tutaj, w golfie code, powinniśmy być w stanie zdobyć siedmiokartowego pokera, prawda? Przy zdobywaniu siedmiokartowego układu, użyj pięciu najlepszych kart dla swojego układu i zignoruj ​​dwa, których nie potrzebujesz.

Odniesienie:

Lista rąk pokera: http://en.wikipedia.org/wiki/List_of_poker_hands

Wejście (podnoszone bezpośrednio z poprzedniego wątku)

7 kart z argumentów standardowego lub wiersza poleceń. Karta to dwuliterowy ciąg znaków w formularzu RS, w którym R oznacza rangę, a S jest koloru. W szeregi2- 9(karty), numer T(dziesięć), J(Jack), Q(Queen), K(King), A(ACE). Te strojeS, D, H, Cdla pik, karo, kier i klubów odpowiednio.

Przykład kart

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

Przykład wejścia => pożądany wynik

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

Zauważ, że w drugim przykładzie są właściwie trzy pary, ale możesz użyć tylko pięciu kart, więc tak jest two pair. W piątym przykładzie są zarówno a, jak three of a kindi straightmożliwe, ale a straightjest lepsze, więc wynik straight.

Punktacja

To jest , więc wygrywa najkrótszy kod!

Errata

  1. Nie możesz używać zasobów zewnętrznych.
  2. As jest zarówno wysoki, jak i niski dla stritów.

Miły; Miałem potajemną nadzieję, że ktoś podniesie piłkę. Chciałem tylko zauważyć, że nie miałem żadnych ograniczeń dotyczących wielkich liter w pierwotnym pytaniu (wyjaśnione w komentarzu), więc mogłeś (i większość / wszyscy mieli) wypisać „Straight Flush”. Kapitalizacja IMHO wygląda lepiej.
daniero

Mówisz, że wkład (podnoszony bezpośrednio z poprzedniego wątku) 5 kart. Myślę, że chciałeś zmienić to na 7.
Level River St

@steveverrill Możesz samodzielnie edytować posty na wymianie stosu. Chociaż zrobiłem to dla ciebie tutaj
durron597

Czy dozwolone są zasoby zewnętrzne? Istnieją tabele odnośników, które pozwolą ci po prostu sprawdzić każdą kartę w ręce i uzyskać siłę ręki.
Kendall Frey

Czy as może być niski, jak i wysoki dla strita?
Nick T

Odpowiedzi:


4

Rubinowy 353

Było to oparte na odpowiedzi Chrona z pierwotnego pytania.

Pobiera to dane wejściowe jako argumenty wiersza poleceń. Zasadniczo po prostu iterujemy wszystkie kombinacje rozmiaru 5, aby dowiedzieć się, jaki to rodzaj ręki. Każdy typ rozdania został zmodyfikowany, więc zaczyna się od liczby. („poker królewski” -> „0royal 4flush”, „high card” -> „9high card”). To pozwala nam sortować zwrócone ciągi. Pierwszy ciąg po sortowaniu jest najlepszą możliwą ręką. Więc drukujemy to po usunięciu wszystkich liczb z ciągu.

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

Miły. GSS na końcu może być sub-prawda?
bazzargh

@bazzargh nie musi usuwać wszystkich liczb. Kod łączy 4flush z 1straight lub 0royal, aby uzyskać „0royal 4 flush” lub „1straight 4flush”. Jeśli użyjemy tylko sub, 4 nie zostaną usunięte.
FDinoff,

Daje zły wynik dla AS QS JS TS 9S 5H 5D. To będzie kosztować cię postać!

@ WumpusQ.Wumbley Hmm wydaje się, że jest to błąd w oryginalnym kodzie. Spróbuję później ustalić, na czym polega problem.
FDinoff,

5

Haskell 618 603 598 525 512 504 480 464

Karty pobierane jako wiersz danych wejściowych. Wydaje mi się, że grałem w golfa na śmierć, ale z łatwością mogę zostać pokonany przez ruby ​​itp. Przy użyciu tej samej sztuczki: jeśli wygenerujesz wszystkie permutacje, otrzymasz typy do przodu, których chcesz szukać prostych, a także odwrotne typy do testowania N z rodzaju.

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

Edytowany w celu wstawienia „parowania” i używania prefiksów liczb po obejrzeniu wpisu @ FDinoffa, również skomponował funkcje mapy, aby ogolić jeszcze jeden znak.


Możesz uratować sobie kilka postaci (myślę, że około 5), jeśli się pozbędziesz. "one pair","two pair"jest wtedy krótszyu=" pair" ... "one"++u,"two++u
FDinoff

tak, właśnie wprowadzałem tę zmianę po przeczytaniu twojego kodu. Również technika prefiksu liczby oszczędza mi kolejne 5
bazzargh

2

C ++, 622 553 znaków

cztery niepotrzebne nowe linie dodane poniżej dla przejrzystości.

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

Rzeczy zmieniły się w wersji golfowej:

Rev 1: Zmieniono wszystkie zmienne numeryczne na __int64dla pojedynczej deklaracji.

Rev 1: Przyrost golfa i stan forpętli

Rev 0: Zmieniono stałe ósemkowe na dziesiętne.

Rev 0: Zmieniono ifinstrukcje na przypisania z operatorem warunkowym. Rev 1: Przeorganizowano dalej w jedno wyrażenie dla t. Wymagało to nowej zmiennej vdla jednej z wartości pośrednich

Rev 0: Usunięto pełne dane wyjściowe. Wysyła tylko najlepszą ogólną rękę.

Rev 0: Zrezygnowałem z kompresji tekstu wyjściowego (trudne w C, ponieważ nie można łączyć łańcuchów za pomocą operatora +). Pisanie „flush” tylko raz zaoszczędziło mi 12 znaków, ale kosztowało mnie 15, co pogorszyło mnie o 3 znaki. Więc napisałem to 3 razy zamiast tego. Rev 1: używany std::stringzamiast char[]sugerowanego przez FDinoffa, umożliwiający konkatenację +.

Wersja bez golfa, 714 niekomentowanych znaków spoza białej przestrzeni.

Pętle przechodzą przez wszystkie 21 możliwych rąk, które można wykonać z 7 kart i za każdym razem odrzucają 2 karty. Kolor i ranga pięciu wybranych kart są sumowane w zmiennych f i p z inną cyfrą ósemkową dla każdego koloru / rangi. Wykonuje się różne operacje bitowe w celu określenia rodzaju ręki, która jest następnie zapisywana w t (wszystkie 21 możliwości są wyprowadzane w wersji bez golfa.) Na koniec wyprowadzana jest najlepsza możliwa ręka.

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

Wyjście bez golfa

wprowadź opis zdjęcia tutaj


Ponieważ mówisz, że używasz c ++, możesz użyć, <string>który obsługuje + do łączenia łańcuchów. Co oznacza, że ​​prawdopodobnie będziesz mógł użyć <iostream>i użyć. coutJednak nie wiem, czy któryś z nich doprowadziłby do zmniejszenia liczby znaków.
FDinoff,

@FDinoff co mogłem zapisać: " pair flush flush straight of a kind"= 35 znaków. Po dodaniu #includeoszczędności są minimalne, należy wziąć pod uwagę dodatkowe ",=+i deklaracje stałych. Również jestem nowy w C ++ i walczę z ustawieniami IDE i kompilatora (zmusza mnie to do używania, scanf_sa printf_szamiast starych „niebezpiecznych” wersji i pomocy w naprawianiu się w kółko.) coutMoże trochę pomóc, to zależy ode mnie zrobić listę, ale prawdopodobnie dla innego programu. Rzeczą, która coutmnie zabija , jest using namespace stdto, że nie wiem, czy istnieje sposób, aby uniknąć napisania tego wszystkiego.
Level River St

Prawie nigdy nie powinieneś potrzebować printf i scanf, ponieważ używasz c ++. Są inne (bezpieczniejsze) robienie tego samego. Możesz użyć, std::coutaby ominąćusing namespace std
FDinoff

@FDinoff thx za wskazówkę. W mojej ostatniej edycji zapisałem 18 bajtów w różnych operacjach na łańcuchach: gets_si putsplus std::stringdo konkatenacji, co oznacza, że ​​muszę przekonwertować char*na wyjście. Golf I pisał prace z tylko stringlub po prostu iostream.Bizarrely muszę to zarówno w obsłudze <<>>podmiotów z cin/cout& std::strings. Ogólnie rzecz biorąc, użycie obu #includes daje 5 bajtów gorszych, mimo że mogę zadeklarować hjako a std::stringi uniknąć osobnej chardeklaracji. Jak można się spodziewać, nie mogę znaleźć listy namespace stdpomocy (lub wyjaśnienia na temat operatora).
Level River St

@FDinoff Zgadzam się, normalnie nie używałbym scanfi gets, z wyjątkiem golfa, gdzie programy są dość niebezpieczne. Mógłbym skrócić o 5 bajtów, -s,99gdybym mógł użyć getszamiast gets_s, ale nie mogę zmusić kompilatora, aby mi pozwolił. Zaskakuje mnie, jak ogólnie niebezpieczne jest C / C ++! Kilka tygodni temu zszokowałoby mnie stwierdzenie, że _int64 x=1<<ydaje to złą odpowiedź na więcej niż 31 lat. Ale teraz jestem lekko zirytowany. Widząc rzeczy, w których indeksy tablic wykraczają poza granice bez komunikatu o błędzie, przywykłem do tego. Czy jest jakiś sposób na lepsze włączenie sprawdzania?
Level River St

2

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

Edycja : wstawił sub, który został wywołany tylko raz, oszczędzając 8 znaków.
Edycja 2 : usunęłam .""resztkę z wczesnej próby
Edycja 3 : zamiast zmiennej tymczasowej, która zachowuje oryginał $_, użyj jednej, aby uczynić go niepotrzebnym. Zysk netto 3 znaki.
Edycja 4 : naprawiono błąd w wykrywaniu przepełnienia full house'a (2x 3 w swoim rodzaju). kosztuje 3 znaki.

Nie całkiem zwycięzca, ale myślę, że prosty detektor jest interesującą koncepcją.

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"

Wersja rozszerzona:

# 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

użycie z 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")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.