¿Quién ganó un juego de dados de barra?

24

Reto

Bar Dice es un juego simple que se juega en un Bar with Dice (de ahí el nombre). Tira 5 dados de seis lados e intenta hacer la mejor mano.

La puntuación se basa en acumular el mayor número de dados con los mismos dígitos. Cada mano debe incluir al menos un solo "As", o uno, para ser una mano válida; Los ases actúan como "comodines" y pueden combinarse con cualquier otro dígito. La fuerza de la mano de un jugador depende primero del número de dígitos y luego del valor de esos dígitos. Como ejemplo, una mano (contando comodines) con cuatro 3 es mejor que una mano con tres 5, pero no mejor que una mano con cinco 2.
Tomado del artículo de Wikipedia

Esto significa que la mano mejor clasificada está compuesta por 6 y 1, y la mano más baja es cualquier mano sin un 1.

Su desafío es tomar dos manos y devolver qué jugador ganó, o si empataron.

Entrada

Dos listas sin clasificar de 5 números, que van del 1 al 6. Cada lista representa la mano de un jugador. El formato de entrada es flexible.

Salida

Cualquier tres valores estáticos distintos pero consistentes (los rangos no están permitidos) que significan si el jugador 1 o el jugador 2 ganaron, o si fue un empate. Indique en su respuesta qué valores está utilizando para qué. Por ejemplo, puede regresar -1si P1 gana, 0si es un empate y 1si P2 gana.

Reglas

  • La entrada siempre será válida
  • Solo se utiliza el mejor puntaje posible de cada mano para determinar un ganador. No hay desempates. Por ejemplo, [1,4,4,3,3]empatará en [1,4,4,2,2]lugar de usar los 3 y 2 como un desempate.
  • La salida debe ser uno de los 3 valores elegidos cada vez. Simplemente mapear todos los números negativos P1 Winsno está permitido y debe normalizarse.
  • Las manos inválidas, es decir, las que no tienen un 1, pierden con todas las manos válidas pero empatan con todas las demás manos inválidas. Por ejemplo, [2,2,2,2,2]corbatas [3,3,3,3,3].
  • Una mano de [1,1,1,1,1]cuenta como un conjunto válido de 6 para fines de clasificación.
  • Este es el por lo que el conteo de bytes más corto gana.

Ejemplos

#You guys are pretty good at finding edge-cases that break things. Good job!
Input:  [2,1,5,6,6], [6,2,6,6,6]
Output: P1 Wins

Input:  [2,4,5,6,6], [6,2,6,6,6]
Output: Tie

Input:  [1,2,3,4,5], [5,4,3,2,1]
Output: Tie

Input:  [1,5,5,3,2], [5,4,1,6,6]
Output: P2 Wins

Input:  [3,2,2,2,1], [4,1,3,6,6]
Output: P1 Wins

Input:  [1,1,1,1,1], [6,1,1,6,6]
Output: Tie

Input:  [1,3,3,4,4], [1,2,2,5,5]
Output: P2 Wins

Input:  [1,3,3,5,5], [1,3,3,2,2]
Output: P1 Wins

Input:  [1,3,3,3,4], [1,1,3,3,3]
Output: P2 Wins

Input:  [2,2,2,6,1], [5,3,3,1,2]
Output: P1 Wins

Input:  [5,5,5,1,5], [1,1,1,1,1]
Output: P2 Wins

Input:  [1,1,1,1,1], [1,1,5,1,1]
Output: P1 Wins
Veskah
fuente

Respuestas:

10

Jalea , 17 14 bytes

ċⱮ6Ḣ©+$®aĖUṀ)M

Pruébalo en línea!

Un enlace monádico que toma una lista de las dos listas como argumento y devuelve [1]para el jugador 1 gana, [2]para el jugador 2 gana y [1, 2]para un empate. El enlace TIO ordena esto para su visualización.

¡Gracias a @JonathanAllan por guardar 3 bytes!

Explicación

            )   | For each input list (e.g. of one list 1,1,3,3,4)
