Strzel grę w kręgle

25

Twoim zadaniem jest zsumowanie i wyprowadzenie wyniku jednego gracza w grze w kręgle z 10 pinami po maksymalnie 21 rzutach .

Rolki są reprezentowane jako sekwencja liczb całkowitych w preferowanej metodzie wprowadzania . Każda liczba całkowita odpowiada liczbie wyrzuconych szpilek w tym rzucie.

Punktacja

Po każdej rundzie liczba szpilek powalonych w tej rundzie jest liczona do końcowego wyniku. Jeśli gracz przewróci wszystkie dziesięć szpilek w pierwszym rzucie rundy, jest to uderzenie i runda się kończy. W przeciwnym razie runda trwa jeszcze jeden rzut. Jeśli drugi rzut rundy powali wszystkie pozostałe szpilki, jest to zapasowy .

Za każde uderzenie przysługuje premia równa sumie szpilek powalonych w dwóch kolejnych rzutach. Za każdą część zapasową przysługuje premia równa liczbie szpilek powalonych w następnym rzucie.

W 10. i ostatniej rundzie gracz może otrzymać dodatkowe rzuty: w przypadku strajku gracz otrzymuje dwa kolejne rzuty w celu uzupełnienia premii za uderzenie. W przypadku rezerwy gracz otrzymuje jeszcze jeden rzut.

Przykłady

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

Zasady

  • Możesz założyć, że dane wejściowe są prawidłowe.
  • Zgodnie z komentarzem Mego poluzowałem wymagania dotyczące metod wejścia / wyjścia, aby spełnić nasz obecny standard .
  • Dozwolone są odpowiedzi w językach nowszych niż wyzwanie
  • Najkrótszy kod wygrywa!
daniero
źródło
Czy dobrze pamiętam, że bonusy się nie kumulują?
Tytus
@Titus Nie jestem do końca pewien, co masz na myśli, ale nie, bonusy nie „kumulują się”, tzn. Do strajku dodajesz liczbę szpilek, które są powalone w dwóch kolejnych rzutach , niezależnie od tego, czy są uderzeniami albo nie. Tak więc maksymalny wynik za jedno uderzenie to 30 punktów, a maksymalny za całą grę to 300.
daniero
Czy różne argumenty wiersza poleceń kwalifikują się jako space separated integers?
Tytus
1
@Titus na pewno. To jest stary post - dzisiejszy konsensus w sprawie dopuszczalnych metod wprowadzania danych nie został w tym momencie ustalony. Właściwie nie rozumiem teraz, dlaczego dzisiejszy standard nie powinien się do tego stosować (w tym parametry funkcji itp.), Chociaż nie jestem fanem zmieniania reguł wyzwania z mocą wsteczną.
daniero
1
@daniero Zwykle radzi się, aby rozluźnić zasady w celu dostosowania do współczesnych standardów, o ile nie zmieni to drastycznie wyzwania.
Mego

Odpowiedzi:

6

GolfScript, 50 41 znaków

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

Kolejna próba w GolfScript ( uruchom go online ).

Poniżej wyjaśniono kod. Rozwiązanie wykorzystuje naturę problemu stosu (konsumuje rolki jeden po drugim), ale w związku z tym dane wejściowe należy odwrócić.

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

Poprzednia wersja:

~].1>.1>]zip{((.10<{@(0=@+@1>1$9><}*@}10*;]{+}.@**
Howard
źródło
5

Python, 116 110 105 103 100 99 znaków

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)

Wydawanie 30 znaków na wejściu jest uciążliwe. Sugestie mile widziane.

Ogromne podziękowania dla Howarda za ulepszenia.

Steven Rumbalski
źródło
Można wymienić 1+(z[i]!=10)z 2-(z[i]>9)uratować jeden char.
Howard,
@ Howard: Doskonała sugestia. Włączyłem to do mojej odpowiedzi. Uratował dwie postacie.
Steven Rumbalski,
I jeszcze dwa, jeśli icałkowicie usuniesz (ustaw na 0) i zamiast tego i+=...użyjeszz=z[2-(z[0]>9)::];
Howard,
@Howard: Jeszcze raz dziękuję. Zapisano trzy postacie.
Steven Rumbalski,
Standardy we / wy są teraz na ogół bardziej elastyczne, więc z=input()powinny być w porządku (efektywnie biorąc ciąg znaków reprezentujący listę ints i wprowadzając evalją). Jednak gdzieś powinny wypisywać się pełne programy (myślę, że wtedy też tak było). Jako taki, wierzę, że można to zmienić na 78-bajtowy program
Jonathan Allan
4

R, 101 bajtów

Nie jestem pewien, dlaczego to wyzwanie zostało zderzone, ale podoba mi się, więc i tak spóźnię się z odpowiedzią.

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)

