Erziele eine Partie Bowling

25

Ihre Aufgabe ist es, die Punktzahl eines Spielers in einem 10-Pin-Bowlingspiel nach bis zu 21 Würfeln zusammenzufassen und auszugeben .

Die Rollen werden in der von Ihnen bevorzugten Eingabemethode als eine Folge von ganzen Zahlen dargestellt . Jede Ganzzahl entspricht der Anzahl der Stifte, die in diesem Wurf niedergeschlagen wurden.

Wertung

Nach jeder Runde wird die Anzahl der in dieser Runde umgeworfenen Stifte in die Endwertung gezählt. Wenn ein Spieler im ersten Wurf einer Runde alle zehn Stifte abwirft, ist dies ein Schlag , und die Runde ist vorbei. Ansonsten dauert die Runde noch einen Wurf. Wenn der zweite Wurf einer Runde alle verbleibenden Stifte umwirft, ist dies ein Ersatz .

Für jeden Schlag gibt es einen Bonus , der der Summe der Stifte entspricht, die in den beiden nächsten Würfen niedergeschlagen wurden. Für jeden Ersatz gibt es einen Bonus, der der Anzahl der Stifte entspricht, die beim nächsten Wurf umgeworfen wurden.

In der zehnten und letzten Runde können dem Spieler zusätzliche Würfe gewährt werden: Im Falle eines Streiks erhält der Spieler zwei weitere Würfe, um seinen Streikbonus zu bilden. Im Falle eines Ersatzes erhält der Spieler einen weiteren Wurf.

Beispiele

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

Regeln

  • Sie können davon ausgehen, dass die Eingabe gültig ist.
  • Gemäß Megos Kommentar habe ich die Anforderungen an die Eingabe- / Ausgabemethoden gelockert, um unseren aktuellen Standard zu erfüllen .
  • Antworten in Sprachen, die neuer sind als die Herausforderung, sind zulässig
  • Kürzester Code gewinnt!
daniero
quelle
Erinnere ich mich richtig, dass Boni nicht gestapelt werden?
Titus
@Titus Ich weiß nicht genau, was Sie meinen, aber nein, Boni "stapeln" sich nicht, dh für einen Schlag addieren Sie die Anzahl der Stifte, die in den beiden nächsten Würfen umgestoßen werden , unabhängig davon, ob es sich um Streiks handelt oder nicht. Die maximale Punktzahl für einen Schlag beträgt 30 Punkte und die maximale Punktzahl für ein ganzes Spiel 300.
daniero
Qualifizieren sich unterschiedliche Befehlszeilenargumente als space separated integers?
Titus
1
@Titus sicher. Dies ist ein alter Beitrag - Der heutige Konsens über akzeptable Eingabemethoden wurde zu diesem Zeitpunkt nicht hergestellt. Eigentlich verstehe ich jetzt nicht, warum der heutige Standard (einschließlich der Funktionsparameter usw.) nicht darauf angewendet werden sollte, obwohl ich kein Fan davon bin, die Regeln der Herausforderung rückwirkend zu ändern.
Daniero
1
@daniero Der übliche Rat ist, dass es akzeptabel ist, die Regeln zu lockern, um sie an moderne Standards anzupassen, solange dies die Herausforderung nicht drastisch ändert.
Mego

Antworten:

6

GolfScript, 50 41 Zeichen

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

Ein weiterer Versuch in GolfScript ( online ausführen ).

Es folgt eine Erläuterung des Codes. Die Lösung nutzt die Stapel-Natur des Problems (verbrauchen Sie Rollen nacheinander), aber deshalb muss die Eingabe umgekehrt werden.

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

Vorherige Version:

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

Python, 116 110 105 103 100 99 Zeichen

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)

Die Eingabe von 30 Zeichen ist lästig. Vorschläge sind willkommen.

Vielen Dank an Howard für die Verbesserungen.

