Badugi, quem ganha?

9

Inspirado por este desafio e relacionado a este .

fundo

Badugi [bæduːɡiː] é uma variante de draw-poker de bola baixa.

O evento de $ 1K da Copa do Mundo Poker Online do Pokerstars começa em 3 horas e eu precisarei saber o quão boas minhas mãos são!

O jogo usa um baralho padrão de 52 cartas de quatro naipes e treze fileiras. Os fatos não têm ordem e devem ser rotulados cdhs; as fileiras - ordenadas do mais alto Kpara o mais baixo A- são KQJT98765432A. Como tal, o baralho completo pode ser representado da seguinte forma (separado por espaço):

Kc Kd Kh Ks Qc Qd Qh Qs Jc Jd Jh Js Tc Td Th Ts 9c 9d 9h 9s 8c 8d 8h 8s 7c 7d 7h 7s 6c 6d 6h 6s 5c 5d 5h 5s 4c 4d 4h 4s 3c 3d 3h 3s 2c 2d 2h 2s Ac Ad Ah As 

Cada jogador recebe quatro cartas do baralho, há quatro rodadas de apostas com três rodadas de empate no meio (um jogador sempre tem quatro cartas, tem a opção de trocar de 0 a 4 de suas cartas por novas do dealer de cada das três rodadas de desenho).

Se mais de um jogador ainda estiver ativo após todas essas rodadas, haverá um showdown, quando as mãos mais fortes vencerão as apostas apostadas.

O jogo é jogado com bola baixa, então a mão mais baixa vence e, como mencionado acima A(ás), é baixa. Além disso, o ranking das mãos é diferente de outras formas de pôquer e pode ser um pouco confuso para iniciantes.

A "mão" jogada é a combinação mais baixa do ranking, feita com o maior número possível de cartas "off-suit" (todos os naipes diferentes) e "off-rank" (todas as classes diferentes) possíveis (das quatro cartas mantidas ) Ou seja: se alguém tem quatro cartas de naipes distintos e de posições distintas, tem uma mão de 4 cartas (chamada de "badugi"); se alguém não tem uma mão de 4 cartas, mas possui um conjunto ou três conjuntos de três cartas de naipes e posições distintas, tem uma mão de 3 cartas (escolhe o melhor); se alguém não tiver uma mão de 4 cartas ou uma mão de 3 cartas, provavelmente terá uma mão de 2 cartas, mas se não houver uma mão de 1 carta.

  • Como tal, a melhor mão possível é a mão de 4 card 4-3-2-A- as mais baixas off-rank cartões de quatro naipes diferentes , muitas vezes chamado de "número 1". A mão mais fraca possível seria a mão de 1 carta Ke só é possível segurando exatamente Kc Kd Kh Ks.

  • Observe que não4c 3h 2c As é um "número 1", já que são e são do mesmo naipe, mas é o mais forte das mãos de 3 cartas , ele empata com outros s (como ) e vence todas as outras mãos de 3 cartas, mas perde para todas as mãos de 4 cartas (o que pode ser tão fraco quanto ). 4c2c3-2-A3-2-1Kh 3d 2s AhK-Q-J-T

    • A outra mão possível de três cartas que poderia ser feita 4c 3h 2c Asé 4-3-A, mas que é mais fraca (mais alta), portanto não escolhida.
  • Da mesma forma, 8d 6h 3s 2huma mão de 3 cartas é jogada como 8-3-2- há duas combinações off-rank de naipe de tamanho 3 e 8-3-2é melhor (menor) do que 8-6-3desde que as três (ou "trey") são menores que as seis.

A comparação entre mãos segue a mesma lógica - qualquer 4 cartas vence qualquer 3, qualquer 3 vence qualquer 2 e qualquer 2 vence qualquer 1, enquanto mãos com o mesmo número de cartas usadas são comparado do mais alto ao mais baixo (por exemplo: 8-4-2batidas, 8-5-Amas não nenhuma 8-4-A, 8-3-2ou 7-6-5)

O desafio:

Dadas duas coleções não ordenadas, cada uma das quatro cartas, identifique as que venceram o confronto Badugi (identifique ambas se for um empate).

A entrada pode ser qualquer coisa razoável:

  • uma única sequência de todas as oito cartas, conforme indicado acima (com ou sem espaços), com as quatro esquerdas sendo uma mão e a direita a outra (com um separador opcional); ou uma lista de caracteres da mesma maneira
  • uma lista de duas strings - uma por mão ou uma lista de listas de caracteres da mesma maneira
  • duas seqüências de caracteres separadas ou entradas de lista, uma por mão
  • as cartas nas mãos também já devem estar separadas (portanto, uma lista de listas de listas é boa)

