¿Es esta una escalera de color?

21

Relacionado: nombra la mano de póker

Una escalera de color es una mano de póker que contiene cinco cartas de rango secuencial, todas del mismo palo. Como parte de una escalera de color, un as puede clasificarse por encima de un rey o por debajo de un dos. Un as puede ser alto (p. Ej., A ♥ K ♥ Q ♥ J ♥ 10 ♥ es una escalera de color as-alto) o bajo (p. Ej., 5 ♦ 4 ♦ 3 ♦ 2 ♦ A ♦ es una escalera de cinco colores), pero no puede clasificar tanto alto como bajo en la misma mano (por ejemplo, Q ♣ K ♣ A ♣ 2 ♣ 3 ♣ es una escalera de color as-high, no una escalera de color).

Reto

Las Ncartas dadas (en cualquier formato razonable) generan un valor verdadero si hay una escalera de color en la mano de póker.

Entrada

  • NNumero de tarjetas. (En cualquier formato razonable)

Hay cuatro trajes; corazones, picas, diamantes y tréboles (H, S, D, C).

Cada palo tiene una carta para los números del 2 al 10, más 4 cartas de 'imagen', as, jota, reina y rey (A, J, Q, K)

Nota: Puedes tomar 10 como T

Salida

  • Truthy/Falsy valor

Caso de prueba

["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

Aplican reglas estándar de .

Criterios ganadores: código más corto en cada idioma

Luis felipe De jesus Munoz
fuente
1
¿Podemos suponer que no habrá dos cartas iguales en la mano?
Jo King
@JoKing sí, no tendrás la misma tarjeta dos veces o más
Luis felipe De jesus Munoz
44
¿Podemos tomar 10como T?
Kevin Cruijssen
@JoKing No creo que eso pueda suceder IRL. ;-)
Erik the Outgolfer
44
@EriktheOutgolfer Literalmente tengo alrededor de 5 paquetes de cartas mixtas a menos de un metro de mí
Jo King

Respuestas:

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))

Pruébalo en línea!

Hay 40 posibles descargas directas, y esto simplemente las verifica a todas. Chas Brown ahorró 2 bytes; Jo King salvó 4 más.

Lynn
fuente
1
Hay 40, que utilizó Aen ambos extremos por lo que creo cambiando 36a 40debe solucionarlo.
Jonathan Allan
Vaya, ¿no soy bueno contando? ¡Lo arreglé!
Lynn
99 bytes .
Chas Brown
¿Cambiar el orden de valor del traje y mover la condición if al índice?
Jo King
95 bytes
Jo King
8

R , 128126 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)

Pruébalo en línea!

La lógica original acortada considerablemente por @ J.Doe.

Hace una matriz de 26 por 26 con mayormente sin sentido, pero todas las cartas (con los Ases repetidos en la parte inferior) contenidas en las filas 10 a 23 de las columnas 3,4,8 y 24. La matriz se crea concatenando todas las combinaciones de mayúsculas alfabeto con letras J a X reemplazadas por A, 2-9, T, J, Q, K, A, S vía chartr. ¡Tenemos C, D, H gratis!

El %in%aplana la matriz en forma de columna en un vector. Luego, vea si la codificación de longitud de ejecución es mayor que 4 para cualquier ejecución de TRUEcoincidencias.

ngm
fuente
Uso inteligente de rleAND outer! Esto ahorra dos bytes
JayCe
94 bytes. Dos cambios: usar una outerllamada simétrica que produce muchas tarjetas inválidas, y usar la coerción vectorial de inpara evitar apply. ¡Ambos tienen que estar en su lugar para que esto funcione!
J.Doe
2
¡Muy agradable! Cambió la respuesta y la convirtió en una wiki comunitaria.
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)

Pruébalo en línea!

¿Cómo?

sdosmetro

Arnauld
fuente
55
Me he acostumbrado tanto a su línea introductoria de "notación curry" que la extraño cuando no es necesaria.
ngm
4

Brachylog , 31 bytes

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

Pruébalo en línea!

 ᵍ                    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 - Restablece a Monica
fuente
3

Retina 0.8.2 , 66 bytes

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

Pruébalo en línea! Explicación:

J
11
Q
12
K
13

Convierta las tarjetas de imágenes en sus valores.

A
1$%'¶14

A puede ser 1 o 14.

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

Convierta el valor en unario y sufíjelo para que las tarjetas se ordenen correctamente.

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

Haga coincidir 5 cartas que aumenten en 1 cada vez y asegúrese de que el último aumento fue exactamente 1.

Neil
fuente
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)

Acepta una serie de representaciones en cadena de tarjetas, reemplazando 10por T. Pruébalo en línea!

Explicación

