Bowling-Punktzahl mit zehn Stiften - World Bowling Edition

20

World Bowling Wertung

Viele Leute sind zu ihrem örtlichen Bowlingzentrum gegangen, um ein paar Bowlingspiele zu spielen, und viele kämpfen weiterhin darum, ihre Punktzahlen zu berechnen. World Bowling hat ein vereinfachtes Punktesystem eingeführt, um mehr Menschen für den Sport zu begeistern. Dieses Punktesystem wird in internationalen Spielen verwendet.

Das Punktesystem funktioniert wie folgt (aus Wikipedia ):

Das World Bowling Scoring-System, das als "Current Frame Scoring" [32] bezeichnet wird, vergibt die Pins folgendermaßen:

  • Streik: 30 (unabhängig von den Ergebnissen der folgenden Würfe)
  • spare: 10 plus pinfall beim ersten würfeln des aktuellen bildes
  • open: Gesamt-Pinfall für den aktuellen Frame

Wenn Sie mit Bowling nicht vertraut sind, finden Sie hier eine Zusammenfassung.

Am Ende einer Bowlingbahn befinden sich 10 Kegel, mit denen alle mit einer Bowlingkugel niedergeschlagen werden sollen. Sie erhalten 2 Wurfbälle, um zu versuchen, sie alle niederzuschlagen, vorzugsweise mit dem ersten Wurf (bekannt als Schlag ). Wenn Sie einen Treffer erzielen, ist dieser Frame abgeschlossen und Sie müssen den Ball nicht ein zweites Mal rollen. Ein Streik ist 30 wert.

Wenn Sie nicht alle zehn umwerfen, erhalten Sie eine weitere Rolle. Wenn Sie alle verbleibenden Stifte umwerfen, spricht man von einem Ersatz . Die Punktzahl ist 10 Pins + die Anzahl der Pins, die beim ersten Wurf abgeworfen wurden. Wenn ich zum Beispiel 7 Pins umgestoßen und dann die restlichen 3 Pins umgestoßen hätte, wäre das 17 wert.

Wenn Sie nach Ihrem zweiten Wurf nicht alle zehn besiegen, spricht man von einem offenen Frame . Die Punktzahl ist die Gesamtzahl der Stifte wert, die für diesen Frame abgeworfen wurden.

Ein Spiel besteht aus 10 Bildern . Wenn Sie mit dem traditionellen Bowling-Scoring vertraut sind, erhalten Sie im 10. Frame beim World Bowling Scoring keine Extrarolle. Bei der traditionellen Bowling-Wertung sind 12 aufeinanderfolgende Schläge erforderlich, um eine perfekte Punktzahl von 300 zu erzielen, während bei der World Bowling-Wertung nur 10 aufeinanderfolgende Schläge erforderlich sind.

Herausforderung

Ihre Herausforderung besteht darin, die Punktzahl anhand eines Bewertungsbogens zu berechnen.

Auf einem Punkteblatt wird ein Fehler durch einen Strich ( - ), einen Schlag mit einem X und einen Ersatz mit einem Schrägstrich ( / ) angezeigt . Wenn diese nicht zutreffen, wird die Pinfall-Anzahl einfach mit einer Zahl (1-9) angegeben. Fouls und Splits werden ebenfalls auf den Spielberichten aufgezeichnet, aber Sie müssen sich nicht darum kümmern.

Eingang

Sie erhalten eine Zeichenfolge, die aus Punktzahlen für jedes Bild besteht und insgesamt zehn Bilder enthält. Jeder Frame hat bis zu zwei Werte oder nur 1 Wert, wenn ein Strike aufgetreten ist. Ihre Eingabe kann ein Zeichenfolgenparameter für eine Funktion sein, der aus einer Datei oder aus STDIN gelesen wird.

Wenn ich zum Beispiel bei meinem ersten Wurf 1 Nadel und dann 2 umgestoßen hätte, würde der Rahmen wie "12" aussehen. Dies bedeutet nicht 12 (zwölf), sondern 1 und 2 für insgesamt 3.

Wenn ich jeden Stift mit beiden Rollen (Rinnenkugeln) verpasst hätte, würde es so aussehen "-" (Punktzahl 0).

Jeder Frame wird durch ein Leerzeichen getrennt.

Probeneingabe

-- 9- -9 X -/ 8/ 71 15 44 X

