Blackjack Bust Calculator

12

O blackjack , também conhecido como vinte e um, é um jogo de cartas comparativo entre você e um dealer, onde cada jogador, por sua vez, compete contra o dealer, mas os jogadores não jogam entre si.

O jogo é o seguinte, o carteador oferece uma carta. O revendedor então negocia uma carta com a face para baixo. O revendedor, então, oferece outro cartão. Por fim, o revendedor negocia uma carta com a face para cima.

Desafio

Seu desafio é escrever um programa (ou função) que, quando executado (ou chamado), gera (ou devolve) a probabilidade de que a próxima carta que o carteador lhe dê, o faça parar, o que significa a pontuação acumulada de cartas em sua mão após o revendedor oferece outro cartão com mais de 21 anos.

Entrada

As três cartas visíveis em jogo. São as duas cartas que você tem na sua mão e a única que pode ser vista na mão do dealer. Isso pode estar no formato que você achar adequado para o seu aplicativo.

Existem 52 cartas em um baralho (4 de cada uma das cartas abaixo). O valor dos cartões é o seguinte:

Symbol(Case Insensitive)  Name     Value
2                         Two      2
3                         Three    3
4                         Four     4
5                         Five     5
6                         Six      6
7                         Seven    7
8                         Eight    8
9                         Nine     9
T                         Ten      10
J                         Jack     10
Q                         Queen    10
K                         King     10
A or 1                    Ace      1 

No Blackjack, um ás pode contar como 1 ou 11. No nosso desafio, conte apenas como 1

Resultado

A probabilidade, em um formato de proporção ou porcentagem, de que a próxima carta que sacaremos nos fará perder.

Você pode gerar a porcentagem, a fração ou apenas o numerador da fração.

Exemplos

Neste exemplo, as duas primeiras cartas estão na nossa mão, a terceira é a carta visível do dealer

 Input          ->       Output

 A 2 Q          ->       0.00%  or  0/49 or 0
 A 2 3          ->       0.00%  or  0/49 or 0
 T T T          ->       91.84% or 45/49 or 91.84 
 T J K          ->       91.84% or 45/49 or 45
 9 7 3          ->       61.22% or 30/49 ...
 9 7 Q          ->       59.18% or 29/49 ...

Regras

As brechas padrão não são permitidas.

Isso é , então o código mais curto em bytes para cada idioma vence!

DevelopingDeveloper
fonte
2
É permitido pegar o ás como 1 e as cartas de face como 10s, ou isso esticaria muito o formato de entrada?
Então, podemos aceitar cartões de face como 10?
Wastl
1
@ Arnauld Obrigado pela captura. Atualizei as proporções, mas não as probabilidades. Quanto à sua pergunta de saída, tudo bem. Você não precisa adicionar o / 49 em cada resposta.
DevelopingDeveloper
1
"TJK -> 91,84% ou 45/49 ou 45 ou etc ..." - para que possamos simplesmente emitir o numerador? Em caso afirmativo, você poderia declarar isso no texto?
Jonathan Allan
1
@JonathanAllan Atualizado
DevelopingDeveloper

Respostas:

7

Geléia ,  26  24 bytes

O%48«⁵µ13R«⁵ẋ4œ-+ṖS$>21S

Um link monádico que aceita uma lista de caracteres (usando a opção minúscula OU a opção maiúscula com 1for A) que retorna o numerador (o número de 49 th ) em [0,49].

Experimente online! Ou veja a suíte de testes

Quão?

Observe que, usando minúsculas, o mínimo de 10 e o módulo ordinal por 48 fornecem os valores do cartão. O mesmo vale para maiúsculas T, J, Q, Ke 1para um ás, como mostrado à direita (mas uma maiúscula Anão funciona):

     card:   a   2   3   4   5   6   7   8   9   t   j   q   k   |   1   T   J   Q   K
  ordinal:  97  50  51  52  53  54  55  56  57 116 106 113 107   |  49  84  74  81  75
   mod 48:   1   2   3   4   5   6   7   8   9  20  10  17  11   |   1  36  26  33  27