Observe, no entanto:

  • os cartões não podem ser organizados em nenhuma ordem antes da entrada
  • ... e os naipes e posições são fixados como os rótulos de caracteres especificados aqui - Se o seu idioma não suportar tais construções, apenas sugira algo razoável e pergunte se é uma alternativa aceitável, considerando as restrições de seu idioma.

A saída deve ser

  • formatado da mesma forma que a entrada ou uma representação impressa da mesma; ou
  • ser um de três resultados distintos e consistentes (por exemplo: "left", "right", "both"; ou 1, 2, 3; etc.)

Realmente - desde que fique claro qual das duas entradas está sendo identificada, tudo bem.

Casos de teste

input                      ->  output
                                   (notes)
----------------------------------------------------------------------------
3c 2s 4d Ah - As 3h 2d 4h  ->  3c 2s 4d Ah
                                   (4-card 4-3-2-A beats 3-card 3-2-A)

3c 2s 4d Ah - As 2c 3d 4h  ->  3c 2s 4d Ah - As 2c 3d 4h
                                   (4-card 4-3-2-A draws with 4-card 4-3-2-A)

2d Ac 4h 3c - Kh Ad 9s 2c  ->  Kh Ad 9s 2c
                                   (3-card 4-2-A loses to 4-card K-9-2-A)

Kc Tc Qc Jc - Ac Ad Ah As  ->  Ac Ad Ah As
                                   (1-card T loses to 1-card A)

9c 9h Qc Qh - Qs Kh Jh Kd  ->  Qs Kh Jh Kd
                                   (2-card Q-9 loses to 3-card K-Q-J)

2d 5h 7c 5s - 2h 3c 8d 6c  ->  2d 5h 7c 5s
                                   (3-card 7-5-2 beats 3-card 8-3-2)

3s 6c 2d Js - 6h Jd 3c 2s  ->  6h Jd 3c 2s
                                   (3-card 6-3-2 loses to 4-card J-6-3-2)

Ah 6d 4d Ac - 3h 2c 3s 2s  ->  3h 2c 3s 2s
                                   (2-card 4-A loses to 2-card 3-2)

2h 8h 6h 4h - 6d 2d 5d 8d  ->  2h 8h 6h 4h - 6d 2d 5d 8d
                                   (1-card 2 = 1-card 2)

Isso é , portanto o código mais curto em bytes vence por idioma e o código mais curto em geral vence. Não deixe que os idiomas do golfe o impeçam de enviar para outros idiomas e ... divirta-se!

Jonathan Allan
fonte
É algo como [['3c', '2s', '4d', 'Ah'], ['As', '3h', '2d', '4h']]razoável?
Erik the Outgolfer
@EriktheOutgolfer Sim - eu ia dizer que acho que você pode adicionar Ona frente.
Jonathan Allan

Respostas:

2

Perl 6 , 128 bytes

{.map({.combinations(1..4).grep({!.join.comb.repeated}).map({-$_,$_».trans('ATK'=>'1BZ')».ord.sort(-*)}).min}).minpairs».key}

Experimente online!

Toma uma lista de mãos (também mais de duas) que são listas de cartas que são como strings Kc. Retorna os índices das mãos com a menor pontuação. Para duas mãos, isso ocorre (0)se a primeira mão vencer, (1)se a segunda mão vencer e o (0, 1)empate.

Explicado:

{
    # Map hands to best "played hand".
    .map({
        # Generate all combinations of length 1 to 4.
        .combinations(1..4)
        # Remove hands with repeated characters.
        .grep({!.join.comb.repeated})
        # Map to a cmp-arable representation. This works because
        # lists are compared element-wise. Translate some characters
        # so that ASCII order works. Sort in reverse order so that
        # element-wise comparison will go from highest to lowest.
        .map({ -$_, $_».trans('ATK'=>'1BZ')».ord.sort(-*) })
        # Find best hand.
        .min
    })
    # Return indices of lowest scoring hands. It's a shame that
    # `minpairs` doesn't support a filter like `min`.
    .minpairs».key
}
Nwellnhof
fonte
Fora de interesse, como o <...>seu equipamento de teste se traduz em uma lista de strings? É algum tipo de açúcar que diz que o conteúdo deve ser dividido em espaços?
Jonathan Allan
@ JonathanAllan Esta é a palavra de Perl citando . Perl 6 suportes <a b c>para além qw(a b c)de Perl 5.
nwellnhof
Bem, isso é agradável e golfy em si mesmo :)
Jonathan Allan
2

JavaScript (ES6), 209 202 192 182 181 bytes

Guardado 7 bytes graças a @Neil

Recebe entrada como uma matriz de matrizes de seqüências de caracteres. Retorna truese a primeira mão vencer, falsese a segunda mão vencer, ou 2em caso de empate.

