Puntuación de billar

16

Estaba viendo el campeonato mundial de billar y me preguntaba ...

Puntuación de billar

En el juego de billar hay ciertas reglas que también debes cumplir:

  • Cuando hay bolas rojas en la mesa, durante tu turno primero debes colocar una bola roja.
  • Después de colocar cada bola roja, debes colocar una bola de color (no roja) (la bola de color en maceta se vuelve a colocar sobre la mesa)
  • Después de que todas las bolas rojas estén arriba (hay 15), primero puede elegir una bola de color y luego comenzar con la bola con la puntuación más baja y avanzar hasta la bola con la puntuación más alta (no se reemplazan)
  • No colocar macetas en ningún punto termina tu turno.
  • Puntos por pelota
    • Bola roja: 1 punto
    • Bola amarilla: 2 puntos
    • Bola verde: 3 puntos
    • Bola marrón: 4 puntos
    • Bola azul: 5 puntos
    • Bola rosa: 6 puntos
    • Balón negro: 7 puntos

La pregunta

Comienzas con una mesa con todas las bolas todavía en ella - 15 rojas y una de cada una de las otras bolas de colores - y se te da la puntuación de un jugador en el billar después de su primer turno, ¿cuáles son las formas en que podrían haber logrado esto? ¿Puntuación?

La entrada será una puntuación que va del 1 al 147. Puede elegir si es un entero o una cadena. La salida debe ser las diferentes combinaciones de la cantidad de veces que macetaste cada bola.

Casos de prueba:

Input: 4
Output: 
1r 1g
2r 1y
Input: 25
Output:
4r 3b
5r 2b 1br 1y
5r 2b 2g
...
9r 8y

Reglas:

  • Puede elegir si genera las posibilidades divididas por una nueva línea o un separador de algún tipo (/ ,; | \ o incluso otros que me faltan)

Este es codegolf, por lo que gana el código más corto.

Michthan
fuente
¿Puedo mostrar como lista de matrices?
Leaky Nun
1
Con respecto a la salida de una matriz: ¿el número de bolas ordenadas por puntaje no es ambiguo, por lo que tal vez "5r 3b 2g"podría salir como [5,0,2,0,3,0,0](siempre y cuando sea consistente)?
Jonathan Allan
2
Usas bpara marrón y blpara azul; entonces bkpara negro? ¿Podríamos usar n, ey k(últimas letras) para estos tres? ¿Qué tal dlerunaidentificar los ocho colores (tercera letra de cada uno)?
Jonathan Allan
1
@ Shaggy, si usa una indicación de color como dleruna u otro, no. Si solo usa una matriz como [5 0 0 4 1 0 0], entonces deben ordenarse de menor a mayor.
Michthan
1
Solo con fines ilustrativos, aquí hay un ejemplo (sorprendente) de una ruptura 147 de Ronnie "The Rocket" O 'Sullivan.
Arnauld

Respuestas:

6

Gelatina , 66 bytes

L⁼30µÐfµ7Ḋ;\¤;€Ṣ€µ€;/
ċ1<⁴µÐfµ;Ç
7Ḋœċ⁴Ḷ¤;/L€;$€;@þ2B¤;/ḟ€0ÇS⁼¥Ðf⁸G

Bueno, ¡es demasiado lento para TIO ahora!
... así que aquí hay una pasta de las 2636 formas de hacer exactamente 100 producidos sin conexión.
... y aquí hay una versión que se ejecutará allí con solo SEIS rojos (pausa máxima = 75)

Imprime una cuadrícula de números, cada línea es una lista de valores de bola separados por espacios (por ejemplo, tres rojos y dos verdes estarían en una lectura de línea 1 1 1 3 3).


Para una versión agrupada de valores que imprime líneas de conteos junto con los nombres completos de las bolas, a 102 bytes:

ŒrÑ€
Ṫ;ị“¡^³ṗ⁼¬wḌ⁼ø÷OẏK¦ẆP»Ḳ¤$K
L⁼30µÐfµ7Ḋ;\¤;€Ṣ€µ€;/
ċ1<⁴µÐfµ;Ç
7Ḋœċ⁴Ḷ¤;/L€;$€;@þ2B¤;/ḟ€0ÇS⁼¥Ðf⁸Ñ€K€Y

¿Cómo?

L⁼30µÐfµ7Ḋ;\¤;€Ṣ€µ€;/ - Link 1, create post-red-ball games: list of all pre-yellow-ball-games
    µÐf               - filter keep if:
L⁼30                  -   length equals 30 (games that get on to the yellow)
       µ         µ€   - for €ach sequence leading to the yellow:
            ¤         -   nilad followed by link(s) as a nilad:
        7Ḋ            -     7 dequeued  = [2,3,4,5,6,7]
          ;\          -     ;\ cumulative reduce with concatenation  = [[2],[2,3],[2,3,4],...]
             ;€       - concatenate the sequence with €ach of those
               Ṣ€     - sort each one
                   ;/ - reduce with concatenation (flatten by one)

ċ1<⁴µÐfµ;Ç - Link 2, filter bogus entries created and append post-yellow-ball games: list of pre-yellow-ball games (along with the bogus ones with 16 reds potted)
    µÐf    - filter keep if:
ċ1         -   count ones
   ⁴       -   literal 16
  <        -   less than?
       µ   - monadic chain separation
         Ç - call the last link (1) as a monad
        ;  - concatenate

7Ḋœċ⁴Ḷ¤;/L€;$€;@þ2B¤;/ḟ€0ÇS⁼¥Ðf⁸G - Main link: score
7Ḋ                                - 7 dequeued = [2,3,4,5,6,7]
      ¤                           - nilad followed by link(s) as a nilad:
     ⁴                            -   literal 16
    Ḷ                             -   lowered range = [0,1,2,...,15]
  œċ                              - combinations with replacement (every possible colour-ball selection that goes with the red pots)
       ;/                         - reduce with concatenation (flatten by one)
            $€                    - last two links as a monad for €ach:
         L€                       -   length of €ach (number of coloured balls potted)
           ;                      -   concatenate
                   ¤              - nilad followed by link(s) as a nilad:
                 2B               -   2 in binary = [1,0]
                þ                 - outer product with:
              ;@                  -   concatenation with reversed @rguments
                    ;/            - reduce with concatenation (flatten by one)
                      ḟ€0         - filter discard zeros from €ach
                         Ç        - call the last link (2) as a monad
                             Ðf   - filter keep:
                            ¥  ⁸  -   last two links as a dyad, with score on the right
                          S⁼      -     sum(ball values) is equal to score?
                                G - format as a grid
                                  - implicit print
Jonathan Allan
fuente
Funciona bien para todos los casos que he probado. Solo en algunos casos el último código da ceros a la izquierda.
Michthan
Ah sí, deberían haber sido filtrados ... Solucionado.
Jonathan Allan
Su salida para el 53 es inequívoca como dije antes, pero todavía dudo si es legible para todos ...
Michthan
Es mucho mejor en la cuadrícula. Si no hay respuestas más cortas en los próximos días, ¡voy a aceptar su respuesta!
Michthan
Hmm Tengo 2636 combinaciones de ruptura del siglo. Entonces, tú o yo estamos equivocados ...
Arnauld
4

JavaScript (ES7), 188 180 178 bytes

Devuelve una matriz de matrices (ordenadas de rojo a negro).

n=>[...Array(17**6)].map((_,x)=>[2,3,4,5,6,p=7].map(v=>(k=a[++j]=x%17|0,x/=17,t+=k,p+=!!(y=y&&k),s-=k*v),y=s=n,a=[j=t=0])&&(s==15|s>=t)&s<16&s<t+2&t<9+p&&(a[0]=s,a)).filter(a=>a)

Comentado

Nota : Esta versión no incluye la última optimización activada p(ahora inicializada en 7), lo que hace que la lógica sea más difícil de entender.

n =>                              // given a target score n:
  [...Array(17**6)].map((_, x) => // for each x in [0 .. 17^6 - 1]:
    [2, 3, 4, 5, 6, 7].map(v =>   //   for each v in [2 .. 7] (yellow to black):
      ( k = a[++j] = x % 17 | 0,  //     k = a[j] = number of colored balls of value v
        x /= 17,                  //     update x to extract the next value
        t += k,                   //     update t = total number of colored balls
        p += !!(                  //     update p = number of consecutive colors that were
          y = y && k              //     potted at least once, using y = flag that is zeroed
        ),                        //     as soon as a color is not potted at all
        s -= k * v ),             //     subtract k * v from the current score s
      y = s = n,                  //     initialize y and s
      a = [j = t = p = 0]         //     initialize a, j (pointer in a), t and p
    )                             //   at this point, s is the alleged number of red balls
    &&                            //   this combination is valid if we have:
      (s == 15 | s >= t) &        //     - 15 red balls or more red balls than colored ones
      s < 16 &                    //     - no more than 15 red balls
      s < t + 2 &                 //     - at most one more red ball than colored ones
      t < 16 + p                  //     - no more than 15 + p colored balls
    &&                            //   if valid:
      (a[0] = s, a)               //     update the combination with red balls and return it
  ).filter(a => a)                // end of outer map(): filter out invalid entries

Salida de ejemplo

A continuación se muestra la salida para n = 140:

//  R   Y  G  Br Bl P  Bk 
[ [ 15, 1, 1, 1, 1, 8, 9  ],
  [ 15, 1, 1, 1, 2, 6, 10 ],
  [ 15, 1, 1, 1, 3, 4, 11 ],
  [ 15, 1, 1, 2, 1, 5, 11 ],
  [ 15, 1, 1, 1, 4, 2, 12 ],
  [ 15, 1, 1, 2, 2, 3, 12 ],
  [ 15, 1, 2, 1, 1, 4, 12 ],
  [ 15, 1, 1, 2, 3, 1, 13 ],
  [ 15, 1, 1, 3, 1, 2, 13 ],
  [ 15, 1, 2, 1, 2, 2, 13 ],
  [ 15, 2, 1, 1, 1, 3, 13 ],
  [ 15, 1, 2, 2, 1, 1, 14 ],
  [ 15, 2, 1, 1, 2, 1, 14 ],
  [ 15, 1, 1, 1, 1, 1, 15 ] ]

Manifestación

Esto es demasiado lento para un fragmento. Puedes probarlo aquí en su lugar. (Puede recibir una o dos alertas de script que no responden , pero eventualmente debería completarse).

Arnauld
fuente