Word Poker, ¿quién gana?

13

La entrada será dos palabras de cinco letras. En realidad, no tienen que ser palabras de diccionario, solo cinco letras cada una, todas en minúsculas o mayúsculas, según su elección. Solo aparecerá AZ en las palabras de entrada y siempre tendrán 5 caracteres de longitud.

Su programa consiste en calificarlos a ambos como si fueran manos de póker y dar salida a la mano más alta. Por supuesto, los trajes no se aplicarán aquí, solo las clasificaciones, por lo que no hay rubores.

El sistema típico de clasificación de póker dice: '1 par', '2 pares', '3 de un tipo', 'recto', 'full house', '4 de un tipo', '5 de un tipo', y por supuesto existe la posibilidad de que la mano (o la palabra en este caso) no valga nada.

En el caso de los empates , las letras más cercanas a A se consideran más altas, por lo que un par de As supera a un par de Bs. En algunos casos, ambas manos pueden ser idénticas, pero en un orden diferente (o no), en ese caso, generar una mano o una versión recurrida de la misma.

Esta página externa contiene información sobre cómo identificar al ganador y, especialmente, aborda los lazos dentro de las clasificaciones específicas, en caso de que no esté familiarizado con la puntuación de las manos de póker.

En el caso de las rectas : las letras deben estar adyacentes en el alfabeto y no se les permite envolverlas. Entonces, 'defgh' en cualquier orden es una recta, 'xyzab' no lo es.

Ejemplos de cómo anotar una sola mano:

word   | scored as
---------------------
ccccc  | 5 of a kind     <-- highest ranking
woooo  | 4 of a kind
opopo  | full house
vurst  | straight
vovvu  | 3 of a kind
ppoww  | 2 pairs
upper  | 1 pair
kjsdf  | high card only (in this case D) <-- lowest ranking

Entonces el programa realmente producirá resultados como este:

input        |  output
-----------------------
voviu,kjsdf  |  voviu     because a pair beats nothing 
opoqo,upper  |  opoqo     because 3 of a kind beats a pair
woooo,ggegg  |  ggegg     because 4 Gs beats 4 Os
queue,hopup  |  queue     because 2 pairs beats 1 pair
lodpl,ddkop  |  ddkop     because pair DD beats pair LL
huhyg,hijht  |  huhyg     both have pair HH, but G beats I
ddffh,ccyyz  |  ccyyz     both have 2 pairs, but CC(yyz) beats DD(ffh)
okaok,nkunk  |  nkunk     KK ties with KK, but NN beats OO
abcdf,bcdef  |  bcdef     because it is a straight
qtery,retyq  |  qtery     identical! so doesnt matter
abedc,vyxwz  |  abedc     because it is a "higher" straight
hhhij,hijkl  |  hijkl     because straight beats 3 of a kind
aaabb,zzzzz  |  zzzzz     because nothing beats 5 of a kind

El orden de las letras tanto en la entrada como en la salida es irrelevante, por lo que el orden en la salida puede ser diferente al de la entrada, pero el mismo inventario de letras debe estar presente.

La salida debe contener exactamente cinco letras, ni más ni menos.

Se aplican las reglas habituales de codegolf. El código más corto gana.

Pulpo
fuente

Respuestas:

4

JavaScript ( 224 218 213 bytes)

s=>t=>(v=s=>(o={},l=n=0,z=3.5,[...s].sort().map(c=>(n+=o[c]=-~o[c],z*=!l|l+1==(l=c.charCodeAt()))),[n+z,Object.keys(o).sort((a,b)=>o[b]-o[a]||(o[b]>o[a]?1:-1))]),w=v(s),x=v(t),w[0]>x[0]||w[0]==x[0]&&w[1]<x[1]?s:t)

Sin golf:

s=>t=>(
  v=s=>(
    o={},
    l=n=0,
    z=3.5,
    [...s].sort().map(c=>(
      n+=o[c]=-~o[c],
      z*=!l|l+1==(l=c.charCodeAt())
    )),
    [n+z,Object.keys(o).sort((a,b)=>o[b]-o[a]||(o[b]>o[a]?1:-1))]
  ),
  w=v(s),x=v(t),
  w[0]>x[0] || w[0]==x[0] && w[1]<x[1] ? s : t
)

Después de las map()carreras, n + zdetermina la clasificación de una mano:

ingrese la descripción de la imagen aquí

(Puede entender por qué inicialicé za 3.5.)

En caso de empate, Object.keys(o).sort()se utiliza para determinar la mano de mayor rango.

Retazo:

f=

s=>t=>(v=s=>(o={},l=n=0,z=3.5,[...s].sort().map(c=>(n+=o[c]=-~o[c],z*=!l|l+1==(l=c.charCodeAt()))),[n+z,Object.keys(o).sort((a,b)=>o[b]-o[a]||(o[b]>o[a]?1:-1))]),w=v(s),x=v(t),w[0]>x[0]||w[0]==x[0]&&w[1]<x[1]?s:t)