a=>([a,b]=a.map(a=>a.reduce((a,x)=>[...a,...a.map(y=>[x,...y])],[[]]).map(a=>!/(\w).*\1/.test(a)*a.length+a.map(a=>'KQJT98765432A'.search(a[0])+10).sort()).sort().pop()),a==b?2:a>b)

Casos de teste

Como?

a => (
  // store the best combination for both hands in a and b respectively
  [a, b] = a.map(a =>
    // compute the powerset of the hand
    a.reduce((a, x) => [...a, ...a.map(y => [x, ...y])], [[]])
    // for each entry:
    .map(a =>
      // invalidate entries that have at least 2 cards of same rank or same value
      !/(\w).*\1/.test(a) *
      // the score of valid entries is based on their length ...
      a.length +
      // ... and their card values, from highest to lowest
      // (we map 'KQJT98765432A' to [10 - 22], so that the resulting
      // strings can be safely sorted in lexicographical order)
      a.map(a => 'KQJT98765432A'.search(a[0]) + 10).sort()
    )
    // keep the best one
    .sort().pop()
  ),
  // compare a with b
  a == b ? 2 : a > b
)
Arnauld
fonte
Você precisa disso join?
Neil
1

Gelatina , 36 bytes

ẎŒQȦ;L;Ṗ€Ṣ$
“A+KYTE”yḲONŒPÇ€ṢṪµ€⁼€Ṁ$

Uma ligação monadic tendo uma lista de duas listas de caracteres
- sendo cada um espaço separado representação da mão (por exemplo "Ac 2d 4s 3h")
retornar uma lista de dois números de identificação do vencedor (s) com 1e qualquer perdedor com 0
- ou seja, [1, 0]= ganhos esquerda; [0, 1]= vitórias certas; [1, 1]= desenhar.

Experimente online! ou veja a suíte de testes .

Como?

ẎŒQȦ;L;Ṗ€Ṣ$ - Link 1, sortKey: list of lists of numbers representing some cards (see Main)
Ẏ           - flatten into a single list of numbers
 ŒQ         - distinct sieve (1 at first occurrence of anything, 0 at the rest)
   Ȧ        - Any & All? zero if any are 0 or if empty; 1 otherwise (i.e. playable hand?)
     L      - length of input (number of cards in the hand)
    ;       - concatenate
          $ - last two links as a monad:
       Ṗ€   -   pop each (get just the rank portions)
         Ṣ  -   sort (Main's translation & negation of ordinals ensures A>2>3>...>Q>K)
      ;     - concatenate (now we have [isPlayable; nCards; [lowToHighCards]])

“A+KYTE”yḲONŒPÇ€ṢṪµ€⁼€Ṁ$ - Main link: list of lists of characters, hands
                  µ€     - for €ach of the two hands:
“A+KYTE”                 -   literal list of characters "A+KYTE" (compressing doesn't help - lower case would be “£Ḅṁ⁽>» though -- I'll stick with kyte though it's kind of nice.)
        y                -   translate - change As to +s, Ks to Ys and Ts to Es
                         -               note the ranks are now in ordinal order:
                         -               +<2<3<4<5<6<7<8<9<E<J<Q<Y
         Ḳ               -   split at spaces - split the four cards up
          O              -   to ordinals '+'->43, '2'->50, ...
           N             -   negate - effectively reverse the ordering
            ŒP           -   power-set - get all combinations of 0 to 4 cards inclusive
              Ç€         -   call the last link (1) as a monad for €ach such selection
                Ṣ        -   sort these keys
                 Ṫ       -   tail - get (one of) the maximal keys
                         -                       (the key of a best, playable selection)
                       $ - last two links as a monad:
                      Ṁ  -   maximum (the better of the two best, playable selection keys)
                    ⁼€   -   equals? for €ach (1 if the hand is a winner, 0 if not)
Jonathan Allan
fonte
1

Python 3 , 207 204 bytes

lambda i,j:L(h(i))-L(h(j))if L(h(i))!=L(h(j))else(h(i)<h(j))-(h(i)>h(j))
L=len
def h(l):s=set();return[x[0]for x in sorted(y.translate({65:49,75:90,84:65})for y in l)if not(s&set(x)or s.update(*x))][::-1]

Experimente online!

Guardado 3 bytes graças a Jonathan Frech

Retorna 1se a primeira mão vencer, -1se a segunda mão vencer e 0em caso de empate.

A função hcalcula uma lista que representa a mão.

O lambda compara duas representações da mão. Eu acho que pode ser reduzido, mas eu queria retornar apenas três valores e não encontrei uma maneira mais simples de fazer comparação.

jferard
fonte
Você pode salvar dois bytes, definindo L=lene substituindo todas as outras ocorrências de lenwith L.
Jonathan Frech 14/09
Além disso, você provavelmente pode substituir s=set()por s={0}e set(x)&s orcoms&set(x)or
Jonathan Frech 14/17