Um dieses Beispiel aufzuschlüsseln,

  • Frame 1 (-) - beide Rollen sind verpasst. erzielte 0
  • Frame 2 (9-) - 9 auf der ersten Rolle niedergeschlagen, auf der zweiten Rolle verfehlt. Punktzahl 9
  • Frame 3 (-9) - Verpasste alles beim ersten, bekam 9 beim zweiten. Punktzahl 9
  • Frame 4 (X) - Strike, alle zehn niedergeschlagen. Ergebnis 30
  • Frame 5 (- /) - Spare, verpasste alles beim ersten, warf alles mit dem zweiten Wurf nieder. Ergebnis 10 + 0 = 10
  • Frame 6 (8 /) - Spare, 8 Stifte auf der ersten Rolle, die anderen 2 mit der zweiten Rolle niedergeschlagen. Ergebnis 10 + 8 = 18
  • Rahmen 7 (71) - offener Rahmen, 7 Stifte auf der ersten Rolle, 1 Stift auf der zweiten Rolle. Ergebnis 7 + 1 = 8
  • Die Rahmen 8, 9, 10 folgen denselben Beispielen wie oben.

Ausgabe

Die Ausgabe ist einfach ein Wert, der die Summe der Ergebnisse aller 10 Frames enthält. Bei Verwendung der Beispieleingabe ist die Ausgabe 128. Bei Ihrer Ausgabe kann es sich um eine Zeichenfolge oder einen numerischen Typ handeln. Dies kann ein Funktionsrückgabewert sein oder in STDOUT geschrieben werden.

Regeln

  • Angenommen, die Eingabe ist immer gültig. Ein ungültiger Frame wäre beispielsweise "/ 8", "XX", "123", "0" usw.
  • Sie müssen sich keine Gedanken über Splits oder Fouls machen.
  • Ihr Code kann ein vollständiges Programm oder eine Funktion sein, die eine Zeichenfolge aufnimmt und die Punktzahl zurückgibt.
  • Ihr Code darf keine Ausnahmen auslösen.
  • Dies ist Codegolf, die Antwort mit der geringsten Anzahl von Bytes gewinnt.
  • Sprachen, die Includes oder Importe verwenden, müssen die Importanweisungen als Teil ihres Codes enthalten und auf die Byteanzahl angerechnet werden.

Testfälle

"-- 9- -9 X -/ 8/ 71 15 44 X" -> 128
"-- -1 2- 12 22 5- 42 61 8- 72" -> 45
"X X X 1/ 2/ 3/ 4/ 5/ -- 9/" -> 174
"X X X X X X X X X X" -> 300
"-- -- -- -- -- -- -- -- -- --" -> 0
Makotosan
quelle
21
Ich bin enttäuscht, dass dies keine Code-Bowling-Herausforderung ist
Jo King
13
Ihr erstes Ersatzbeispiel besagt, dass die Punktzahl 13 betragen würde, aber ich denke, es soll 17 sein.
Jo.
@Jo. Guter Fang. Ich habe die Frage aktualisiert, um diesen Fehler zu beheben.
Makotosan
@JoKing Ich dachte, dies ist eine Code-Bowling-Herausforderung, die aus 10 Teilherausforderungen besteht, als ich den Titel zum ersten Mal sah.
Weijun Zhou
1
Eine der am besten dokumentierten und schriftlichen Herausforderungen, die ich gesehen habe.
Joshua

Antworten:

7

05AB1E , 12 11 Bytes

Code

S'/T:'X30:O

Probieren Sie es online!

Erläuterung

S             # Split the string into a list of characters
 '/T:         # Replace '/' with 10
     'X30:    # Replace 'X' with 30
          O   # Sum up the array (ignoring non-number elements)
Adnan
quelle
7

JavaScript, 43 Bytes

f=([c,...s])=>c?({'/':10,X:30}[c]|c)+f(s):0

Wie es funktioniert

Wir konvertieren jedes Zeichen auf seinen Punkt:

  • 'X' ist 30 Punkte wert
  • '/' 10 Punkte wert
  • '1' .. '9' ist 1 .. 9 Punkte wert
  • andere Charaktere im Wert von 0 Punkt

Dann summiere alle Punkte.

Konvertieren