ċⱮ6             | - Count each of 1..6 (e.g. 2,0,2,1,0,0)
      $         | - Following as a monad:
   Ḣ            |   - Head (number of 1s)
    ©︎           |   - Copy to register
     +          |   - Add (e.g. 2,4,3,0,0)
       ®a       | - Register logical and with this
         Ė      | - Enumerate (e.g. [1,2],[2,4],[3,3],[4,0],[5,0])
          U     | - Reverse each (e.g. [2,1],[4,2],[3,3],[0,4],[0,5])
            Ṁ   | - Max (e.g. 4,2)
              M | Index/indices of maximal score
Nick Kennedy
fuente
1
Puede reemplazar el IṠcon My generar una lista de los ganadores.
Jonathan Allan
@JonathanAllan Buen punto! Gracias
Nick Kennedy
1
15 bytes haciendo uso del registro.
Jonathan Allan
1
Creo que ahora también puede ser redundante ya que las listas se ordenan igual que los enteros.
Jonathan Allan
1
Este es un enfoque encantador. Bien hecho.
Jonás
9

R , 115 96 bytes

-6 bytes gracias a Giuseppe.

-6 bytes gracias a Aaron Hayman.

-2 bytes gracias a Arnauld, siguiendo el formato de salida en su respuesta de JavaScript .

function(i,j)(f(i)-f(j))/0
f=function(x,s=tabulate(x,6),l=s[1]+s[-1]*!!s[1])max(l)*6+order(l)[5]

Pruébalo en línea!

Devoluciones Infpara P1,NaN para un empate, -Infpara P2.

Utiliza la función auxiliar fque calcula una puntuación para cada mano. El puntaje se define de la siguiente manera: dsea ​​el dígito que más se repite y nel número de veces que se repite. Entonces el puntaje es 6*n+dsi hay al menos un as, y0 si no hay ases. Entonces solo necesitamos encontrar al jugador con la puntuación más alta.

Sin golf:

f = function(x) {
  s = tabulate(x, 6)         # number of occurrences of each integer
  l = s[1] + s[-1] * !!s[1]  # add the number of wild aces to all values; set to 0 if s[1] == 0
  max(l) * 6 +               # highest number of repetitions (apart from aces)
    order(l)[5]              # most repeated integer (take largest in case of tie)
}
function(i, j){
  sign(f(i) - f(j))
}
Robin Ryder
fuente
Puede usar en order(l)[5]lugar de max.col(t(l),"l")obtener una solución de 96 bytes: ¡ Pruébelo en línea!
Aaron Hayman
@AaronHayman Muy bien, gracias!
Robin Ryder
6

JavaScript (ES6),  97  90 bytes

Toma entrada como (a)(b). Devoluciones +Infinitypara P1, -Infinitypara P2 o NaNpara un empate.

a=>b=>((g=(x,m)=>x>6?m*/1/.test(a):g(-~x,a.map(k=>n+=k<2|k==x,n=x/6)|m>n?m:n))()-g(a=b))/0

Pruébalo en línea!

Comentado

a => b => (                 // a[] = dice of P1; b[] = dice of P2
  ( g = (                   // g is a recursive function taking:
      x,                    //   x = dice value to test; initially, it is either undefined
                            //       or set to a non-numeric value
      m                     //   m = maximum score so far, initially undefined
    ) =>                    //
      x > 6 ?               // if x is greater than 6:
        m * /1/.test(a)     //   return m, or 0 if a[] does not contain any 1 
      :                     // else:
        g(                  //   do a recursive call:
          -~x,              //     increment x (or set it to 1 if it's non-numeric)
          a.map(k =>        //     for each dice value k in a[]:
            n +=            //       add 1 to n if:
              k < 2 |       //         k is equal to 1
              k == x,       //         or k is equal to x
            n = x / 6       //       start with n = x / 6
          ) |               //     end of map()
          m > n ?           //     if m is defined and greater than n:
            m               //       pass m unchanged
          :                 //     else:
            n               //       update m to n
        )                   //   end of recursive call
  )()                       // first call to g, using a[]
  - g(a = b)                // subtract the result of a 2nd call, using b[]
) / 0                       // divide by 0 to force one of the 3 consistent output values
Arnauld
fuente
6

