Pitão, 73 bytes
eo_S+*-5l@\AN}SPMJ+NZSM.:+\AT5+-4l{eMJlM.gPkJ-sM*=T+`M}2Tc4"JQKA""hscd"=Zc
Isso é bem terrível. Analisando cartões, classificando os valores, ... Tudo leva tantos caracteres. Mas a abordagem é interessante.
Experimente on-line: Demonstration or Test Suite
Explicação:
Gero todos os 52 cartões, retiro os quatro cartões da entrada, giro uma pontuação para cada cartão (pontuação da mão) e imprimo o cartão com a pontuação máxima.
A pontuação é um pouco estranha. Se eu comparar a pontuação de duas mãos completamente diferentes, pode escolher o vencedor errado. Por exemplo, uma sequência venceria 4 ases. Mas funciona, se as 4 primeiras cartas forem iguais nas duas mãos. E minha pontuação calculada não é realmente um valor, mas uma lista de valores:
- G: Primeiro eu agrupo as 5 cartas por posição e compro:
5h 5d 6c 5s Jd
->
[3, 1, 1]
- F: Em seguida, acrescento 4 menos o número de suítes diferentes a esta lista.
Flush
->
3
é anexado, not flush
->
2/1/0
é anexado.
- S: adicione outro número.
0
se não for uma sequência, 4
se for a sequência A2345
, ou 5
se for uma sequência mais alta.
Essas listas de 4-7 números são classificadas em ordem decrescente e a lista com valor máximo é selecionada.
Por que isso funciona? Aqui você vê as configurações possíveis para todos os tipos. A letra ao lado dos números indica com qual regra esse número foi gerado.
- Straight flush:
[5S, 3F, 1G, 1G, 1G, 1G, 1G]
ou[4S, 3F, 1G, 1G, 1G, 1G, 1G]
- Quatro de um tipo:
[4G, 1G, 0F, 0S]
- Casa completa:
[3G, 2G, 1F, 0S]
ou[3G, 2G, 0F, 0S]
- Rubor:
[3F, 1G, 1G, 1G, 1G, 1G, 0S]
- Em linha reta:
[5S, 2F, 1G, 1G, 1G, 1G, 1G]
, [5S, 1F, 1G, 1G, 1G, 1G, 1G]
, [5S, 1G, 1G, 1G, 1G, 1G, 0F]
, [4S, 2F, 1G, 1G, 1G, 1G, 1G]
, [4S, 1F, 1G, 1G, 1G, 1G, 1G]
,[4S, 1G, 1G, 1G, 1G, 1G, 0F]
- Três de um tipo:
[3G, 1G, 1G, 1F, 0S]
,[3G, 1G, 1G, 0F, 0S]
- Dois pares:
[2G, 2G, 2F, 1G, 0S]
, [2G, 2G, 1F, 1G, 0S]
,[2G, 2G, 1G, 0F, 0S]
- Um par de:
[2G, 2F, 1G, 1G, 1G, 0S]
, [2G, 1G, 1G, 1G, 1F, 0S]
,[2G, 1G, 1G, 1G, 0F, 0S]
- Alta card:
[2F, 1G, 1G, 1G, 1G, 1G, 0S]
, [1F, 1G, 1G, 1G, 1G, 1G, 0S]
,[1G, 1G, 1G, 1G, 1G, 0S, 0F]
Pyth compara as listas em elementos. Portanto, é óbvio que um straight flush sempre vence quatro do mesmo tipo. A maioria das regras típicas do poker é óbvia nessas listas. Alguns parecem conflitantes.
- Uma Straight vencerá o Four ou o Full house: Não é um problema. Se você tiver a chance de obter Four of a kind / Full house com a carta do river, não poderá chegar a uma sequência ao mesmo tempo (já que você já tem 2 ou 3 suítes diferentes na sua mão).
- Um Straight vencerá contra um flush. Se você conseguir um flush e um straight com a carta do river, também poderá alcançar um straight. E o straight flush tem uma pontuação melhor do que o straight e o flush.
- Um par
[2G, 2F, 1G, 1G, 1G, 0S]
ganhará contra algumas mãos de dois pares. Também não há problema. Se você receber dois pares com a carta do river, terá pelo menos um par antes do river. Mas isso significa que você pode melhorar para três tipos, o que é melhor. Portanto, um par de dois nunca será realmente a resposta.
- A carta alta
[2F, 1G, 1G, 1G, 1G, 1G, 0S]
ganhará contra algumas mãos de um par. Se esta é a melhor pontuação que você pode alcançar, antes do river você terá 3 cartas de uma suíte e uma carta de uma suíte diferente. Mas então você pode escolher o cartão com uma dessas duas suítes e com um valor que já aparece, e você terminará com a pontuação [2F, 2G, ...]
, que também é melhor.
Portanto, isso escolhe o tipo correto de solução. Mas como obtenho o melhor par (de 4 possibilidades), como escolho o melhor straight, ...? Porque duas soluções diferentes de um par podem ter a mesma pontuação.
Isso é fácil. Pyth garante uma classificação estável (ao usar o máximo). Então, eu simplesmente gero os cartões na ordem 2h 2s 2c 2d 3h 3s ... Ad
. Portanto, o cartão com o valor mais alto será automaticamente o máximo.
Detalhes da implementação
=Zc
divide a sequência de entrada e armazena a lista de cartões Z
.
=T+`M}2Tc4"JQKA"
gera a lista de classificações ['2', ..., '10', 'J', 'Q', 'K', 'A']
e as armazena T
. -sM*T..."hscd"Z
gera cada combinação de classificação com as suítes e remove os cartões de Z
.
o...
ordena essas cartas restantes por: lM.gPkJ
o comprimento dos grupos das fileiras, +-4l{eMJlM
anexa 4 comprimentos (suítes), +*-5l@\AN}SPMJ+NZSM.:+\AT5
acrescenta 0/4/5, dependendo da suíte (gere cada substring de comprimento 5 de "A" + T, verifique se a mão um deles (requer classificar a mão e classificar todos os subconjuntos), multiplicar por 5 - número de "A" s no cartão), _S
classifica a lista diminuindo.
e
escolha o máximo e imprima.
JavaScript (ES6),
329324317312309 bytesComo funciona
Para cada carta restante no baralho, calculamos a pontuação da mão
S
. Quanto menor a pontuação, melhor a mão.Variáveis usadas para calcular a pontuação
F
: falsy se a mão é um flushc
: bitmask de clubesd
: bitmask de diamantesh
: bitmask de Copass
: bitmask de espadasx = c | d
: bitmask de clubes ou diamantesy = h | s
: bitmask de copas ou espadasa
: máscara de bit de todos os fatos combinadosp = c & d | x & y | h & s
: par de máscara de bit (1)t = c & d & y | h & s & x
: três de um tipo máscara de bit (1)(1) Eu escrevi essas fórmulas alguns anos atrás e as usei em vários mecanismos de pôquer. Eles trabalham. :-)
Outras fórmulas
c & d & h & s
: quatro de um tipo de máscaraa == 7681
: teste para a reta especial "A, 2, 3, 4, 5" (0b1111000000001)((j = a / 31) & -j) == j
: teste para todas as outras retasGráfico de pontuação
NB: Não precisamos nos preocupar com dois pares, o que não pode ser nossa melhor opção. (Se já temos um par, podemos transformá-lo em um Três. E se já temos dois pares, podemos transformá-los em um Full House.)
Casos de teste
Mostrar snippet de código
fonte
JavaScript (ES6), 307
349Isso é bastante volumoso e não tenho certeza de que é a melhor abordagem.
Ainda um pouco de golfe, talvez.Menos golfe
Teste
fonte