É um straight flush?

21

Relacionados: Nomeie a mão de pôquer

Um straight flush é uma mão de pôquer que contém cinco cartas de ordem sequencial, todas do mesmo naipe. Como parte de um straight flush, um ás pode ser classificado acima de um rei ou abaixo de dois. Um ás pode ter uma classificação alta (por exemplo, A ♥ K ♥ Q ♥ J ♥ 10 ♥ é um straight flush com ás), ou baixa (por exemplo, 5 ♦ 4 ♦ 3 ♦ 2 ♦ A ♦ é um flush com cinco altos), mas não pode classificar alto e baixo na mesma mão (por exemplo, Q ♣ K ♣ A ♣ 2 ♣ 3 ♣ é um flush ás-alto, não um flush direto).

Desafio

As Ncartas dadas (em qualquer formato razoável) geram um valor verdadeiro se um straight flush estiver contido na mão de poker.

Entrada

  • Nnúmero de cartões. (Em qualquer formato razoável)

Existem quatro naipes; corações, espadas, diamantes e paus (H, S, D, C).

Cada naipe tem uma carta para os números de 2 a 10, além de 4 cartas 'Á', Ás, Valete, Rainha e Rei (A, J, Q, K)

Nota: Você pode tomar 10 como T

Saída

  • Truthy/Falsy valor

Caso de teste

["AS", "2S", "3S", "4S", "5S"] => true

["3D", "9C", "4S", "KH", "AD", "AC"] => false

["5D", "6D", "7D", "8H", "9D", "10D", "JD"] => false

["JC", "7C", "5D", "8C", "AC", "10C", "9C", "5S"] =>true

[] => false

["AS", "2S", "3S"] => false

["JC", "QC", "KC", "AC", "2C"] => false

[ "2H", "3H", "4H", "5H", "6H", "7H"] => true

Aplicam-se as regras padrão de .

Critérios para ganhar: Código mais curto em cada idioma

Luis felipe De jesus Munoz
fonte
1
Podemos assumir que não haverá duas cartas iguais na mão?
Jo rei
@ JoKing sim, você não terá o mesmo cartão duas ou mais vezes
Luis felipe De jesus Munoz
4
Podemos tomar 10como T?
Kevin Cruijssen
@ JoKing Eu não acho que isso possa acontecer IRL. ;-)
Erik the Outgolfer
4
@EriktheOutgolfer Eu tenho literalmente cerca de 5 pacotes de cartões mistos menos de um metro de distância de mim
Jo rei

Respostas:

15

Python 2 , 95 bytes

lambda a:any(set('A234567891JQKA'[i/4:][:5])<={r['HCSD'[i%4]in r]for r in a}for i in range(40))

Experimente online!

Existem 40 straight flushes possíveis, e isso simplesmente verifica todos eles. Chas Brown economizou 2 bytes; Jo King economizou mais 4.

Lynn
fonte
1
Existem 40, você usou Anas duas extremidades, então acredito que mudar 36para 40deve corrigi-lo.
23618 Jonathan Allan
Opa, eu não sou bom em contar. Eu consertei isso!
Lynn
99 bytes .
Chas Brown
Troque a ordem do valor do naipe e mova a condição if para o índice?
Jo rei
95 bytes
Jo King
8

R , 128 126 94 91 bytes

function(x,r=rle(outer(y<-chartr("J-X","A2-9TJQKAS",LETTERS),y,paste0)%in%x))any(r$l>4&r$v)

Experimente online!

A lógica original foi consideravelmente reduzida por @ J.Doe.

Cria uma matriz de 26 por 26, principalmente sem sentido, mas todas as cartas (com os Ases repetidos na parte inferior) contidas nas linhas 10 a 23 das colunas 3,4,8 e 24. A matriz é criada concatenando todas as combinações de letras maiúsculas alfabeto com as letras J a X substituídas por A, 2-9, T, J, Q, K, A, S via chartr. Temos C, D, H de graça!

O %in%achata a matriz da coluna-sábio num vector. Veja se a codificação de duração da execução é maior que 4 para qualquer execução de TRUEcorrespondências.

ngm
fonte
Uso inteligente de rleAND outer! Isso economiza dois bytes
JayCe 26/07/18
94 bytes. Duas mudanças: usar uma outerchamada simétrica que produz muitos cartões inválidos e usar a coerção vetorial inpara evitar apply. Ambos precisam estar no local para que isso funcione!
J.Doe
2
Muito agradável! Alterou a resposta e a transformou em um wiki da comunidade.
NGM
5

JavaScript (ES6), 116 bytes

a=>[...'CDHS'].some(s=>a.map(c=>m|=c.match(s)&&2<<"234567891JQKA".search(c[0]),m=0)|(g=k=>k&&1+g(k&k/2))(m|m>>13)>4)

