Anota un juego de bolos

25

Su tarea es resumir y obtener el puntaje de un jugador en un juego de bolos de 10 pines después de hasta 21 tiradas .

Los rollos se representan como una secuencia de enteros en su método de entrada preferido . Cada número entero corresponde al número de pines que fueron derribados en ese rollo.

Tanteo

Después de cada ronda, el número de pines derribados en esa ronda se cuenta en la puntuación final. Si un jugador derriba los diez pines en la primera tirada de una ronda, esto es un strike , y la ronda ha terminado. De lo contrario, la ronda dura un rollo más. Si el segundo lanzamiento de una ronda derriba todos los pasadores restantes, este es un repuesto .

Por cada golpe hay una bonificación igual a la suma de pines derribados en las dos tiradas siguientes. Para cada repuesto hay una bonificación igual al número de pines derribados en la próxima tirada.

La décima y última ronda, el jugador puede recibir tiradas adicionales: en caso de un golpe, el jugador obtiene dos tiradas más para compensar su bonificación de golpe. En caso de repuesto, el jugador obtiene una tirada más.

Ejemplos

Input: 4 3 8 2 7 1 10 7 3 0 10 2 2 10 10 5 4
Output: 131

Input: 10 10 9 1 7 3 2 7 10 1 9 10 7 1 10 10 10
Output: 183

Reglas

  • Puede suponer que la entrada es válida.
  • Según el comentario de Mego, he aflojado los requisitos para que los métodos de entrada / salida cumplan con nuestro estándar actual .
  • Se permiten respuestas en idiomas más nuevos que el desafío.
  • ¡El código más corto gana!
daniero
fuente
¿Recuerdo correctamente que los bonos no se acumulan?
Titus
@Titus No estoy exactamente seguro de lo que quieres decir, pero no, las bonificaciones no se "acumulan", es decir, para un golpe agregas el número de pines que se derriban en los dos próximos lanzamientos , independientemente de si son golpes o no. Entonces, el puntaje máximo para un strike es de 30 puntos, y el máximo para un juego completo es de 300.
daniero
¿Los argumentos de línea de comandos distintos califican como space separated integers?
Titus
1
@Titus seguro. Esta es una publicación antigua: el consenso de hoy sobre los métodos de entrada aceptables no se estableció en este momento. En realidad, ahora no veo por qué el estándar de hoy no debería aplicarse a esto (incluidos los parámetros de función, etc.), aunque no soy fanático de cambiar las reglas del desafío de manera retroactiva.
daniero
1
@daniero El consejo habitual es que es aceptable aflojar las reglas para que se ajusten a los estándares modernos, siempre que no cambie drásticamente el desafío.
Mego

Respuestas:

6

GolfScript, 50 41 caracteres

~0]-1%~0{\.9>{+1$3$}{@+.9>3$*}if++}10*p];

Otro intento en GolfScript ( ejecútelo en línea ).

Una explicación del código sigue. La solución utiliza la naturaleza de la pila del problema (consume rollos uno tras otro) pero, por lo tanto, la entrada debe invertirse.

~0          # Take the input and evaluate to single numbers on the stack. Add zero.
]-1%~       # Reverse the stack (make array, reverse array, dump array)

0           # Start with a sum of zero
{           # Perform this block 10 times (once for each round)
  \         #   Take the next roll
  .9>{      #   If it is a strike
    +       #     Add the value of the roll to the sum
    1$3$    #     and duplicate top two members of the stack (i.e. next two rolls).
  }{        #   ... else ...
    @+      #     Take the next roll and add with first roll in round.
    .9>     #     Does this sum show a spare?
    3$*     #     Get next roll (potential bonus) and multiply with yes/no.
            #     Since we pushed an additional 0 in the beginning 
            #     there is a spare roll even for the last round.
  }if       #   endif
  ++        #   Add top three stack entries together
            #   (i.e. sum+2 bonus rolls for strike, sum+rolls+bonus else)
}10*        # Loop ten times

p];         # Sum is top of stack. Print sum and discard any leftover rolls.

Versión previa:

~].1>.1>]zip{((.10<{@(0=@+@1>1$9><}*@}10*;]{+}.@**
Howard
fuente
5

Python, 116 110 105 103 100 99 caracteres

z=map(int,raw_input().split())
s=0
exec('s+=sum(z[:2+(z[0]+z[1]>9)]);z=z[2-(z[0]>9):];'*10)

Gastar 30 caracteres en la entrada es molesto. Sugerencias bienvenidas.

Muchas gracias a Howard por las mejoras.

Steven Rumbalski
fuente
Puede reemplazar 1+(z[i]!=10)con 2-(z[i]>9)para guardar un personaje.
Howard
@Howard: Excelente sugerencia. Lo he incorporado a mi respuesta. Se salvó dos personajes.
Steven Rumbalski
Y dos más si lo elimina por icompleto (establecido en 0) y en lugar de i+=...usarloz=z[2-(z[0]>9)::];
Howard
@Howard: Gracias de nuevo. Guardado tres personajes.
Steven Rumbalski
Los estándares para E / S son generalmente más flexibles ahora, por lo que z=input()deberían estar bien (tomando efectivamente una representación en cadena de una lista de intsy eval). Sin embargo, los programas completos deberían aparecer en algún lugar (creo que también era el caso en ese entonces). Como tal, creo que esto puede cambiarse a este programa de 78 bytes
Jonathan Allan el
4

R, 101 bytes

No estoy seguro de por qué este desafío fue rechazado, pero me gusta, así que responderé tarde de todos modos.

f=function(x,s=0,c=10)`if`(c&length(x),f(x[-(0:(x[1]!=10)+1)],sum(x[1:(2+(sum(x[1:2])>9))])+s,c-1),s)

Pruébalo en línea!

Sin golf:

f <- function(throws, score = 0, count = 10){
  if(count != 0 & length(throws) != 0){
    IsStrike <- throws[1] == 10
    IsStrikeOrSpare <- sum(throws[1:2]) >= 10
    f(throws[-c(1, 2 * !IsStrike)],
      score + sum(throws[c(1:(2 + IsStrikeOrSpare))]),
      count - 1)
  } else {
    return(score)
  }
}

Función recursiva. Toma xcomo entrada, que contiene los puntajes. Inicializa los snúcleos y cmuestra la cantidad de rondas lanzadas.

La instrucción if verifica si se lanzan 10 rondas o si xestá vacía. Si ese es el caso, se devuelve el puntaje. De lo contrario, la función se llamará a sí misma de la siguiente manera:

Elimina los lanzamientos x, verificando si es un strike o no. Si es así, se elimina la primera entrada, de lo contrario, las dos primeras. (S=x[1]!=10)comprueba huelgas. Eliminamos el -índice ( ) 0:S, donde Ses 1 si es un strike y 0 si no. Y luego añadimos uno: -(0:(x[1]!=10)+1). Pasamos el acortado xa la próxima llamada.

En cuanto al puntaje, esto se encuentra tomando x[1:2]si es un turno regular y x[1:3]si es un golpe o un repuesto. Verificamos si sum(x[1:2])es mayor o igual que 10. Si es un strike, obviamente este es el caso. Si es un repuesto, entonces esto también funciona. Entonces, si esto es VERDADERO, agregamos x[3]a la suma. Esto luego se agrega a s.

JAD
fuente
1

CoffeeScript ( 234 215 170)

z=(a)->b=(Number i for i in a.split(' ').reverse());t=0;(r=b.pop();l=b.length;if(9<r)then(t+=r;t+=b[l-1]+b[l-2];)else(f=r+b.pop();t+=f;(t+=b[l-2])if 9<f))for i in[0..9];t

EDITAR : una fuerte reescritura, plagando descaradamente el gran enfoque basado en la pila de Howard. Estoy seguro de que se puede eliminar más para acceder al último elemento de una matriz sin destruirlo ...

Johno
fuente
1

Rubí, 252 bytes

Acepta la entrada en una matriz, agrega todos los elementos primero, luego busca la bonificación de repuesto y huelga

s,p,t,r=0,0,1,1
o=ARGV
o.each_with_index do |m,n|
y=m.to_i
s+=y
if r<10
p+=y
if p==10&&t==1
r,p=(r+1),0
s+=o[n+1].to_i+o[n+2].to_i
elsif p<10&&t==1
t=2
elsif p<10&&t==2
t,p,r=1,0,(r+1)
elsif p==10&&t==2
t,p,r=1,0,(r+1)
s+=o[n+1].to_i
end end end
puts s
principianteProg
fuente
1

PHP, 82 bytes

for($a=$argv;$r++<10;$i+=$p<10)$s+=(9<$q=$a[++$i+1]+$p=$a[$i])*$a[$i+2]+$q;echo$s;

toma datos de los argumentos de la línea de comandos; ejecutarlo -nro probarlo en línea .

Descompostura

for($a=$argv;       # import arguments
    $r++<10;        # loop through rounds
    $i+=$p<10)          # 6. if no strike, increment throw count again
    $s+=(9<
        $q=$a[++$i+1]+  # 1. increment throw count  2. $q=second throw plus
        $p=$a[$i]       # 3. $p=first throw
        )*$a[$i+2]      # 4. if $q>9 (strike or spare), add third throw to sum
    +$q;                # 5. add first and second throw to sum
echo$s;             # print sum
Titus
fuente
1

Gelatina ,  36  35 bytes

+\µi©⁵+Ị$ḂḤị;®×Ị¤¡-
;0Ç3ƤFṣ-m€2Fḣ⁵S

Un enlace monádico que acepta una lista de enteros y devuelve un entero.

Pruébalo en línea!

¿Cómo?

Calcula el puntaje de cada carrera superpuesta de tres cuencos como si fuera uno que comenzó al comienzo de un cuadro y, opcionalmente, agrega un identificador de huelga ( -1), aplana esta lista resultante, la divide en los identificadores de huelga, luego descarta cada segundo resultado de cada fragmento (eliminando los puntajes de esas carreras que realmente no comenzaron con el inicio de un fotograma).

Para atender el cuadro final, primero se agrega un cero a la entrada (para permitir el corte en tres partes para permitir que un cuadro comience en lo que fue el penúltimo tazón) y las puntuaciones resultantes se truncan a los primeros diez (para eliminar el ahora posible 11o cuadro falso) antes de resumirlos.

+\µi©⁵+Ị$ḂḤị;®×Ị¤¡- - Link 1, threeBowlEvaluate: list, bowlScores
                    -               e.g. [0,4,6]   [9,1,10]   [0,4,4]  [10,7,9]
 \                  - cumulative reduce with:
+                   -   addition         [0,4,10]  [9,10,20]  [0,4,8]  [10,17,26]
  µ                 - monadic chain separation, call that "left"
     ⁵              - literal ten        10        10         10       10
   i                - first index in left 3         2 (spare)  0        1 (strike)
    ©               - (copy to register for later reuse)
        $           - last two links as a monad (f(x)):
       Ị            -   abs(x) <= 1       0         0          1        1
      +             -   add x             3         2          1        2
         Ḃ          - modulo by 2         1         0          1        0
          Ḥ         - double              2         0          2        0
           ị        - index into left (both 1-indexed and modular)
                    -            ...      4        20          4       26
                  - - literal -1         -1        -1         -1       -1
                 ¡  - repeat:
            ;       - ...action: concatenate
                ¤   - ...number of times: nilad followed by link(s) as a nilad:
             ®      -   z from register   3         2          0        1
               Ị    -   abs(z) <= 1       0         0          1        1
              ×     -   multiply          0         0          0        1 (strike)
                    - ...yielding:        4         20         4        [26,-1]

;0Ç3ƤFṣ-m€2Fḣ⁵S - Main link: list bowlValues
                -                    e.g. [4,3,8,2,7,1,10,7,3,0,10,2,2,10,10,5,4]
 0              - literal zero            0
;               - concatenate             [4,3,8,2,7,1,10,7,3,0,10,2,2,10,10,5,4,0]
   3Ƥ           - for infixes of length 3:
  Ç             -   last link (1) as a monad
                -                         [7,11,17,9,8,11,[20,-1],10,3,12,[14,-1],4,12,[25,-1],[19,-1],9]
     F          - flatten                 [7,11,17,9,8,11,20,-1,10,3,12,14,-1,4,12,25,-1,19,-1,9]
       -        - literal -1              -1
      ṣ         - split at                [[7,11,17,9,8,11,20],[10,3,12,14],[4,12,25],[19],[9]]
          2     - literal two             2
        m€      - modulo slice for €ach   [[7,17,8,20],[10,12],[4,25],[19],[9]]
           F    - flatten                 [7,17,8,20,10,12,4,25,19,9]
             ⁵  - literal ten             10
            ḣ   - head to index           [7,17,8,20,10,12,4,25,19,9] (no effect this time)
              S - sum                     131
Jonathan Allan
fuente
0

Perl, 140?

Primer intento:

#!/usr/bin/perl
# usage: ./bowling.pl [list of scores]

@A=@ARGV;{last if(9<$n++);$a=shift@A;$S+=$a;($S+=$A[0]+$A[1])&redo if($a==10);$b=shift@A;$S+=$b;($S+=$A[0])&redo if(10==$a+$b);redo}print$S

Lamentablemente, hay ciertos casos en los que falla. Vendré y lo rehaceré más tarde.

o_o
fuente