Pontuação da Ponte

13

Uma das coisas que torna a ponte de contrato muito interessante é o seu meta-jogo "artificial" altamente complicado. Este sistema de pontuação de mãos é uma pequena parte dele.

Bridge é um jogo de cartas complicado. Cada jogador recebe uma mão de 13 cartas e o jogo começa com a licitação . A licitação determina como o restante do jogo é jogado e, portanto, é uma parte crucial dele. Para garantir que você e seu parceiro não façam lances muito altos (ou muito baixos), este sistema de pontuação artificial foi desenvolvido para lhe dizer o quão boa é sua mão.

Pontuação

Aqui está um exemplo de mão:

S:KQT5
H:J72
D:965
C:AK8

OS, H, D, C representam os naipes (espadas, copas, diamantes e paus) e o restante são os cartões desses naipes. Portanto, esta mão tem uma dama de espadas (Q), rei de espadas (K), dez de espadas (T), cinco de espadas, valete de copas, sete de copas, etc.

O sistema de pontuação funciona da seguinte maneira:

  • Você ganha 4 pontos por cada ás (A) que possui, 3 pontos por cada rei (K), 2 pontos por cada rainha (Q) e 1 ponto por cada valete (J). Nenhuma outra carta dá pontos.
  • Cada carta após a quarta do naipe dá 1 ponto. Então, se você tiver seis corações, receberá 2 pontos.
  • Um naipe em que você tem apenas 2 cartas dá 1 ponto (este é um doubleton). Um naipe em que você tem apenas 1 carta dá 2 pontos (este é um singleton). Se você não tem cartas em um determinado naipe, você recebe 3 pontos (isto é um vazio). (Normalmente, isso só é contado quando você concordar com um processo com seu parceiro, mas eu os incluo para tornar o desafio mais interessante.)

Portanto, a mão acima tem 13 pontos.

Desafio

Dada uma mão ponte no formato mostrado acima, calcule quantos pontos ela tem. Os naipes sempre serão listados na ordem de espadas, copas, diamantes e tacos, e as cartas serão sempre classificadas na ordem A, K, Q, J, T, 9-2.

Amostras de entradas e saídas

S:KQT5
H:J72
D:965
C:AK8
       \-> 13

S:AKQT6
H:54
D:J83
C:732
       \-> 12

S:
H:KQT8754
D:A86
C:432
       \-> 15

S:9876
H:843
D:652
C:432
       \-> 0

S:AKQT5
H:AQJ6
D:Q3
C:AK
       \-> 28

Isso é , então o código mais curto em bytes vence.

um spaghetto
fonte

Respostas:

4

Geléia, 27 25 21 bytes

Obrigado @Dennis por -3 bytes!

L_5.AḞW+“JQKA”i$€Sµ€S

Isso leva a entrada como uma lista de linhas. Para receber a entrada como uma cadeia de linhas múltiplas, precatene a ṣ⁷µ.

Fazendo uma tabela dos pontos de frequência:

Cards:    0  1  2  3  4  5  6 ... 4+k
Points:   3  2  1  0  0  1  2 ... k

podemos ver que eles são iguais a abs(c-3.5)-.5, onde c é o número de cartões. Como cada linha contém dois caracteres extras e o número de pontos é sempre um número inteiro, é aqui floor(abs(l-5.5))que l é o comprimento da linha.

Observe que os índices de Jelly são baseados em 1 e também o comportamento de funções vetorizadas em dimensões incompatíveis: os elementos extras da lista mais longa não são afetados. Então [1] + [3,2,0,0][4,2,0,0].

                  µ      The program is two monadic fs applied in turn; an atop.
L_5.AW+“JQKA”i$€S       Helper function:
                 €        For €ach line:
L                         Get the line Length.
 _5.                      Subtract 5.5 (Numeric literals' decimal parts default to .5)
    A                     Apply Absolute value
     Ḟ                    Floor
      W                   Then Wrap it in an array. "S:AKQT6" gives [1].
        “JQKA”i$          Monadic function: index into the string "JQKA".
                €         Apply ^ over €ach char of the line; [3,2,0,0,0].
       +                  Add the two arrays together; [4,2,0,0,0].
                 S        Sum; 6.
                    S    Main link: Sum all results

Experimente aqui .

lirtosiast
fonte
3

ES6, 107 99 89 bytes

s=>(t=0,[...s].map(c=>t+="JQKA".search(c)+1),s.split`
`.map(l=>t+=(l=l.length-6)^l>>4),t)
Neil
fonte
2

Pitão, 27 25 24 bytes

sms+a5.5ldshMxL"JQKA"d.z

Calculamos os valores separadamente para cada naipe e os adicionamos.

  s m                 sum of map lambda d:  (d is a line of input)
      +                 add the
        s a                 floor of the absolute difference between
            5.5               5.5
            l d               and len(d)
          s hM xL           to the sum of the indices each incremented by one
                  "JQKA"      of each char in d in the string "JQKA"
                  d
      .z

Conjunto de teste .

lirtosiast
fonte
1

Retina, 77 59 bytes

T`AKQJTd`5-1
:(.){0,3}(.)?
$#1$#1$#2 3$0
\S
$0$*1
+`1 1

1

Explicação por linhas / pares de linhas:

  • Na primeira linha, convertemos caracteres AKQJT987655432para 5432111111111. Isso significa que para cada naipe temos uma soma. Se tivermos 0 1 2 3 4 5 6 7 ...cartas neste naipe, a soma será reduzida pela +3 +1 -1 -3 -4 -4 -4 -4 ...pontuação correta.
  • Nas linhas 2 e 3, para corrigir isso, adicionamos 3 a cada linha e, antes de um espaço, adicionamos valores que subtrairemos. Esse valor subtraído é o dobro do tamanho de cartões com um máximo de 3 e mais 1 se houver pelo menos 4 cartões.
  • Nas linhas 4 e 5, convertemos dígitos em unários, descartando todo o resto, exceto o espaço separador.
  • Nas linhas 6 e 7, fazemos subtração unária.
  • Na linha 8, contamos os 1's que fornecem o resultado.

Experimente online aqui.

randomra
fonte
1

Stax , 18 bytes

½Γ}♣▓="pì∩û╨▐M↨}╚-

A resposta mais curta até agora, derrotou Jelly (embora eu espere ser derrotado em breve ...)

Execute e depure online!

Explicação

Usa a versão descompactada para explicar.

LZF{"JQKA"I^+i5-:++F5+
L                         Collect input in a list (if this is not needed, we can yet save another byte)
 Z                        Put a zero under the top of the stack, used as the accumulator
  F                       Loop for every suit
   {               F      Calculate the "score" for the string describing the suit
    "JQKA"I^              Find the 1-based index of current character in "JQKA", 0 for not found
            +             Add to the accumulator
             i5-:+        Subtract 5 from the current 0-based index, and take the sign
                  +       Add to the accumulator
                    5+    Add 5 extra points for each suit

Isso é alcançado através da tradução

  • Cada carta após a quarta do naipe dá 1 ponto. Então, se você tiver seis corações, receberá 2 pontos.
  • Um naipe em que você tem apenas 2 cartas dá 1 ponto (este é um doubleton). Um naipe em que você tem apenas 1 carta dá 2 pontos (este é um singleton). Se você não tem cartas em um determinado naipe, você recebe 3 pontos (isto é um vazio).

Para

  • Marque 3 pontos extras para cada naipe
  • Cada carta antes da quarta do naipe dá -1 ponto, cada carta depois da quarta dá 1 ponto, a quarta carta recebe 0.

Então podemos fazer uso da propriedade da função signum.

Ao fazer isso, podemos evitar o tratamento explícito do número de cartões, economizando alguns bytes.

Weijun Zhou
fonte