console.log(/voviu/.test(f('voviu')('kjsdf')))       //because a pair beats nothing 
console.log(/opoqo/.test(f('opoqo')('upper')))       //because 3 of a kind beats a pair
console.log(/ggegg/.test(f('woooo')('ggegg')))       //because 4 Gs beats 4 Os
console.log(/queue/.test(f('queue')('hopup')))       //because 2 pairs beats 1 pair
console.log(/ddkop/.test(f('lodpl')('ddkop')))       //because pair DD beats pair LL
console.log(/huhyg/.test(f('huhyg')('hijht')))       //both have pair HH, but G beats I
console.log(/ccyyz/.test(f('ddffh')('ccyyz')))       //both have 2 pairs, but CC(yyz) beats DD(ffh)
console.log(/nkunk/.test(f('okaok')('nkunk')))       //KK ties with KK, but NN beats OO
console.log(/bcdef/.test(f('abcdf')('bcdef')))       //because it is a straight
console.log(/qtery|retyq/.test(f('qtery')('retyq'))) //identical! so doesnt matter
console.log(/abedc/.test(f('abedc')('vyxwz')))       //because it is a "higher" straight
console.log(/hijkl/.test(f('hhhij')('hijkl')))       //because straight beats 3 of a kind
console.log(/zzzzz/.test(f('aaabb')('zzzzz')))       //because nothing beats 5 of a kind

Rick Hitchcock
fuente
3

Jalea ,  28 27 29  27 bytes

+2 y luego -2 arreglan un error, luego vuelven a jugar al golf.

FI=1ȦḤW
OµNĠLÞṚịµL€+Ç,N
ÇÞṪ

Un enlace monádico que toma una lista de "manos" y devuelve (uno de) los ganadores.

Funciona para entradas en mayúsculas o en minúsculas.
(... pero no mezclado, para eso anteponer la línea final con Œlo Œu).

Pruébalo en línea! o ver el conjunto de pruebas .

¿Cómo?

FI=1ȦḤW - Link 1, straight offset: grouped and reverse sorted hand ordinals
        -                     e.g. [[-101],[-100],[-99],[-98],[-97]]