Experimente online!

Quão?

scsm

Arnauld
fonte
5
Eu me acostumei tanto à sua linha introdutória de "notação de curry" que sinto falta dela quando não é necessária.
ngm
4

Braquilog , 31 bytes

tᵍkᵐ²cᵐ{ps₅~s"A23456789TJQKA"}ᵉ

Experimente online!

 ᵍ                    Group input by
t                     each element's "tail" (i.e. suit)
kᵐ²                   Knife off the suit character from each element in each array
cᵐ                    Concatenate the elements of each suit array into a string
{               }ᵉ    There exists at least one string in that such that
 p                    it has a permutation
 s₅                   which has a substring of length 5
 ~s                   which is also a substring of
 "A23456789JQKA"
sundar - Restabelecer Monica
fonte
3

Retina 0.8.2 , 66 bytes

J
11
Q
12
K
13
A
1$%'¶14
\d+(.)
$1$&$*
O`
^
¶
((?(1)\1.|¶.+)){5}\b

Experimente online! Explicação:

J
11
Q
12
K
13

Converta os cartões de imagem em seus valores.

A
1$%'¶14

A pode ser 1 ou 14.

\d+(.)
$1$&$*
O`

Converta o valor em unário e coloque-o como sufixo, para que os cartões sejam classificados corretamente.

^
¶
((?(1)\1.|¶.+)){5}\b

Combine 5 cartas que aumentam 1 em cada vez e garanta que o último aumento seja exatamente 1.

Neil
fonte
2

JavaScript (ES6), 106 bytes

h=>h.map(([r,s])=>[..."HSDCA23456789TJQKA"].map(c=>i+=c==s?i*15:c==r?d[i]=1:1,i=0),d=[])|/(,1){5}/.test(d)

Aceita uma matriz de representações de sequência de cartões, substituindo 10por T. Experimente online!

Explicação

Repete cada cartão e define uma bandeira em uma matriz de booleanos usando um índice calculado a partir da combinação exclusiva de sua classificação e naipe. Essa matriz é então especificada para permitir a correspondência de um padrão de 5 valores consecutivos de verdade.

Por exemplo, uma mão com um straight flush pode produzir o seguinte como uma substring da representação completa da cadeia de caracteres da matriz booleana: ,,,,1,1,1,1,1,,,,

Como o primeiro valor da classificação (ou seja, A) é compensado desde o início da string, sempre haverá valores vazios precedendo todos 1os da matriz, garantindo que a representação da string comece com um,

h =>
    h.map(([r, s]) =>                         // destructure card value, e.g. "JH" => ["J", "H"]
        [..."HSDCA23456789TJQKA"].map(c =>    // mapping accounts for both positions of 'A'
            i +=                              // increment index value
            c == s                            // if found index of suit...
                ? i * 15                      // buffer so that cards from different suits cannot be confused
            : c == r                          // if found index of rank...
                ? d[i] = 1                    // set flag to denote card is in hand
            : 1,
            i = 0
        ),
        d = []
    ) |
    /(,1){5}/.test(d)                         // implicitly converts to string joined with a ,
redundância
fonte
2
Agradável. Isso merece mais votos, mas as pessoas tendem a perder o interesse em desafios alguns dias após a publicação inicial.
Rick Hitchcock
2

Java 10, 189 167 165 164 160 157 156 bytes

s->{int i=10;for(;i-->0;)i=s.matches("AKQJT98765432A".substring(i,i+5).replaceAll(".","(?=.*$0\\\\1)").replaceFirst(".1","([HSDC])")+".*")?-2:i;return-1>i;}

Toma a entrada como uma única String delimitada por espaço (ou seja "AS 2S 3S 4S 5S").

-22 bytes graças a @ OlivierGrégoire .
-1 byte graças a @AlexRacer .

Experimente online.

Versão em golf do código que usei para o Projeto Euler # 54 , que fiz principalmente com regexes (por diversão e para aprender mais sobre regexes). Sem regexes, provavelmente teria sido melhor para o desempenho e mais fácil (provavelmente também se aplica ao golfe nesta resposta; daremos uma olhada mais tarde).

Explicação:

s->{                    // Method with String parameter and boolean return-type
  int i=10;for(;i-->0;) //  Loop `i` in the range (10,0]:
    i=s.matches(        //   If the input matches the following regex:
        "AKQJT98765432A".substring(i,i+5)
                        .replaceAll(".","(?=.*$0\\\\1)")
                        .replaceFirst(".1","([HSDC])")
                        //    Five adjacent cards
        +".*")?         //    With optionally zero or more other characters
         -2             //     Set `i` to -2, which also stops the loops at the same time
      :i;               //   Else: leave `i` unchanged to continue
  return-1>i;}          //  Return whether `i` is not -2 (so whether the loop has finished)