Itera sobre cada carta y establece una bandera en una matriz de booleanos usando un índice calculado a partir de la combinación única de su rango y palo. Esta matriz se encadena para permitir la coincidencia de un patrón de 5 valores de verdad consecutivos.

Por ejemplo, una mano con una escalera de color puede producir lo siguiente como una subcadena de la representación de cadena completa de la matriz booleana: ,,,,1,1,1,1,1,,,,

Debido a que el primer valor de rango (es decir, A) está desplazado desde el inicio de la cadena, siempre habrá valores vacíos que preceden a todos 1en la matriz, asegurando que la representación de la cadena comenzará con un,

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 ,
redundancia
fuente
2
Agradable. Esto merece más votos, pero la gente tiende a perder interés en los desafíos un par de días después de la publicación 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 la entrada como una sola cadena delimitada por espacios (es decir "AS 2S 3S 4S 5S").

-22 bytes gracias a @ OlivierGrégoire .
-1 byte gracias a @AlexRacer .

Pruébalo en línea.

Versión de golf del código que he usado para el Proyecto Euler # 54 , que hice principalmente con expresiones regulares (por diversión y para aprender más sobre expresiones regulares). Sin expresiones regulares, probablemente hubiera sido mejor para el rendimiento y más fácil (probablemente también se aplica para jugar golf esta respuesta; lo veremos más adelante).

Explicación:

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)

Explicación adicional de expresiones regulares:

  • "AKQJT98765432A".substring(i,i+5) toma cinco cartas adyacentes basadas en i
  • .replaceAll(".","(?=.*$0\\\\1)")reemplaza cada una de esas cartas con "(?=.*c\\1)"(donde cestá el personaje de la carta)
  • .replaceFirst(".1","([HSDC])")luego reemplazará el primero \\1con ([HSDC]).

Es decir, la expresión regular total para verificar la Escalera de color para las cartas en el rango de valor [9,5]se convertirá en:
^(?=.*9([HSDC]))(?=.*8\\1)(?=.*7\\1)(?=.*6\\1)(?=.*5\\1).*$
(NOTA: String#matchesagrega implícitamente el final / inicio ^...$para verificar toda la Cadena). Esta expresión regular:

^(?=.*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
fuente
1
172 bytes . Solo jugué al golf con la generación de expresiones regulares: sigue siendo su algoritmo.
Olivier Grégoire
1
167 bytes . Eliminé el ".*"+prefijo innecesario .
Olivier Grégoire
1
@ OlivierGrégoire Gracias! Bonitos campos de golf.
Kevin Cruijssen
1
-1 byte si se sale del bucle en lugar de usarf
AlexRacer
1
@AlexRacer Smart, gracias! Y ha sido capaz de campo de 2 bytes más de cambiar la breaka i=-2y la vuelta a return-1>i;la utilización de su enfoque (y 2 más cambiante (.)a .y $1a $0). :)
Kevin Cruijssen
1

Limpio , 145135 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))==[]]

Pruébalo en línea!

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
       ]
Οurous
fuente
1

Japt , 37 bytes

Toma la entrada como una matriz 2D.

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

Intentalo


Explicación

"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
Lanudo
fuente
0

Jalea , 18 bytes

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

Pruébalo en línea!

[..., ...][1,13]UNA23456789TJQK[1,4 4]doreHS

Formato de salida: lista vacía como falsa, lista no vacía como verdadera.

Erik el Outgolfer
fuente
No veo nada en las especificaciones que sugiera que los enteros se puedan sustituir por los palos y las tarjetas con imágenes. ¿Me perdí algo?
Shaggy
@ Shaggy Supongo que está dentro de "cualquier formato razonable", no creo que tengamos valores predeterminados con respecto a la entrada de cartas de juego.
Erik the Outgolfer
0

PHP , 264 bytes

Se hace eco de 1si se trata de una escalera de color y 0, o nullen caso contrario.

Si nombra el archivo 1X, puede guardarlo 11 bytesya que no necesita cambiarlo $argv[0]. No estoy seguro en este momento por qué el nombre de archivo puede romperlo.

Por alguna razón, las cadenas :;<=>solucionarse antes de que las cadenas 0123456789de asorten TIO a pesar de :;<=>tener valores ASCII 58-62 y 0123456789tienen valores ASCII 48-57. Entonces, si toma el código del enlace TIO o inferior y usa PHPTester con el siguiente conjunto de pruebas, funciona.

$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;

Pruébalo en línea!

Sam Dean
fuente
0

Kotlin , 226 bytes

Usé T para 10, por lo que todas las cartas tienen 2 caracteres de longitud.

{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}

Pruébalo en línea!

JohnWells
fuente
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.

Pruébalo en línea!

Usos Tpara 10. La entrada contiene 1 tarjeta por línea.

Ahora lo jugué tanto que ya no sé cómo funciona ...

Explicación:

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
fuente