F       - flatten                  [-101,-100,-99,-98,-97]
 I      - increments               [1,1,1,1]
  =1    - equal 1? (vectorises)    [1,1,1,1]
    Ȧ   - any and all?             1
     Ḥ  - double                   2
      W - wrap in a list           [2]
        -   The purpose of this is so that when "a" from Link 2 represents a straight we
        -   get [2], whereas for any other hand we get [0]. Adding the [2] to [1,1,1,1,1]
        -   (the lengths of a straight's groups) yields [3,1,1,1,1], placing it between
        -   three of a kind, [3,1,1], and a full house, [3,2], as required.

OµNĠLÞṚịµL€+Ç,N - Link 2, hand rank key function: list of characters       e.g. "huhyg"
O               - cast to ordinals                                [104,117,104,121,103]
 µ              - monadic chain separation, call that o
  N             - negate (to give them a reverse-sort order) [-104,-117,-104,-121,-103]
   Ġ            - group indices by value                            [[4],[2],[1,3],[5]]
     Þ          - sort by key function:
    L           -   length                                          [[4],[2],[5],[1,3]]
      Ṛ         - reverse                                           [[1,3],[5],[2],[4]]
       ị        - index into o                       [[-104,-104],[-103],[-117],[-121]]
        µ       - monadic chain separation (call that a)
         L€     - length of €ach                                              [2,1,1,1]
            Ç   - call last link (2) as a monad -> [isStraight? * 2]                [0]
           +    - addition (vectorises)                                       [2,1,1,1]
              N - negate o                                [[104,104],[103],[117],[121]]
             ,  - pair                        [[2,1,1,1],[[104,104],[103],[117],[121]]]
                -   now sorting by this will first be comparing the hand class, and if
                -   and only if they match comparing the card values in the required order.

ÇÞḢ - Main link: list of lists of characters (list of hands)
 Þ  - sort by key function:
Ç   -   last link (2) as a monad
  Ṫ - tail (best or an equal-best hand)
Jonathan Allan
fuente
Muy corto en comparación con lo que estoy haciendo en JS 0.o
Stephen
3
@StephenS Bienvenido a PPCG, donde haces algo en un lenguaje que no es de golf y luego alguien hace algo en Jelly, 05AB1E, Pyth, CJam, etc. que es más corto que el nombre de tu idioma: I: P
HyperNeutrino
1
@StephenS: JS debe competir con JS. ¡No permita que los idiomas de golf le impidan presentar soluciones bien pensadas en otros idiomas!
Jonathan Allan
@JonathanAllan me disuade de poner demasiado esfuerzo en pensar demasiado y abstraer un problema que se puede resolver en ~ 25 caracteres, aquí está el violín en el que estaba trabajando: escribí toda la plantilla y nada del código real
Stephen
Esto es asombroso, pero recientemente agregué un caso de prueba que no calcula, específicamente ["hhhij", "hijkl"]. ¿Creo que es por la forma en que clasificas una escalera como [3,1,1,1,1]?
Pulpo
3

JavaScript ( 250 247 232 bytes)

S=d=>(x={},l=99,h=s=0,[...d].map(v=>x[v]=-~x[v]),Object.keys(x).map(v=>(c=91-v.charCodeAt(),t=x[v],s+=1e4**t,c<x[t]?0:x[t]=c,g=(h=c>h?c:h)-(l=c<l?c:l))),[5,4,3,2,1].map(v=>s+=0|x[v]**v),s+(s<5e7&&g<5?1e13:0)),C=a=>b=>(S(a)>S(b)?a:b)

Código no protegido y casos de prueba en JSFiddle: https://jsfiddle.net/CookieJon/8yq8ow1b/

Ahorré algunos bytes gracias a @RickHitchcock. @StephenS & @Arnauld

Con baches
fuente
Esto es lo que estaba tratando de hacer pero no tenía idea de cómo hacerlo.
Stephen
¡Ni lo hice hasta después de empezar! :-)
Bumpy
s=0,h=0=> s=h=0Creo
Stephen
1
Se corrigió ahora después de muchos tirones de cabello. Determinar el desempate en los casos en que la mano es la misma Y los caracteres más bajos en el primer y segundo grupo más grande fueron el mismo asesino (¿¡¿¡¿¡¿¡¿¡¡¡¿¡¿¡¡33 bytes más o menos SOLO para eso !?) :-(
Bumpy
x[v]=x[v]?++x[v]:1 puede llegar a ser x[v]=(x[v]|0)+1 , ahorrando 3 bytes.
Rick Hitchcock
2

Python 2.7, 242 223 bytes

from collections import*
s=sorted
f=lambda x,y:s(map(lambda h:(lambda (r,n):((3,1.5)if len(r)==5 and ord(r[0])+4==ord(r[4])else n,[-ord(d) for d in r],h))(zip(*s(Counter(h).items(),key=lambda z:(-z[1],z[0])))),(x,y)))[1][2]

Similar en concepto básico a los ejemplos de JavaScript (ordenar por fuerza manual con una excepción para las rectas; luego por rango); pero aprovechando collections.Counterdesafortunadamente,.most_common no tiene el comportamiento deseado; así que tuve que agregar una clave de clasificación personalizada.

Editar: un poco más de código de golf para recortar 19 bytes.

Código sin golf

from collections import Counter

def convertHand(h):
    # first get item counts, appropriately ordered; e.g. cbabc -> (('b',2), ('c',2),('a',1))
    sortedPairs = sorted(Counter(h).items(),key=lambda x:(-x[1],x[0]))

    # 'unzip' the tuples to get (('b','c','a'), (2,2,1))
    ranks, numberFound = zip(*sortedPairs) 

    if len(ranks)==5:
        # no pairs; is it a straight? well, since they are in increasing order...
        if ord(ranks[0])+4 == ord(ranks[4]):
            # replace numberFound with something that will sort above 3 of a kind but below full house
            numberFound = (3,1.5)

    # invert the values of the ranks, so they are in decreasing, rather then increasing order
    ranks = [-ord(r) for r in ranks]

    # arrange tuples so we can sort by numberFound, and then ranks; and keep a reference to the hand
    return (numberFound, ranks, h)

# put it all together...
def f(x,y):
    hands = [convertHand(h) for h in (x,y)]
    rankedHands = sorted(hands)
    return rankedHands[1][2]
Chas Brown
fuente
1

Mathematica, 635 bytes

H[x_]:=Block[{t},T=Sort@ToCharacterCode[x];L=Last/@Tally@T;t=0;S=Count;If[S[L,2]==1,t=1];If[S[L,2]==2,t=2];If[S[L,3]==1,t=3];If[S[Differences@T,1]==4,t=4];If[S[L,2]==1&&S[L,3]==1,t=5];If[S[L,4]==1,t=6];If[S[L,5]==1,t=7];t];F[K_,v_]:=First@Flatten@Cases[Tally@K,{_,v}];B=ToCharacterCode;(Z=Sort@B@#1;Y=Sort@B@#2;a=H[#1];b=H[#2];If[a>b,P@#1,If[a<b,P@#2]]If[a==b&&a==0,If[Z[[1]]<Y[[1]],P@#1,P@#2]];If[a==b&&(a==1||a==2),If[F[Z,2]<F[Y,2],P@#1,If[F[Z,2]==F[Y,2],If[F[Z,1]<F[Y,1],P@#1,P@#2],P@#2]]];If[a==b&&(a==3||a==5),If[F[Z,3]<F[Y,3],P@#1,P@#2]];If[a==b&&a==6,If[F[Z,4]<F[Y,4],P@#1,P@#2]];If[a==b&&(a==7||a==4),If[Tr@Z<Tr@Y,P@#1,P@#2]])&

.
.
Formulario de entrada

["abcde", "kkekk"]

J42161217
fuente
¿Hay alguna forma de probar esto en línea?
Pulpo
1
sandbox.open.wolframcloud.com/app/objects pegue con ctrl + v agregue la entrada al final del código y ejecute con shift + enter
J42161217