min(_,10):   1   2   3   4   5   6   7   8   9  10  10  10  10   |   1  10  10  10  10

O%48«⁵µ13R«⁵ẋ4œ-+ṖS$>21S - Link: list of characters   e.g. "q3a"
O                        - ordinals (of the input list)    [113, 51, 97]
 %48                     - modulo by 48                    [17,3,1]
     ⁵                   - ten
    «                    - minimum                         [10,3,1]
      µ                  - start a new monadic chain
       13R               - range of 13                     [1,2,3,4,5,6,7,8,9,10,11,12,13]
           ⁵             - ten                             10
          «              - minimum                         [1,2,3,4,5,6,7,8,9,10,10,10,10]
            ẋ4           - repeat four times               [1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10]
              œ-         - multi-set difference            [1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10  ,2  ,4,5,6,7,8,9   ,10,10,10]
                   $     - last two links as a monad:
                 Ṗ       -   pop                           [10,3]
                  S      -   sum                           13
                +        - add (vectorises)                [14,15,16,17,18,19,20,21,22,23,23,23,23,14,15,16,17,18,19,20,21,22,23,23,23,23,14,15,16,17,18,19,20,21,22,23,23,23,23,15,17,18,19,20,21,22,23,23,23]
                    >21  - greater than 21?                [0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1]
                       S - sum                             19
Jonathan Allan
fonte
tentação de flat-out roubar os mod-48 intensifica tecnologia
Magia Octopus Urna
Se eu acabar respondendo usando o mod-48, concedo 200 para a observação épica.
Magic Octopus Urn
4

JavaScript (ES6), 73 62 bytes

Recebe a entrada como uma matriz de 3 caracteres com 1ases. Retorna o número inteiro X que representa a probabilidade X / 49 de ser eliminada.

a=>([b,c]=a.map(v=>v*4||40)).map(n=>b-=n+b>52,b+=c-32)|b>12&&b

Experimente online!

Ensaio exaustivo

A fórmula do golfe não é muito intuitiva. Portanto, a maneira mais fácil de provar sua consistência é provavelmente apenas comparar todas as saídas possíveis com as fornecidas por uma implementação básica não-armazenada:

g = a => {
  deck = [...'123456789TJQK'.repeat(4)];
  a.forEach(card => deck.splice(deck.indexOf(card), 1));

  return deck.filter(card =>
    (+a[0] || 10) +
    (+a[1] || 10) +
    (+card || 10) > 21
  ).length;
}

Experimente online!

Arnauld
fonte
O que .map(n=>b-=n+b>52,b+=c-32)faz em geral? Eu não estou muito familiarizado com JS de .mape tentando entender o que a vírgula faz aqui .. Inicialmente I embora seja uma variante mais curta .map(n=>{b-=n+b>52;b+=c-32})ou algo .. Eu sei a=>([b,c]=a.map(v=>v*4||40))convertidos ['1','2','Q']para [ 4, 8, 40 ], em seguida, ele faz um loop sobre esses três valores, onde bé o primeiro valor e cé o segundo (se bem entendi). Mas estou um pouco confuso sobre .map(n=>b+=(n+b<53)-1,b+=c-32)(se o primeiro b-=é alterado para b+=) vs .map(n=>b+=(n+b<53)-33+c)..
Kevin Cruijssen
Hmm, ou é de fato b= primeiro valor, c= segundo valor em [4, 8, 40]e o b-=n+b>52modifica ctambém se for a segunda iteração? Nesse caso, a combinação de ambos b-=e b+=em um único b+=(ou b-=) não funcionará por causa disso?
Kevin Cruijssen
1
@KevinCruijssen b+=c-32é um parâmetro (não utilizado) de map()e é avaliado apenas uma vez antes da primeira iteração. n=>b-=n+b>52é a função de retorno de chamada (o 1º parâmetro de map()) e é chamada em cada iteração. Tecnicamente, map()aceita um segundo parâmetro (chamado thisArg ), mas isso é irrelevante aqui: queremos apenas que esse trecho de código seja executado antes do início do loop.
Arnauld
1
@KevinCruijssen Aqui está um código mostrando o que está acontecendo.
Arnauld
Ah, ok, agora tudo faz sentido. Obrigado!
Kevin Cruijssen
2