Der bitweise ODER- Operator |konvertiert seinen Operanden vor der Operation in Int32. Bei der Konvertierung in Int32 wird der Wert zuerst in das 64-Bit-Gleitkommazahlenformat (Number) konvertiert und anschließend in Int32 umgeleitet (oder bei Ungültigkeit in 0 konvertiert).

  • ToInt32({'/':10,X:30}[c]) könnte gelesen werden als:
    • wenn c == '/': Ergebnis ist 10;
    • wenn c == 'X': Ergebnis ist 30;
    • sonst: Ergebnis ist ToInt32(undefined)-> ToInt32(NaN)-> 0;
  • ToInt32(c) könnte sein:
    • wenn c == '1' ... '9': Ergebnis ist 1 .. 9;
    • wenn c == '': Number(c)0 ist, ist das Ergebnis 0;
    • Andernfalls Number(c)lautet das NaNErgebnis 0.
  • Bitweise oder hier ist dasselbe wie "add", da einer seiner Operanden 0 ist

Summe

  • [c,...s] = slassen c = s[0], und s = s.slice(1);
    • Wenn s eine leere Zeichenfolge ist, ist c undefiniert .
    • ansonsten ist c der erste Buchstabe von s
  • undefined ist falsch, nicht leere Zeichenkette (einschließlich Leerzeichen) ist wahr
tsh
quelle
1
Können Sie Ihren Code erklären? sieht wirklich gut aus
Luis Felipe De Jesus Munoz
@ LuisfelipeDejesusMunoz Gerade hinzugefügt.
Dienstag,
5

Stax , 13 Bytes

─*âⁿ┴8òt↨HÉ÷8

Führen Sie es aus und debuggen Sie es

Ausgepackt, ungolfed und kommentiert ist es so.

F               for each character in input, execute...
 9R$'/20*+'X+   build the string "123456789////////////////////X"
 I              get the index of the current character in string
 ^+             increment and add to running total
                (index is -1 when no match; space and dash are 0 score)

Führen Sie dieses aus

rekursiv
quelle
3

Python 2 , 55 Bytes

lambda l:sum(map(('123456789/'+'X'*20).rfind,l))+len(l)

Probieren Sie es online!

Basierend auf dem String-Index-Ansatz vieler Lösungen.

xnor
quelle
3

Java 8, 64 59 46 Bytes

s->s.map(c->c<46?0:c<48?10:c>87?30:c-48).sum()

-5 Bytes dank @Neil .
-13 Bytes dank @ OlivierGrégoire .

Erläuterung:

Probieren Sie es online aus.

s->               // Method with an IntStream parameter and integer return-type
  s.map(c->       //  Loop over the characters
          c<46?   //   If the character is a space or '-':
           0      //    Count it as 0
          :c<48?  //   Else-if it's a '/':
           10     //    Count it as 10
          :c>87?  //   Else-if it's an 'X':
           30     //    Count it as 30
          :       //   Else (it's a digit):
           c-48   //    Count it as the value of the digit
       ).sum()    //   And sum everything
Kevin Cruijssen
quelle
1
("123456789//"+1e6+1e6+"X")scheint 5 Bytes zu sparen.
Neil
Das ist eine clevere Technik, um eine Füllzeichenfolge zu erstellen.
Makotosan
1
46 Bytes
Olivier Grégoire
3

F #, 106 103 Bytes

let s c=Seq.sumBy(fun x->if x=' '||x='-'then 0 elif x='X'then 30 elif x='/'then 10 else int(string x))c

Probieren Sie es online!

Ich denke, dass dieses Rätsel (ohne das Golfen) eine großartige Frage für einen Leitfaden "Funktionale Programmierung für Anfänger" wäre. Und ich sollte es wissen!

-3 von Kevin Cruijssen, um festzustellen, dass das Leerzeichen zwischen 'und "dann" gelöscht werden kann. Vielen Dank!

Die Stax-Lösung von recursive für die Verwendung von String-Indizes ist sehr, sehr gut. Wenn Sie es auf F # portieren, können Sie es für 77 Bytes erhalten :

let s c=Seq.sumBy(fun x->"123456789/???????????????????X".IndexOf(char x)+1)c

Versuchen Sie dies online!

Ciaran_McCarthy
quelle
1
Ich kenne F # nicht sehr gut, aber es scheint, dass Sie die Leerzeichen danach 'für -3 Bytes löschen können.
Kevin Cruijssen
Ich auch nicht! Aber du hast recht, gut gesehen! Vielen Dank!
Ciaran_McCarthy
2
@Ciaran_McCarthy: Es macht mir nichts aus, wenn Sie meine Lösung kopieren, wenn Sie sie auch einschließen möchten. Die Leute hier sind im Allgemeinen ziemlich offen für solche Dinge. Es ist eine kooperative Anstrengung, den kleinsten Code zu finden, auch wenn es sich formal um einen Wettbewerb handelt.
rekursiven
1
Danke rekursiv. Ich werde es dann einbeziehen, weil es eine sehr schöne Lösung ist und es interessant ist zu sehen, wie es in verschiedenen Sprachen aussieht.
Ciaran_McCarthy
2