Wypróbuj online!

Nie golfowany:

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

Funkcja rekurencyjna. Pobiera xjako dane wejściowe, które przechowuje wyniki. Inicjuje srdzenie i czlicza liczbę wyrzuconych rund.

Instrukcja if sprawdza, czy wyrzucono 10 rund lub czy xjest pusta. W takim przypadku wynik jest zwracany. W przeciwnym razie funkcja wywoła się w następujący sposób:

Usuwa rzuty x, sprawdzając, czy to strajk, czy nie. Jeśli tak, pierwszy wpis jest usuwany, w przeciwnym razie dwa pierwsze. (S=x[1]!=10)sprawdza strajki. Usuwamy -indeks ( ) 0:S, gdzie Swynosi 1, jeśli jest to ostrzeżenie, a 0, jeśli nie. A następnie dodajemy jeden: -(0:(x[1]!=10)+1). Skrócone przekazujemy xdo następnego połączenia.

Jeśli chodzi o wynik, można to stwierdzić, biorąc pod uwagę, x[1:2]czy jest to zwykła tura i x[1:3]czy jest to strajk czy zapasowy. Sprawdzamy, czy sum(x[1:2])jest większy czy równy 10. Jeśli jest to strajk, oczywiście tak jest. Jeśli jest to zapasowe, to również działa. Więc jeśli jest to PRAWDA, dodajemy x[3]do sumy. To jest następnie dodawane do s.

JAD
źródło
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

EDYCJA : Mocne przepisywanie, bezwstydnie plagiatujące podejście Howarda oparte na stosie. Jestem pewien, że można uzyskać więcej, aby uzyskać dostęp do ostatniego elementu tablicy bez niszczenia go ...

Johno
źródło
1

Rubinowy, 252 bajtów

Akceptuje dane wejściowe do tablicy, najpierw dodaj wszystkie elementy, a następnie wyszukuje zapasową i uderzającą premię

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
początkujący
źródło
1

PHP, 82 bajty

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

pobiera dane wejściowe z argumentów wiersza poleceń; Biegnij z-nr lub przetestuj online .

awaria

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
Tytus
źródło
1

Galaretka ,  36  35 bajtów

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

Łącze monadyczne przyjmujące listę liczb całkowitych i zwracające liczbę całkowitą.

Wypróbuj online!

W jaki sposób?

Oblicza wynik każdego nakładającego się przebiegu trzech misek, tak jakby był to ten, który zaczął się na początku ramki i opcjonalnie dołącza identyfikator uderzenia (-1 ), spłaszcza tę wynikową listę, dzieli ją na identyfikatory uderzenia, a następnie odrzuca co drugi wynik z każda porcja (usuwanie wyników tych przebiegów, które tak naprawdę nie zaczęły się od początku ramki).

Aby zaspokoić ostateczną klatkę, najpierw do wejścia dołączane jest zero (aby umożliwić 3-mądre krojenie, aby umożliwić ramie rozpoczęcie od tego, co było przedostatnią misą), a wynikowe wyniki są obcinane do pierwszej dziesiątki (aby usunąć teraz możliwa fałszywa 11. rama) przed ich zsumowaniem.

+\µ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
źródło
0

Perl, 140?

Pierwsze podejscie:

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

Niestety w niektórych przypadkach zawodzi. Przyjdę i powtórzę to później.

o_o
źródło