05AB1E , 16 15 bytes

-1 byte gracias a JonathanAllan

εWΘ*6L¢ć+°ƶà}ZQ

Pruébalo en línea!

Devuelve [1, 0] para P1 gana, [1, 1] para empates, [0, 1] para P2 gana.

En lugar de usar el orden lexicográfico en una tupla de 2 (conteo de dados, valor de dados), esto calcula el puntaje como 10 ** recuento de dados * valor de dados. Manos sin 1 puntaje 5.

ε           }           # map each hand to its computed score
 WΘ                     # minimum == 1 (1 if the hand contains a 1, 0 otherwise)
   *                    # multiply (sets hands without 1 to [0, 0, 0, 0, 0])
    6L                  # range [1..6]
      ¢                 # count occurences of each in the hand
       ć                # head extract (stack is now [2-count, ..., 6-count], 1-count)
        +               # add the 1-count to all the other counts
         °              # 10**x
          ƶ             # multiply each element by its 1-based index
           à            # take the maximum

Z                       # maximum
 Q                      # equality test (vectorizes)
Mugriento
fuente
1
¡Ohhh ... me gusta el ć+(ahora que lo veo no puedo creer que no haya pensado en eso ...)! Eso es mucho mejor de lo que estaba intentando ... Tuve una idea similar con °. :) Excepto que ya estaba en 20 bytes y todavía tenía que solucionar un problema para el caso de prueba [[1,1,1,1,1],] [6,1,1,6,6]]... Así que gracias por ahorrarme tiempo para poder poner mi intento en el basurero ...; p
Kevin Cruijssen
1
@KevinCruijssen Sí, es increíble lo bien que ć+funciona. Mi idea inicial comenzó con æʒW}ʒ1KË, pero el [1,1,1,1,1]problema lo mata .
Grimmy
1
Sí, mi enfoque fue en la línea de ε1¢©Āy{γéθ¬sg®+°P}`.S, pero también lo [1,1,1,1,1]arruinó. Toda su respuesta tiene un buen sinergia con el WΘ*, 6L¢, ć+, y °ƶ. Especialmente los constructores Wćƶrealmente muestran su fuerza aquí.
Kevin Cruijssen
Wno es realmente necesario, 6L¢¬Ā*es el mismo conteo de bytes que WΘ*6L¢.
Grimmy
Hmm, buen punto. :) Pensó Wsin estallar y luego *mostró su fuerza, pero ¬sin estallar y luego *es básicamente lo mismo. El hecho de que no explote es la fuerza que estaba implicando, guardar un byte. Pero es de hecho principalmente ćƶ.
Kevin Cruijssen
6

Python 2 , 85 81 80 bytes

lambda p:cmp(*[max((h.count(i)+h.count(i>1),i)*(1in h)for i in[6]+h)for h in p])

Pruébalo en línea!

Devuelve 1para P1, 0para empate y -1para P2.

-1 byte, gracias al calamar

TFeld
fuente
1
Espacio en blanco entre 1y inpuede ir
Restablece Mónica el
@quid Gracias, :)
TFeld
4

Perl 6 , 60 49 bytes

&[cmp]o*.map:{.{1}&&max (.{2..6}X+.{1})Z ^5}o&bag

Pruébalo en línea!

Retornos More, Same, Lesspara P1 Wins, Tie, P2 Wins.

Explicación

       *.map:  # Map input lists
                                             &bag  # Convert to Bag
             {                             }o  # Pass to block
              .{1}&&  # Return 0 if no 1s
                    max  # Maximum of
                         .{2..6}  # number of 2s,3s,4s,5s,6s
                                X+.{1}  # plus number of 1s
                        (             )Z     # zipped with
                                         ^5  # secondary key 0,1,2,3,4
&[cmp]o  # Compare mapped values
nwellnhof
fuente
4

Consulta T-SQL, 148 bytes

Usando la variable de tabla como entrada

p: jugador

v: valor para rollo

DECLARE @ table(p int,v int)
INSERT @ values(1,5),(1,5),(1,5),(1,5),(1,5)
INSERT @ values(2,4),(2,3),(2,3),(2,1),(2,4)

SELECT sign(min(u)+max(u))FROM(SELECT(p*2-3)*(s+sum(sign(s)-1/v))*(s/5*5+v+30)u
FROM(SELECT*,sum(1/v)over(partition by p)s FROM @)c GROUP BY v,s,p)x

Pruébalo en línea

Player 1 wins returns -1
Tie returns 0 
Player 2 wins returns 1
t-clausen.dk
fuente
2

Jalea , 21 bytes

aplastado incluso antes de que lo publicara Nick Kennedy :)

’-oÆṃṀ$$Ạ?fÆṃ$L;$o5)M

Un enlace monádico que acepta una lista de jugadores que genera una lista de ganadores (indexados).

Entonces P1 es [1], P2 es [2]y un empate es [1,2].

Pruébalo en línea!

Jonathan Allan
fuente
2

PowerShell , 112 126 123 121 bytes

Toma entrada como (a)(b). Retornos -1para la victoria de P1, 1para P2 o 0para un empate.

$args|%{$d=$($_-ne1|group|sort c*,n*|%{$m=$_};(7*(($o=($_-eq1).Count)+$m.Count)+$m.Name+6*!$m)[!$o])-$d}
[math]::Sign($d)

Pruébalo en línea!

Caso de prueba @( @(1,1,5,1,1), @(1,1,1,1,1), 1)agregado.

Desenrollado:

$args|%{
    $score=$(                                            # powershell creates a new scope inside expression $(...)
        $_-ne1|group|sort count,name|%{$max=$_}          # $max is an element with the widest group and the maximum digit except 1
        $ones=($_-eq1).Count                             # number of 1s in a player's hand
        $scoreRaw=7*($ones+$max.Count)+$max.Name+6*!$max # where $max.Name is digit of the widest group
        $scoreRaw[!$ones]                                # output $scoreRaw if the array contains 1, otherwise output $null 
    )                                                    # powershell deletes all variables created inside the scope on exit
    $diff=$score-$diff
}
[math]::Sign($diff)                                     # output the score difference
mazzy
fuente
2

Wolfram Language (Mathematica) , 78 75 74 bytes

-1 byte por Greg Martin

Order@@(#~FreeQ~1||Last@Sort[Reverse/@Tally@Flatten[#/. 1->Range@6]]&)/@#&

Pruébalo en línea!

Produce -1 cuando el jugador 1 gana, 1 cuando gana el jugador 2 y 0 para un empate.

                                    Helper function to score a list:
FreeQ[#,1] ||                       If there are 0 1s, score is True
Last@Sort[                          Otherwise, take the largest element of
    Reverse/@Tally@                 the {frequency, number} pairs in the flat list
       Flatten[ #/. 1->Range@6]     where each 1 is replaced by {1,2,3,4,5,6}.
]&                              e.g. {1,3,3,5,5} -> {1,2,3,4,5,6,3,3,5,5} -> {3,5}

Order @@ (...) /@ #&                Apply this function to both lists,
                                    then find the ordering of the result.
lirtosiast
fuente
Puede guardar un byte reemplazándolo FreeQ[#,1]con #~FreeQ~1.
Greg Martin
2

Java 8, 244 240 236 215 199 bytes

a->b->{int c[][]=new int[2][7],m[]=new int[2],p,i=5;for(;i-->0;c[1][b[i]]++)c[0][a[i]]++;for(i=14;i-->4;)m[p=i%2]=Math.max(m[p],c[p][1]>0?i/2+9*(c[p][i/2]+c[p][1]):0);return Long.compare(m[0],m[1]);}

-4 bytes gracias a @someone .
-21 bytes gracias a @Neil .
-16 bytes gracias a @ceilingcat .

Devoluciones 1 si gana P1;-1si P2 gana; 0si es un empate

Pruébalo en línea.

Explicación:

a->b->{                        // Method with 2 integer-array parameters & integer return
  int c[][]=new int[2][7],     //  Create a count-array for each value of both players,
                               //  initially filled with 0s
      m[]=new int[2],          //  The maximum per player, initially 0
      p,                       //  Temp-value for the player
  i=5;for(;i-->0;              //  Loop `i` in the range (5, 0]:
    c[1]                       //   For player 2:
        [b[i]                  //    Get the value of the `i`'th die,
             ]++)              //    and increase that score-count by 1
    c[0][a[i]]++;              //   Do the same for player 1
  for(i=14;i-->4;)             //  Then loop `i` in the range (14, 4]:
    m[p=i%2]=                  //   Set the score of a player to:
                               //   (even `i` = player 1; odd `i` = player 2)
      Math.max(                //    The max between:
        m[p],                  //     The current value,
                               //     And the value we calculate as follows:
        c[p][1]>0?             //     If this player rolled at least one 1:
          i/2                  //      Use the current value `i` integer-divided by 2
          +9*                  //      With 9 times the following added:
             (c[p][i/2]        //       The amount of dice for value `i//2`
              +c[p][1])        //       Add the amount of dice for value 1
        :                      //     Else (no 1s were rolled):
         0);                   //      Use 0
  return Long.compare(m[0],m[1]);}
                               //  Finally compare the maximum scores of the players,
                               //  resulting in -1 if a<b; 0 if a==b; 1 if a>b
