Segna una partita a Bowling


25

Il tuo compito è quello di riassumere e ottenere il punteggio di un giocatore in una partita di bowling a 10 pin dopo un massimo di 21 tiri .

I rulli sono rappresentati come una sequenza di numeri interi nel metodo di input preferito . Ogni numero intero corrisponde al numero di pin eliminati in quel tiro.

punteggio

Dopo ogni round il numero di pin eliminati in quel round viene conteggiato nel punteggio finale. Se un giocatore abbatte tutti e dieci i birilli nel primo tiro di un round, questo è uno strike e il round è finito. Altrimenti, il round dura per un altro tiro. Se il secondo tiro di un round abbatte tutti i perni rimanenti, questo è un ricambio .

Per ogni strike c'è un bonus pari alla somma dei pin eliminati nei due tiri successivi. Per ogni riserva c'è un bonus pari al numero di spilli buttati giù nel tiro successivo.

Nel decimo e ultimo round, al giocatore possono essere assegnati tiri extra: in caso di sciopero, il giocatore ottiene altri due tiri per compensare il suo bonus di sciopero. In caso di riserva, il giocatore ottiene un altro tiro.

Esempi

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

Regole

  • Si può presumere che l'input sia valido.
  • Secondo il commento di Mego ho allentato i requisiti per i metodi di input / output per soddisfare il nostro standard attuale .
  • Sono consentite risposte in lingue più recenti della sfida
  • Vince il codice più corto!

Ricordo correttamente che i bonus non si accumulano?
Tito,

@Titus Non sono esattamente sicuro di cosa intendi, ma no, i bonus non si "impilano", cioè per uno strike aggiungi il numero di pin che vengono buttati giù nei due tiri successivi , indipendentemente dal fatto che siano strike o no. Quindi il punteggio massimo per uno strike è di 30 punti e il massimo per un'intera partita è 300.
daniero,

Gli argomenti distinti della riga di comando sono qualificati come space separated integers?
Tito,

1
@Titus certo. Questo è un vecchio post - Il consenso di oggi sui metodi di input accettabili non è stato stabilito a questo punto. In realtà, non vedo ora perché lo standard di oggi non dovrebbe applicarsi a questo (compresi i parametri di funzione ecc.), Anche se non sono un fan di cambiare le regole della sfida in modo retroattivo.
daniero,

1
@daniero Il consueto consiglio è che è accettabile allentare le regole per adattarle agli standard moderni, purché non cambi drasticamente la sfida.
Mego

Risposte:


6

GolfScript, 50 41 caratteri

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

Un altro tentativo in GolfScript (eseguilo online ).

Segue una spiegazione del codice. La soluzione utilizza la natura dello stack del problema (consuma i rulli uno dopo l'altro) ma pertanto l'input deve essere invertito.

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

Versione precedente:

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

5

Python, 116 110 105 103 100 99 caratteri

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)

Trascorrere 30 caratteri in input è fastidioso. Suggerimenti benvenuti.

Mille grazie a Howard per i miglioramenti.


È possibile sostituire 1+(z[i]!=10)con 2-(z[i]>9)per salvare un carattere.
Howard,

@Howard: eccellente suggerimento. L'ho incorporato nella mia risposta. Ha salvato due personaggi.
Steven Rumbalski,

E altri due se rimuovi icompletamente (impostato su 0) e invece di i+=...utilizzarez=z[2-(z[0]>9)::];
Howard

@Howard: grazie ancora. Hai salvato tre personaggi.
Steven Rumbalski,

Gli standard per l'I / O sono generalmente più flessibili ora, quindi z=input()dovrebbe andare bene (prendere effettivamente una rappresentazione in forma di stringa di un elenco inte evalinserirla). Tuttavia, i programmi completi dovrebbero essere prodotti da qualche parte (penso che anche in questo caso fosse così). In quanto tale, credo che questo possa essere cambiato in questo programma da 78 byte
Jonathan Allan,

4

R, 101 byte

Non sono sicuro del perché questa sfida sia stata superata, ma mi piace, quindi risponderò tardi comunque.

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)

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

Funzione ricorsiva. Accetta xcome input, che contiene i punteggi. Inizializza i score e conora la quantità di round lanciati.

L'istruzione if verifica se vengono lanciati 10 round o se xè vuoto. In tal caso, il punteggio viene restituito. Altrimenti la funzione si chiamerà come segue:

Rimuove i tiri da x, controllando se è un colpo o meno. In tal caso, la prima voce viene rimossa, altrimenti le prime due. (S=x[1]!=10)controlla gli scioperi. Rimuoviamo l' -indice ( ) 0:S, dove Sè 1 se si tratta di un avvertimento e 0 in caso contrario. E poi aggiungiamo una: -(0:(x[1]!=10)+1). Passiamo l'accorciato xalla chiamata successiva.

Per quanto riguarda il punteggio, questo si ottiene prendendo x[1:2]se si tratta di un turno regolare e x[1:3]se si tratta di uno strike o uno di riserva. Controlliamo se sum(x[1:2])è maggiore o uguale a 10. Se si tratta di uno strike, ovviamente è così. Se è un ricambio, funziona anche questo. Quindi, se questo è VERO, aggiungiamo x[3]alla somma. Questo viene quindi aggiunto a s.


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 : una pesante riscrittura, spudoratamente plagiando il grande approccio basato su stack di Howard. Sono sicuro che più può essere rimosso per accedere all'ultimo elemento di un array senza distruggerlo ...


1

Rubino, 252 byte

Accetta l'input in un array per prima cosa aggiunge tutti gli elementi, quindi cerca bonus di riserva e strike

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

1

PHP, 82 byte

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

accetta input dagli argomenti della riga di comando; eseguirlo -nro testarlo online .

abbattersi

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


1

Gelatina ,  36  35 byte

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

Un collegamento monadico che accetta un elenco di numeri interi e restituisce un numero intero.

Provalo online!

Come?

Calcola il punteggio di ciascuna serie sovrapposta di tre ciotole come se fosse una che iniziava all'inizio di un frame e opzionalmente aggiunge un identificatore di strike ( -1), appiattisce questo elenco risultante, lo divide in corrispondenza degli identificatori di strike, quindi scarta ogni secondo risultato da ogni blocco (rimuovendo i punteggi di quelle tirature che non sono realmente iniziate con l'inizio di un frame).

Per soddisfare il fotogramma finale viene prima aggiunto uno zero all'input (per consentire la suddivisione in 3 parti per consentire a un fotogramma di iniziare su quello che era il penultimo riquadro) e i punteggi risultanti vengono troncati ai primi dieci (per rimuovere il now possibile falso 11 ° fotogramma) prima di riassumerli.

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

0

Perl, 140?

Primo tentativo:

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

Purtroppo, ci sono alcuni casi in cui fallisce. Verrò e lo rifarò più tardi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.