Calculadora de busto de blackjack

12

El Blackjack , también conocido como veintiuno, es un juego de cartas de comparación entre usted y un crupier, donde cada jugador compite a su vez contra el crupier, pero los jugadores no juegan entre sí.

El juego es el siguiente, el crupier te reparte una carta. El crupier se reparte una carta boca abajo. El crupier le reparte otra carta. Luego, finalmente, el crupier se reparte una carta boca arriba.

Desafío

Su desafío es escribir un programa (o función) que cuando se ejecuta (o se llama), genera (o devuelve) la probabilidad de que la próxima carta que le dé el crupier lo haga quebrar, lo que significa la puntuación acumulada de cartas en su mano después el crupier le da otra tarjeta que tenga más de 21 años.

Entrada

Las tres cartas visibles en juego. Son las dos cartas que tienes en tu mano, y la carta de una cara que puedes ver en la mano del crupier. Esto puede estar en cualquier formato que considere adecuado para su aplicación.

Hay 52 cartas en una baraja (4 de cada una de las cartas a continuación). El valor de las tarjetas son las siguientes:

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 

En Blackjack, un as puede contar como 1 u 11. En nuestro desafío, solo contar como 1

Salida

La probabilidad, en un formato de proporción o porcentaje, de que la próxima carta que robemos nos haga reventar.

Puede generar el porcentaje, la fracción o simplemente el numerador de la fracción.

Ejemplos

En este ejemplo, las dos primeras cartas están en nuestra mano, la tercera carta es la carta visible del crupier

 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 ...

Reglas

Las lagunas estándar no están permitidas.

Este es el , por lo que gana el código más corto en bytes para cada idioma.

Desarrollador en desarrollo
fuente
2
¿Se nos permite tomar el as como 1 y las tarjetas de cara como 10s, o eso sería estirar demasiado el formato de entrada?
Entonces, ¿podemos tomar cartas de cara como 10?
wastl
1
@Arnauld Gracias por la captura. Actualicé las razones pero no las probabilidades. En cuanto a su pregunta de salida, está bien. No tiene que agregar el / 49 en cada respuesta.
DevelopingDeveloper
1
"TJK -> 91.84% o 45/49 o 45 o etc ..." - ¿entonces podemos simplemente generar el numerador? Si es así, ¿podría decirlo en el texto?
Jonathan Allan
1
@JonathanAllan Actualizado
DevelopingDeveloper

Respuestas:

7

Jalea ,  26  24 bytes

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

Un enlace monádico aceptar una lista de caracteres (utilizando ya sea la opción de menor caso o la opción mayúscula con 1para A) que devuelve el numerador (el número de 49 º S) en [0,49].

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

¿Cómo?

Tenga en cuenta que al usar minúsculas, el mínimo de 10 y el módulo de ordinales en 48 da los valores de la tarjeta. Lo mismo ocurre con mayúsculas T, J, Q, Ky 1de un as, como se muestra a la derecha (pero una mayúscula Ano 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
fuente
la tentación de robar la tecnología mod-48 se intensifica
Magic Octopus Urn
Si termino haciendo una respuesta usando mod-48, te recomiendo 200 para la observación épica.
Magic Octopus Urn
4

JavaScript (ES6), 73 62 bytes

Toma la entrada como una matriz de 3 caracteres con 1para ases. Devuelve el entero X que representa la probabilidad de que X / 49 se rompa.

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

Pruébalo en línea!

Prueba exhaustiva

La fórmula de golf no es muy intuitiva. Por lo tanto, la forma más fácil de demostrar su consistencia es probablemente comparar todos los resultados posibles con los proporcionados por una implementación básica sin protección:

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;
}

Pruébalo en línea!

Arnauld
fuente
¿Qué hace .map(n=>b-=n+b>52,b+=c-32)en general? No estoy muy familiarizado con los JS .mapy estoy tratando de entender qué hace la coma aquí. Inicialmente, pensé que es una variante más corta .map(n=>{b-=n+b>52;b+=c-32})o algo así. Sé que se a=>([b,c]=a.map(v=>v*4||40))convierte ['1','2','Q']a [ 4, 8, 40 ], y luego recorre estos tres valores, ¿dónde bestá el primer valor? , y ces el segundo (si lo entiendo correctamente). Pero estoy un poco confundido sobre .map(n=>b+=(n+b<53)-1,b+=c-32)(si el primero b-=se cambia a b+=) vs .map(n=>b+=(n+b<53)-33+c)..
Kevin Cruijssen
Hmm, o es de hecho b= primer valor, c= segundo valor en [4, 8, 40], y el b-=n+b>52modifica ctambién si es la segunda iteración? ¿En qué caso combinar ambos b-=y b+=formar uno solo b+=(o b-=) no funcionará por eso?
Kevin Cruijssen
1
@KevinCruijssen b+=c-32es un parámetro (no utilizado) map()y se evalúa solo una vez antes de la primera iteración. n=>b-=n+b>52es la función de devolución de llamada (el primer parámetro de map()) y se llama en cada iteración. Técnicamente, map()acepta un segundo parámetro (llamado thisArg ), pero esto es irrelevante aquí: solo queremos que este fragmento de código se ejecute antes de que comience el ciclo.
Arnauld
1
@KevinCruijssen Aquí hay un código que muestra lo que está sucediendo.
Arnauld
Ah ok, ahora todo tiene sentido. ¡Gracias!
Kevin Cruijssen
2

Pyth, 35 bytes

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

Toma la entrada como una lista de caracteres (o como una cadena).
Pruébalo aquí

Explicación

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.

fuente
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

Pruébalo en línea!

Xcali
fuente
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)

Pruébalo en línea!

Toma una cadena de 3 caracteres como entrada, con '1' como As. Devuelve el numerador.

Chas Brown
fuente
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;}

Puerto de la respuesta de JavaScript de @Arnauld (ES6) .
Entrada como conjunto de caracteres con tres valores, Ases como '1'; salida es la probabilidad pen p/49.

Pruébalo en línea.

Explicación:

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
fuente
1

05AB1E , 46 bytes

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

Pruébalo en línea!

Esto se puede hacer mejor, trabajando en ello.

Urna de pulpo mágico
fuente
1

05AB1E , 23 22 21 bytes

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

Pruébalo en línea!

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
Mugriento
fuente