Marque um jogo de boliche

25

Sua tarefa é resumir e obter a pontuação de um jogador em um jogo de boliche de 10 pinos após até 21 jogadas .

Os rolos são representados como uma sequência de números inteiros no seu método preferido de entrada . Cada número inteiro corresponde ao número de pinos que foram derrubados nesse rolo.

Pontuação

Após cada rodada, o número de pinos derrubados nessa rodada é contabilizado na pontuação final. Se um jogador derruba todos os dez pinos no primeiro lançamento de uma rodada, isso é um golpe e a rodada termina. Caso contrário, a rodada dura mais um rolo. Se o segundo rolo de uma rodada derrubar todos os pinos restantes, isso é uma reposição .

Para cada ataque, há um bônus igual à soma dos pinos derrubados nas duas próximas jogadas. Para cada reposição, há um bônus igual ao número de pinos derrubados no próximo rolo.

Na 10ª e última rodada, o jogador pode receber jogadas extras: no caso de um ataque, o jogador recebe mais duas jogadas para compensar seu bônus de ataque. Em caso de reposição, o jogador recebe mais uma jogada.

Exemplos

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

Regras

  • Você pode assumir que a entrada é válida.
  • De acordo com o comentário de Mego, afrouxei os requisitos para os métodos de entrada / saída para atender nosso padrão atual .
  • Respostas em idiomas mais recentes que o desafio são permitidas
  • O menor código vence!
daniero
fonte
Lembro-me corretamente de que os bônus não são acumulados?
Titus
@Titus Não sei exatamente o que você quer dizer, mas não, os bônus não "empilham", ou seja, para uma batida, você adiciona o número de pinos que são derrubados nas próximas jogadas , independentemente de serem greves. ou não. Pontuação Assim máximo para uma greve é de 30 pontos, e máximo para um jogo inteiro é 300.
daniero
Os argumentos distintos da linha de comando se qualificam como space separated integers?
Titus
1
@ Titus certeza. Este é um post antigo - O consenso de hoje sobre métodos de entrada aceitáveis ​​não foi estabelecido neste momento. Na verdade, não vejo agora por que o padrão de hoje não se aplica a isso (incluindo parâmetros de função etc.), embora eu não seja fã de mudar as regras do desafio de maneira retroativa.
Daniero
1
@daniero O conselho usual é que seja aceitável afrouxar as regras para atender aos padrões modernos, desde que isso não mude drasticamente o desafio.
Mego 24/08

Respostas:

6

GolfScript, 50 41 caracteres

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

Outra tentativa no GolfScript ( execute-o online ).

Segue uma explicação do código. A solução utiliza a natureza da pilha do problema (consumir rolos um após o outro), mas, portanto, a entrada deve ser revertida.

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

Versão anterior:

~].1>.1>]zip{((.10<{@(0=@+@1>1$9><}*@}10*;]{+}.@**
Howard
fonte
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 na entrada é cansativo. Sugestões são bem-vindas.

Muito obrigado a Howard por melhorias.

Steven Rumbalski
fonte
Você pode substituir 1+(z[i]!=10)por 2-(z[i]>9)para salvar um caractere.
1011 Howard
@ Howard: Excelente sugestão. Eu o incorporei na minha resposta. Ele salvou dois caracteres.
Steven Rumbalski 10/10
E mais dois se remover icompletamente (definido como 0) e em vez de i+=...usoz=z[2-(z[0]>9)::];
Howard
@ Howard: Obrigado novamente. Salvou três caracteres.
Steven Rumbalski 10/10/12
Normas para I / O são geralmente mais flexíveis agora assim z=input()deve ser fino (tendo efetivamente uma representação em cadeia de uma lista de ints e evaling-lo). No entanto, os programas completos devem sair em algum lugar (acho que também foi esse o caso naquela época). Como tal, eu acredito que este pode ser alterado para este programa 78 byte
Jonathan Allan
4

R, 101 bytes

Não sei por que esse desafio foi ultrapassado, mas eu gosto, então vou responder de qualquer maneira tarde.

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)

Experimente online!

Ungolfed:

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

Função recursiva. Toma xcomo entrada, que contém as pontuações. Inicializa os snúcleos e conça a quantidade de rodadas lançadas.

A instrução if verifica se 10 rodadas são lançadas ou se xestá vazia. Se for esse o caso, a pontuação é retornada. Caso contrário, a função se chamará da seguinte maneira:

Ele remove os arremessos de x, verificando se é um ataque ou não. Nesse caso, a primeira entrada é removida, e as duas primeiras. (S=x[1]!=10)verifica se há greves. Removemos o -índice ( ) 0:S, onde Sé 1 se for um aviso e 0 se não. E, então, adicionar um: -(0:(x[1]!=10)+1). Passamos o encurtado xpara a próxima ligação.

Quanto à pontuação, isso é encontrado x[1:2]se for um turno regular e x[1:3]se for um ataque ou um sobressalente. Verificamos se sum(x[1:2])é maior ou igual a 10. Se for uma greve, obviamente este é o caso. Se é um sobressalente, isso também funciona. Portanto, se isso é VERDADEIRO, adicionamos x[3]à soma. Isso é então adicionado a s.

JAD
fonte
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

EDIT : Uma reescrita robusta, plagiando descaradamente a grande abordagem baseada em pilha de Howard. Estou confiante de que mais pode ser retirado para acessar o último elemento de uma matriz sem destruí-lo ...

Johno
fonte
1

Ruby, 252 bytes

Aceita entrada em uma matriz, adicione todos os elementos primeiro e, em seguida, procure por bônus de reposição e greve

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
beginnerProg
fonte
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;

recebe entrada de argumentos de linha de comando; executar -nrou testá-lo online .

demolir

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

Perl 5 , 65 + 2 = 67 bytes

Requer -apsinalizadores

$\+=(($"=shift@F)<10?$"+=shift@F:10+$F[1])+$F[0]*(9<$")for 0..9}{

Experimente online!

Xcali
fonte
1

Geléia ,  36  35 bytes

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

Um link monádico que aceita uma lista de números inteiros e retorna um número inteiro.

Experimente online!

Quão?

Calcula a pontuação de cada execução sobreposta de três tigelas como se fosse uma que começou no início de um quadro e, opcionalmente, acrescenta um identificador de ocorrência (-1 ocorrência ), aplaina essa lista resultante, divide-a nos identificadores de ocorrência e descarta cada segundo resultado de cada pedaço (removendo a pontuação das corridas que realmente não começaram com o início de um quadro).

Para atender ao quadro final, um zero é anexado primeiro à entrada (para permitir que o fatiamento em três sentidos permita que um quadro comece no que era a penúltima tigela) e as pontuações resultantes são truncadas para os dez primeiros (para remover o agora possível falso quadro 11) antes de resumir.

+\µ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
fonte
0

Perl, 140?

Primeira tentativa:

#!/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

Infelizmente, há certos casos em que falha. Eu irei refazê-lo mais tarde.

o_o
fonte