Explicação adicional do regex:

  • "AKQJT98765432A".substring(i,i+5) leva cinco cartões adjacentes com base em i
  • .replaceAll(".","(?=.*$0\\\\1)")substitui cada uma dessas cartas por "(?=.*c\\1)"(onde cestá o caractere da carta)
  • .replaceFirst(".1","([HSDC])")substituirá o primeiro \\1por ([HSDC]).

Ou seja, o regex total para verificar se há Straight Flush para cards no intervalo de valores [9,5]se tornará:
^(?=.*9([HSDC]))(?=.*8\\1)(?=.*7\\1)(?=.*6\\1)(?=.*5\\1).*$
(OBSERVAÇÃO: String#matchesadiciona implicitamente o final / o início ^...$para verificar toda a String.) Esse regex:

^(?=.*9([HSDC]))(?=.*8\\1)(?=.*7\\1)(?=.*6\\1)(?=.*5\\1).*$
^                                                         $ Match the entire string
 (?=           )(?=      )(?=      )(?=      )(?=      )    Do positive lookaheads to check
                                                            each card
    .*             .*        .*        .*        .*         With optional leading characters
                                                            in front of every card
                                                        .*  And any trailing characters at
                                                            the end of the entire hand
      9              8         7         6         5        The five adjacent values
        [HSDC]                                              With a suit
       (      )       \\1       \\1       \\1       \\1     which is the same for all cards
Kevin Cruijssen
fonte
1
172 bytes . Eu só joguei golfe na geração regex: ainda é o seu algoritmo.
Olivier Grégoire
1
167 bytes . Eu removi o ".*"+prefixo desnecessário .
Olivier Grégoire
1
@ OlivierGrégoire Obrigado! Bons golfe.
Kevin Cruijssen
1
-1 byte de se romper para fora do loop de em vez de usarf
AlexRacer
1
@AlexRacer Smart, obrigado! E foi capaz de jogar com mais 2 bytes alterando o breakpara i=-2e retornando ao return-1>i;uso da sua abordagem (e mais 2 alterando (.)para .e $1para $0). :)
Kevin Cruijssen
1

Limpo , 145 135 bytes

import StdEnv,Data.List
?l=or[isInfixOf(map hd h)['A234567891JQKA']\\a<-l,b<-l,c<-l,d<-l,e<-l,h<-[[a,b,c,d,e]]|tl(nub(map last h))==[]]

Experimente online!

Simplificado:

? l                                             // function ? taking argument l
  = or [                                        // is at least one of these true
        isInfixOf (map hd h) ['A234567891JQKA'] // do the first characters of a hand appear in this string, in order
        \\ a <- l                               // loop level 1, assigns `a`
           , b <- l                             // loop level 2, assigns `b`
             , c <- l                           // loop level 3, assigns `c`
               , d <- l                         // loop level 4, assigns `d`
                 , e <- l                       // loop level 5, assigns `e`
                   , h <- [[a,b,c,d,e]]         // trick to assign `h`, because it's cheaper than let .. in ..
        | tl (nub (map last h)) == []           // only take the loop iterations where all the suits are the same
       ]
Furioso
fonte
1

Japonês , 37 bytes

Recebe a entrada como uma matriz 2D.

"AJQKA"i1Aò2 q)øUñÌòÏ̦XÌÃËmάú5 á5Ãc

Tente


Explicação

"AJQKA"                                   :String literal
       i1                                 :Insert at (0-based) index 1
         Aò2                              :  Range [2,10]
             q                            :  Join
              )                           :End insert
               ø                          :Does that string contain any element in the following array?
                U                         :Input
                 ñ                        :Sort
                  Ì                       : By last element (grouping suits together)
                   òÏ                     :Partition between X & Y where
                     Ì                    :  Last element of Y
                      ¦                   :  Does not equal
                       XÌ                 :  Last element of X
                         Ã                :End partition
                          Ë               :Map
                           m              :  Map
                            Î             :   First elements (card values)
                             ¬            :  Join
                              ú5          :  Right pad with spaces to length 5
                                 á5       :  Permutations of length 5
                                   Ã      :End map
                                    c     :Flatten
Shaggy
fonte
0

Geléia , 18 bytes

Ṣœc5Uµ13R;1wṪ€ȧEµƇ

Experimente online!

[..., ...][1,13]A23456789TJQK[1,4]CDHS

Formato de saída: lista vazia como falsa, lista não vazia como verdade.