Steven Rumbalski
quelle
Sie können ersetzen 1+(z[i]!=10)mit 2-(z[i]>9)einem Zeichen zu speichern.
Howard
@ Howard: Ausgezeichneter Vorschlag. Ich habe es in meine Antwort aufgenommen. Es wurden zwei Zeichen gespeichert.
Steven Rumbalski
Und zwei weitere, wenn Sie ivollständig entfernen (auf 0 setzen) und stattdessen i+=...verwendenz=z[2-(z[0]>9)::];
Howard
@ Howard: Nochmals vielen Dank. Drei Zeichen gespeichert.
Steven Rumbalski
Die Standards für E / A sind jetzt im Allgemeinen flexibler, daher z=input()sollten sie in Ordnung sein (effektiv eine Zeichenfolgendarstellung einer Liste von ints nehmen und evalsie verwenden). Vollständige Programme sollten jedoch irgendwo ausgegeben werden (ich denke, das war damals auch so). Als solches glaube ich, dass dies in diesem 78-Byte-Programm
Jonathan Allan
4

R 101 Bytes

Ich bin mir nicht sicher, warum diese Herausforderung bewältigt wurde, aber ich mag sie, deshalb antworte ich sowieso zu spät.

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)

Probieren Sie es 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)
  }
}

Rekursive Funktion. Nimmt xals Eingabe, die die Scores enthält. Initialisiert die sKerne und czählt die Anzahl der geworfenen Runden.

Die if-Anweisung prüft, ob 10 Runden geworfen wurden oder ob xleer ist. In diesem Fall wird die Punktzahl zurückgegeben. Ansonsten ruft sich die Funktion wie folgt auf:

Es entfernt die Würfe x, indem es überprüft, ob es sich um einen Schlag handelt oder nicht. In diesem Fall wird der erste Eintrag entfernt, ansonsten die ersten beiden. (S=x[1]!=10)prüft auf Streiks. Wir entfernen ( -) index 0:S, wobei S1 ist, wenn es sich um einen Strike handelt, und 0, wenn nicht. Und dann fügen wir ein: -(0:(x[1]!=10)+1). Wir übergeben die verkürzten xzum nächsten Anruf.

Die Punktzahl wird ermittelt, indem man feststellt, x[1:2]ob es sich um eine reguläre Runde handelt und x[1:3]ob es sich um einen Streik oder eine Ersatzrunde handelt. Wir prüfen, ob sum(x[1:2])größer oder gleich 10 ist. Wenn es sich um einen Streik handelt, ist dies offensichtlich der Fall. Wenn es ein Ersatz ist, funktioniert dies auch. Wenn dies also WAHR ist, addieren wir x[3]die Summe. Dies wird dann hinzugefügt s.

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

BEARBEITEN : Ein heftiges Umschreiben, das Howards großartigen Stack-basierten Ansatz schamlos plagiiert. Ich bin zuversichtlich, dass mehr herausgenommen werden kann, um auf das letzte Element eines Arrays zuzugreifen, ohne es zu zerstören ...

Johno
quelle
1

Ruby, 252 Bytes

Akzeptiert Eingaben in ein Array, fügt man zuerst alle Elemente hinzu und sucht dann nach Ersatz- und Trefferbonus

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
AnfängerProg
quelle
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;

Nimmt Eingaben von Befehlszeilenargumenten entgegen. Laufen Sie mit -nroder testen Sie es online .

Nervenzusammenbruch

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

Jelly ,  36  35 Bytes

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

Ein monadischer Link, der eine Liste von Ganzzahlen akzeptiert und eine Ganzzahl zurückgibt.

Probieren Sie es online!

Wie?

Berechnet die Punktzahl für jeden überlappenden Lauf von drei Schalen so, als ob er am Anfang eines Frames begonnen hätte und fügt optional eine Strike-ID hinzu ( -1), glättet diese resultierende Liste, teilt sie an den Strike- IDs auf und verwirft dann jedes zweite Ergebnis von jeden Block (Entfernen der Punkte der Läufe, die nicht wirklich mit dem Start eines Frames begonnen haben).

Um dem letzten Frame gerecht zu werden, wird zuerst eine Null an die Eingabe angehängt (um das dreiteilige Schneiden zu ermöglichen, damit ein Frame auf der vorletzten Schüssel beginnen kann), und die resultierenden Scores werden auf die ersten zehn gekürzt (um das Jetzt zu entfernen) möglichen falschen 11. Frame), bevor Sie sie aufsummieren.

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

Perl, 140?

Erster Versuch:

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

Leider gibt es bestimmte Fälle, in denen dies fehlschlägt. Ich werde später kommen und es wiederholen.

o_o
quelle