Pitão, 35 bytes

Jm?}dGTsdQclf>T-21sPJ.-*4+ST*3]TJ49

Recebe a entrada como uma lista de caracteres (ou como uma sequência).
Experimente aqui

Explicação

Jm?}dGTsdQclf>T-21sPJ.-*4+ST*3]TJ49
Jm?}dGTsdQ                            Convert each input to the appropriate number.
                     .-*4+ST*3]TJ     Remove each from the deck.
           lf>T-21sPJ                 Count how many remaining cards bust.
          c                      49   Get the probability.

fonte
1

Perl 5 , 115 bytes

map{//;$k{$_}=4-grep$' eq$_,@F}1..9,T,J,Q,K;map{s/\D/10/}@F;$_=grep{$F[0]+$F[1]+$_>21}map{(s/\D/10/r)x$k{$_}}keys%k

Experimente online!

Xcali
fonte
1

Python 2 , 97 96 bytes

def f(s):C=[min(int(c,36),10)for c in s];D=C[0]+C[1];return(4*D-35+sum(v+D<22for v in C))*(D>11)

Experimente online!

Pega uma string de 3 caracteres como entrada, com '1' sendo usado como Ace. Retorna o numerador.

Chas Brown
fonte
1

Java 8, 109 bytes

a->{int r=3;for(;r-->0;a[r]=a[r]<59?a[r]*4-192:40);r=a[0]+a[1]-32;for(int v:a)r-=v+r>52?1:0;return r>12?r:0;}

Porta da resposta JavaScript (ES6) de @Arnauld .
Entrada como matriz de caracteres com três valores, Aces como '1'; saída é a probabilidade pem p/49.

Experimente online.

Explicação:

a->{                   // Method with integer-array as parameter and integer return-type
  int r=3;for(;r-->0;  //  Loop over the array
    a[r]=a[r]<59?      //   If the current item is a digit:
          a[r]*4-192   //    Multiply it by 4
         :             //   Else:
          40);         //    Change it to 40
  r=a[0]+a[1]-32;      //  Set `r` to the first value, plus the second value, minus 32
  for(int v:a)         //  Loop over the now modified array again
    r-=v+r>52?         //   If the current value plus `r` is larger than 52
        1              //    Decrease the result-integer by 1
       :0;             //   Else: Leave the result-integer the same
  return r>12?         //  If the result-integer is larger than 12
          r            //   Return the result-integer
         :             //  Else:
          0;}          //   Return 0
Kevin Cruijssen
fonte
1

05AB1E , 46 bytes

Y9ŸJ.•§®т•«Á4שsð.;#S|UεX‚˜ε®sk>T‚W}O21›}DOsg/

Experimente online!

Isso pode ser feito melhor, trabalhando nisso.

Urna de polvo mágico
fonte
1

05AB1E , 23 22 21 bytes

AST:4-D¨OÐ4@*4*Š+T@O-

Experimente online!

AST:                   # replace all letters in the input with 10
    4-                 # subtract 4 from each card value
      D                # duplicate
       ¨               # drop the last element
        O              # sum (hand value of the player - 8)
         Ð             # triplicate that
          4@*          # set to 0 if it's less than 4
             4*        # multiply by 4
               Š       # 3-way swap
                +      # add the player's hand value to each card value
                 T@O   # count how many are >= 10
                    -  # subtract
Grimmy
fonte