Gelee , 17 Bytes

ḟ⁾ -“X0/⁵”yV€o30S

Eine monadische Verknüpfung, die eine Liste von Zeichen akzeptiert und eine Ganzzahl zurückgibt

Probieren Sie es online!

Wie?

ḟ⁾ -“X0/⁵”yV€o30S - Link: list of characters
 ⁾ -              - literal list of characters [' ','-']
ḟ                 - filter discard
    “X0/⁵”        - literal list of characters ['X','0','/','⁵']
          y       - translate (change 'X's to '0's and '/'s to '⁵'s)
           V€     - evaluate €ach character as Jelly code (the '⁵'s become 10s)
             o30  - logical OR with 30 (change all instances of 0 to 30)
                S - sum

Ebenfalls mit 17:

”/ẋ20ØD;;”XḊiЀ⁸S

Versuch das

Jonathan Allan
quelle
2

Retina , 17 Bytes

X
///
/
55
\d
*
_

Probieren Sie es online!

Ich bin nicht ganz auf dem neuesten Stand der Retina-Änderungen. Ich werde sie mir genauer ansehen, wenn ich die Gelegenheit dazu bekomme und herausfinde, ob es neue Tricks gibt, wie man so etwas runtergolfen kann. Der Code verwandelt alle Strikes in drei Ersatzteile, alle Ersatzteile in zehn Punkte und alle Punkte in die entsprechende Anzahl von Unterstrichen. Dann wird die Anzahl der Unterstriche gezählt.

PunPun1000
quelle
2

Perl 5 -pF , 30 27 Bytes

-3 Bytes dank Xcali

#!/usr/bin/perl -pF
$\+=m%/%+3*/X/.0+$_ for@F}{

Probieren Sie es online!

Tonne Hospel
quelle
Sie können zwei Bytes durch Verwenden von /X/anstelle von y/X//und eines durch Verwenden von m%/%anstelle von schneiden y%/%%: Probieren Sie es online aus!
Xcali
@Xcali Ah, natürlich. Klassische Golf-Kurzsichtigkeit, dachte ich immer noch darüber nach, y///wann ich sie außerhalb einer Schleife gemacht habe. Thanks
Ton Hospel
1

05AB1E , 14 Bytes

þ`I…/aXS¢ƶT*`O

Probieren Sie es online!

Erläuterung

þ`              # Push the digits of the input on the stack (removes everyting that isn't a digit)
  I…/aXS        # Push the input and the array "/","a","X" on the stack
        ¢       # Index of each element in the input ...
         ƶT*    # ... multiplied by its index (a could be anything that can't be found in the input), multiplied by 10.
            `O  # Sum the stack, implicit display
Kaldo
quelle
1

J , 33 Bytes

1#.31|('-123456789',20 1#'/X')i.]

Probieren Sie es online!

Erläuterung:

] die Eingabe

('-123456789',20 1#'/X')hängt 20 /und eins Xan die Zeichenkette an-123456789

i. Findet die Indizes der Eingabe in der obigen Zeichenfolge

31|Modulo 31 - um die Leerzeichen loszuwerden - werden sie nicht in der Zeichenkette gefunden, also i.gibt es 31 für sie zurück

1#. Findet die Summe der Indizes

Galen Ivanov
quelle
Da J und Rot zwei völlig unterschiedliche Sprachen sind, ist es besser, zwei getrennte Antworten zu posten, auch wenn sie möglicherweise dasselbe tun. Sie können dieser J-Antwort einen Link aus der roten Antwort hinzufügen, der angibt, dass dies ein Port Ihrer J-Antwort ist.
Kevin Cruijssen
@ Kevin Cruijssen - Ok, danke - ich werde es tun. Der Grund für die Veröffentlichung ist, dass die rote Lösung offensichtlich nicht wettbewerbsfähig ist (obwohl gut lesbar :))
Galen Ivanov
1

Python 2 , 67 Bytes

-3 Bytes dank @KevinCruijssen

lambda I,p='-123456789/'+20*'X':sum(p.rfind(i)for i in I if i in p)

Probieren Sie es online!