Kevin Cruijssen
fuente
En el bucle for sobre p, puede reemplazar ...*(c[p][1]>0?1:0)con c[p][1]>0?...:0. No puedo publicar un enlace TIO, ya que es demasiado largo y no quiero acortarlo. La versión sin golf tiene paréntesis desequilibrados en algún lugar por allí.
mi pronombre es monicareinstate el
@ alguien Ah, por supuesto, gracias. Agregué el c[p][1]>0?cheque más tarde como corrección de errores, pero aparentemente sin pensarlo mucho. Gracias por el -4. :)
Kevin Cruijssen
Porqué el *(i<2?6:i) ? Solo estás duplicando el esfuerzo para i=6y i=1. Esto puede ser justo *i(y dejar de bucle cuando llegue a 2).
Neil
Además, 9puede ser cualquier número mágico entre 5y alrededor 32, ¿verdad? Si usa 8, en lugar de (int)Math.pow(8,(...)*i)puede usar i<<3*(...).
Neil
1
Terminé con lo a->b->{int c[][]=new int[2][7],m[]=new int[2],s,p,i=5;for(;i-->0;c[1][b[i]]++)c[0][a[i]]++;for(i=7;i-->2;)for(p=2;p-->0;m[p]=s>m[p]?s:m[p])s=c[p][1]>0?i+9*(c[p][i]+(i>1?c[p][1]:0)):0;return Long.compare(m[0],m[1]);}que parece pasar todos sus casos de prueba ...
Neil
1