Erik, o Outgolfer
fonte
Não vejo nada nas especificações sugerindo que números inteiros possam ser substituídos pelos naipes e cartões com figuras - perdi alguma coisa?
Shaggy
@ Shagy Suponho que esteja dentro de "qualquer formato razoável", não acho que tenhamos padrões em relação à introdução de cartas de baralho.
Erik the Outgolfer
0

PHP , 264 bytes

Ele ecoa 1se for um straight flush e 0ou nullnão.

Se você nomear o arquivo 1X, poderá salvar, 11 bytespois não precisará alterar $argv[0]. Não tenho certeza no momento por que o nome do arquivo pode quebrá-lo.

Por algum motivo, as seqüências :;<=>são classificadas antes das seqüências 0123456789de caracteres asortem TIO, embora :;<=>tenham valores ASCII 58-62 e 0123456789valores ASCII 48-57. Portanto, se você pegar o código no link TIO ou abaixo e usar o PHPTester com o seguinte conjunto de testes, ele funcionará.

$argb[0] = [".code.tio", "AS", "2S", "3S", "4S", "5S"]; // => true
$argb[1] = [".code.tio", "3D", "9C", "4S", "KH", "AD", "AC"]; // => false
$argb[2] = [".code.tio", "5D", "6D", "7D", "8H", "9D", "TD", "JD"]; // => false
$argb[3] = [".code.tio", "JC", "7C", "5D", "8C", "AC", "TC", "9C", "5S"]; // => true
$argb[4] = [".code.tio", ]; // => false
$argb[5] = [".code.tio", "AS", "2S", "3S"]; // => false
$argb[6] = [".code.tio", "JC", "QC", "KC", "AC", "2C"]; // => false
$argb[7] = [".code.tio", "TC", "JC", "QC", "KC", "AC", "2C"]; // => true
$argb[8] = [".code.tio", "2H", "3H", "4H", "5H", "6H", "7H"]; // => true

for ($z=0; $z<9;$z++){
    $argv=$argb[$z];
    array_shift($argv);
    unset($a,$b,$c,$d,$e,$f,$g,$h,$i);
    $f=false; // not needed, just removes several notices

    // TIO code here

    echo "<br>";

Código TIO

for($b=count($a=$argv);$b;){$a[0]='1X';$a[--$b]=strtr($a[$b],'ATJQK','1:;<=');$a[]=($a[$b][0]==1?">".$a[$b][1]:1);}asort($a);foreach($a as$c){$d[$c[1]][]=$c[0];}foreach($d as$e){if(4<$g=count($e)){for($h=0;$g>$i=4+$h;){$f|=(ord($e[$i])-ord($e[$h++])==4);}}}echo$f;

Experimente online!

Sam Dean
fonte
0

Kotlin , 226 bytes

Utilizado T para 10, para que todos os cartões tenham 2 caracteres.

{h:List<String>->val m=List(4){mutableSetOf<Int>()}
for(c in h)m["CDHS".indexOf(c[1])].add("A23456789TJQK".indexOf(c[0]))
var r=0>1
for(b in m){if(b.contains(0))b.add(13)
for(i in 0..9)r=b.containsAll((i..i+4).toList())||r}
r}

Experimente online!

JohnWells
fonte
0

Pascal (FPC) , 223 216 210 209 bytes

var a,b:char;c:set of byte;i:byte;begin repeat readln(a,b);i:=pos(b,'HDC')*14+pos(a,'23456789TJQK');c:=c+[i];if a='A'then c:=c+[i+13]until eof;i:=0;while not([i..i+4]<=c)or(i mod 14>9)do i:=i+1;write(i<52)end.

Experimente online!

Usa Tpara 10. A entrada contém 1 cartão por linha.

Agora eu jogava tanto que não sei mais como funciona ...

Explicação:

var a,b:char; //for reading cards
    c:set of byte; //this set is for remembering which cards are present in the input
                   //14 numbers used for each suit
    i:byte;
begin
  repeat
    readln(a,b);             //read rank into a, suit into b and a newline
    i:=pos(b,'HDC')*14+pos(a,'23456789TJQK');
        //temporary use i to calculate corresponding number for the card
        //pos() gives 0 if b is not found
        //1st pos() is for the group of numbers for that suit, 2nd pos() is for offset
    c:=c+[i];                //include i into set
    if a='A'then c:=c+[i+13] //if rank is A, include the number at the end of group as well
  until eof;
  i:=0;
  while not(
    ([i..i+4]<=c) //if NOT 5 cards in a row are present...
    and           //while the check is started from 10 (T)...
    (i mod 14<10) //(otherwise, it is checking across 2 different suits)
  )do i:=i+1;     //increment i, otherwise stop
  write(i<52) //if i<=51, there is a straight flush starting at the card corresponding to i
              //(if there isn't a straight flush, i stops at 252 due to i..i+4, I don't know why)
end.
AlexRacer
fonte