Totes Opossum
quelle
1
Sie können 3 Bytes sparen, indem Sie '-123456789'+'/'*20+'X':sum(p.index(i)zu'-123456789/'+'X'*20:sum(p.rfind(i)
Kevin Cruijssen
@ KevinCruijssen danke, gute!
Dead Possum
1

Gelee , 12 Bytes

⁾/X,“½œ‘y|0S

Probieren Sie es online!

Wie es funktioniert

⁾/X,“½œ‘y|0S  Main link. Argument: s (string)

⁾/X,“½œ‘      Literal; yield [['/', 'X'], [10, 30]].
        y     Transliterate; replace '/' with 10, 'X' with 30.
         |0   Bitwise OR with 0. Bitwise operators attempt to cast to int, mapping 
              '0', ..., '9' to 0, ..., 9. All other characters map to 0.
           S  Take the sum.
Dennis
quelle
1

Kotlin , 50 Bytes

x->x.sumBy{"123456789/_${Math.E}_X".indexOf(it)+1}

Probieren Sie es online!

Hoffentlich verstößt es nicht gegen die Regeln, deine eigene Frage zu beantworten, aber ich wollte mich an dem Spaß beteiligen.

Math.Eerzeugt den Wert 2.718281828459045. Ich benutze es, um eine Füllzeichenfolge zu erstellen, um X auf Position 30 zu drücken.

indexOfRuft die Position (0-basiert) des Zeichens in der Zeichenfolge "12345 ..." ab. Wenn es nicht gefunden wird, gibt es -1 zurück. Wir addieren 1, um diese 0 zu machen, und das macht auch die 0-basierte Position zum Wert des Strings.

Makotosan
quelle
1

PHP, 119 109 Bytes

-10 Bytes dank @KevinCruijssen

<?foreach(explode(" ",$argv[1])as$f){[$a,$b]=str_split($f);$n+=$f==X?30:(int)$a+($b=='/'?10:(int)$b);}echo$n;

Probieren Sie es online!

Jo.
quelle
Sie können ändern , ($b=='/'?10+(int)$a:((int)$a+(int)$b))um (int)$a+($b=='/'?10:(int)$b)für -10 Bytes.
Kevin Cruijssen
@ KevinCruijssen Danke, sieht gut aus! Wenn ich mir die anderen Antworten ansehe, sieht es so aus, als würde ich das falsch machen. :)
Jo.
0

Holzkohle , 23 Bytes

IΣEχΣES⎇№-/Xλ×χ⌕-//XλIλ

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

  Eχ                    Map over 10 frames
      S                 Input the frame
     E                  Map over the characters
            λ           Current character
        №-/X            Search the literal string `-/X`
                    λ   Current character
               ⌕-//X    Find position in literal string `-//X`
             ×χ         Multiply by predefined variable 10
                      λ Current character
                     I  Cast to integer
       ⎇                Ternary
    Σ                   Sum for each frame
 Σ                      Sum over frames
I                       Cast to string for implicit print
Neil
quelle
0

SNOBOL4 (CSNOBOL4) , 169 151 147 Bytes

	F =INPUT ' '
R	F '-' =0	:S(R)
T	F 'X' ='_'	:S(T)
S	F LEN(1) . X ARB . Y ' ' REM . F	:F(O)
	X '_' =30
	Y '/' =10
	S =S + X + Y	:(S)
O	OUTPUT =S
END

Probieren Sie es online!

	F =INPUT ' '					;* read input and append a space
R	F '-' =0	:S(R)				;* replace - with 0
T	F 'X' ='_'	:S(T)				;* replace X with _
S	F LEN(1) . X ARB . Y ' ' REM . F	:F(O)	;* set first character to x, remainder up to ' ' to y, and remainder to F
	X '_' =20					;* replace _ in x with 20
	Y '/' =10					;* replace / in y with 10
	S =S + X + Y	:(S)				;* else X and Y are their values so we can sum them
O	OUTPUT =S					;* output the sum
END
Giuseppe
quelle
0

Clojure , 70 Bytes

#(reduce(fn[s i](+ s(case i\- 0\/ 10\X 30\space 0(bigint(str i)))))0%)

Probieren Sie es online!

Wenn man reduceüber einen String geht, wird jedes Zeichen in ein Zeichen umgewandelt - wer hätte das gedacht. Aber das meine ich, ich muss schreiben \spaceund das tut mehr weh, als man sich vorstellen kann. Beim Erstellen einer tatsächlichen Zahl aus einem Zeichen wird auch die Kombination von bigintund verwendetstr scheint die einzig verwendbare Kombination zu sein.

Nun, abgesehen von all diesen Kämpfen: Anonyme Funktion, die die Punktzahl als eine natürliche zurückgibt.

Joshua
quelle