Jalea , 27 bytes

’o5Rṗ5¤ṢŒr$€UẎṀ1e⁸¤×µ€_/Ṡo/

Pruébalo en línea!

1 para P1, -1 para P2, 0 para empate

Explicación

’o5Rṗ5¤ṢŒr$€UẎṀ1e⁸¤×µ€_/Ṡo/  Main link
                    µ€       For each list
’                            Decrement each value (so 1s become falsy)
 o                           Vectorized logical or (this replaces previous 1s (now 0s) with the test values)
  5Rṗ5¤                      1..5 cartesian-power 5 (1,1,1,1,1; 1,1,1,1,2; 1,1,1,1,3; ...)
          $€                 For each test list
       ṢŒr                   Sort and run-length encode (gives [digit, #digit])
            U                Reverse each list (gives [#digit, digit])
             Ẏ               Tighten by one (gives a list containing each possible hand for each possible wildcard)
              Ṁ              Take the maximum
               1e⁸¤×         Multiply the list values by (whether or not the original contained a 1) - becomes [0, 0] if not
                      _/Ṡ    Take the sign of the difference between the #digits and the digits
                         o/  If the number of digits differs, then 1/-1 is returned; otherwise, check the value of the digit (could still be 0)
Hiperneutrino
fuente
1

Almádena 0.4 , 27 bytes

⢱⢙⢂⠠⡾⢃⠐⢈⠸⣞⠴⠻⠎⡥⡳⡐⢒⠘⢛⣩⡓⣮⡕⡠⣢⣡⠿

Se descomprime en esta función Wolfram Language:

Order @@ (FreeQ[#1, 1] || Last[Sort[Reverse[Tally[Flatten[#1 /. 1 -> Range[6]]], 2]]] & ) /@ #1 & 

que resulta ser exactamente lo mismo que mi respuesta de Mathematica .

lirtosiast
fuente
1

Carbón , 48 45 bytes

UMθ⮌E⁷№ι∨λ¹UMθ׬¬⊟ι⁺⊟ιιUMθ⟦⌈ι±⌕ι⌈ι⟧I⁻⌕θ⌈θ⌕θ⌊θ

Pruébalo en línea! El enlace es a la versión detallada del código. Toma entrada como una matriz de matrices y salidas -1si el jugador 1 gana, 0para un empate y 1si el jugador 2 gana. Explicación:

UMθ⮌E⁷№ι∨λ¹

Reemplace cada mano con la cuenta de cuántas veces 6..1aparecen los valores en la mano. La lista se invierte porque a) hace que sea más fácil encontrar el valor más alto con la cuenta más alta yb) hace que sea más fácil eliminar la cuenta de 1s. El recuento de 1s se duplica porque debe eliminarse dos veces, una para verificar que no es cero y otra para agregarlo a los otros recuentos.

UMθ׬¬⊟ι⁺⊟ιι

Agregue el recuento de 1s a los recuentos para 6..2, pero establezca todos los recuentos en cero si el recuento de 1s fue cero.

UMθ⟦⌈ι±⌕ι⌈ι⟧

Para cada mano, encuentre el conteo más alto y el valor más alto con ese conteo. (En realidad, encontramos el valor menos, 6ya que es más golfista)

I⁻⌕θ⌈θ⌕θ⌊θ

Determine qué mano ganó restando las posiciones de las manos ganadoras y perdedoras. (Si las manos están empatadas, la primera mano gana y pierde, por lo que el resultado es el 0deseado).

Neil
fuente
1

C (gcc) / 32 bit, 117 bytes

t;m;s(int*r){int c[6]={};for(m=0;t=*r++;m=t>m?t:m)c[--t]+=5,t=t?c[t]+t:5;t=*c?*c+m:0;}f(a,b){t=s(a)-s(b);t=(t>0)-!t;}

Pruébalo en línea!

Toma dos matrices enteras terminadas en cero. Retornos 1, 0, -1para P1 Wins, P2 Wins, Tie.

nwellnhof
fuente
1
@Veskah OK, arreglado.
nwellnhof
1

J , 47 44 bytes

*@-&([:({.([:>./#\@]+9^*@[*+)}.)1#.i.@6=/<:)

Pruébalo en línea!

Inspirado por la idea de Nick Kennedy.

sin golf

*@-&([: ({. ([: >./ #\@] + 9 ^ *@[ * +) }.) 1 #. i.@6 =/ <:)
Jonás
fuente
1

Perl 5 -MList::Util=max -pl , 80 bytes

sub t{$t=pop;$_=max map$_ x$t=~s/$_//g,2..6;/./;$t&&$_.$t*($&||6)}$_=t($_)<=>t<>

Pruébalo en línea!

Entrada:

Cada jugador en una línea separada, sin espacios

Salida:

1 La línea uno gana

0 Corbata

-1 Línea dos victorias

Xcali
fuente
1
Cambiado en función de su aclaración de las reglas del juego
Xcali