Wynik kręgli z 10 pinów - edycja World Bowling

20

Punktacja World Bowling

Wiele osób poszło do lokalnego centrum gry w kręgle, aby zagrać w kilka gier w kręgle, a wiele osób nadal próbuje wyliczyć swoje wyniki. World Bowling wprowadził uproszczony system punktacji, aby przyciągnąć więcej osób do sportu. Ten system punktacji jest wykorzystywany w grach międzynarodowych.

System punktacji działa w następujący sposób (z Wikipedii ):

System punktacji World Bowling - opisany jako „bieżąca punktacja klatek” [32] - przyjmuje następujące piny:

  • strajk: 30 (niezależnie od wyników rzutów)
  • spare: 10 plus pinfall przy pierwszym rzucie bieżącej ramy
  • open: całkowity pinfall dla bieżącej ramki

Jeśli nie jesteś zaznajomiony z kręgielnią na 10 pinów, oto podsumowanie.

Na końcu toru do gry w kręgle znajduje się 10 kręgli, których celem jest powalenie ich wszystkich kulą do kręgli. Dostajesz 2 rzuty piłki, aby spróbować powalić je wszystkie, najlepiej powalić je wszystkie pierwszym rzutem (znanym jako uderzenie ). Jeśli dostaniesz ostrzeżenie, ta rama jest zakończona i nie musisz ponownie rzucać piłką. Strajk jest wart 30.

Jeśli nie powalisz wszystkich dziesięciu, otrzymasz jeszcze jeden rzut. Jeśli powalisz wszystkie pozostałe szpilki, jest to znane jako zapasowe . Wynik jest wart 10 pinów + liczba pinów powalonych podczas pierwszego rzutu. Na przykład, jeśli powaliłem 7 szpilek, a następnie udało mi się powalić pozostałe 3, byłoby to warte 17.

Jeśli po drugim rzucie nie uda Ci się powalić wszystkich dziesięciu, nazywa się to otwartą ramą . Wynik jest wart całkowitej liczby wyrzuconych szpilek dla tej ramki.

Gra zawiera 10 klatek . Jeśli jesteś zaznajomiony z tradycyjną punktacją w kręgle, nie uzyskasz dodatkowego rzutu w 10. klatce dzięki World Bowling Scoring. W tradycyjnych punktach do gry w kręgle potrzeba 12 kolejnych uderzeń, aby uzyskać doskonały wynik 300, podczas gdy punktacja w World Bowling wymaga tylko 10 kolejnych uderzeń.

Wyzwanie

Twoim wyzwaniem jest obliczenie podanych wartości z arkusza wyników.

Na karcie wyników chybienie jest oznaczone kreską ( - ), uderzeniem za pomocą X i rezerwowym ukośnikiem ( / ). Jeśli nie mają zastosowania, liczba pinfall jest po prostu oznaczana liczbą (1-9). Faule i podziały są również zapisywane na kartach wyników, ale nie musisz się o to martwić.

Wkład

Otrzymasz ciąg znaków składający się z wyników dla każdej klatki i będziesz miał w sumie dziesięć klatek. Każda ramka będzie miała maksymalnie dwie wartości lub 1 wartość, jeśli wystąpi ostrzeżenie. Dane wejściowe mogą być ciągiem parametrów funkcji, odczytanym z pliku lub ze STDIN.

Na przykład, jeśli przewróciłem 1 kołek przy pierwszym rzucie, a następnie przewróciłem 2, ramka wyglądałaby jak „12”. Nie oznacza to 12 (dwanaście), ale oznacza 1 i 2, w sumie 3.

Gdybym nie trafił w każdy kołek przy obu rolkach (kule rynnowe), wyglądałoby to tak: „-” (wynik 0).

Każda ramka będzie oddzielona spacją.

Przykładowe dane wejściowe

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

Aby rozbić ten przykład,

  • Ramka 1 (-) - brak dwóch rzutów. zdobył 0
  • Frame 2 (9-) - powalony na 9 przy pierwszym rzucie, pominięty przy drugim rzucie. Ocena 9
  • Ramka 3 (-9) - Nieodebrane wszystkie za pierwszym razem, otrzymałem 9 za drugim. Ocena 9
  • Ramka 4 (X) - Uderzenie, powalenie wszystkich dziesięciu. Ocena 30
  • Ramka 5 (- /) - Zapasowa, spudłowała za pierwszym razem, powalona za wszystko przy drugim rzucie. Ocena 10 + 0 = 10
  • Ramka 6 (8 /) - Zapasowa, 8 szpilek na pierwszym rolce, powalona na pozostałe 2 za pomocą drugiej rolki. Ocena 10 + 8 = 18
  • Rama 7 (71) - otwarta rama, 7 pinów na pierwszym rolce, 1 pin na drugim rolce. Wynik 7 + 1 = 8
  • Ramki 8,9,10 przedstawiają te same przykłady, co powyżej.

Wydajność

Wynik będzie po prostu wartością, która ma sumę wyników ze wszystkich 10 klatek. Przy użyciu przykładowego wejścia wynik będzie wynosił 128. Wynik może być ciągiem lub typem liczbowym. Może to być wartość zwracana przez funkcję lub zapisana w STDOUT.

Zasady

  • Załóż, że dane wejściowe zawsze będą prawidłowe. Na przykład niepoprawna ramka to „/ 8”, „XX”, „123”, „0” itd.
  • Nie musisz się martwić rozłamami lub faulami.
  • Kod może być pełnym programem lub funkcją, która pobiera ciąg znaków i zwraca wynik.
  • Twój kod nie może zgłaszać żadnych wyjątków.
  • To jest golf golfowy, odpowiedź z najmniejszą liczbą bajtów wygrywa.
  • Języki, które używają obejmują lub importują, muszą zawierać instrukcje importu jako część kodu i liczyć się do liczby bajtów.

Przypadki testowe

"-- 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
źródło
21
Jestem rozczarowany, że nie jest to wyzwanie
Jo King
13
Twój pierwszy przykład podaje, że wynik to 13, ale myślę, że powinien to być 17.
Jo.
@Jo. Dobry chwyt Zaktualizowałem pytanie, aby naprawić ten błąd.
Makotosan
@JoKing Myślałem, że to wyzwanie polegające na tworzeniu kręgli, składające się z 10 wyzwań, kiedy pierwszy raz zobaczyłem tytuł.
Weijun Zhou
1
Jedno z najlepiej udokumentowanych i napisanych wyzwań, jakie widziałem.
Joshua

Odpowiedzi:

7

05AB1E , 12 11 bajtów

Kod

S'/T:'X30:O

Wypróbuj online!

Wyjaśnienie

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

JavaScript, 43 bajty

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

Jak to działa

Konwertujemy każdą postać na jej punkt:

  • „X” wart 30 punktów
  • „/” o wartości 10 punktów
  • „1” .. „9” o wartości 1… 9 punktów
  • inne postacie warte 0 punktów

Następnie zsumuj wszystkie punkty.

Konwertować

Bitowy operator LUB| konwertuje swój operand na Int32 przed wykonaniem operacji. Podczas konwersji na Int32 wartość najpierw konwertuje na format Number (liczba zmiennoprzecinkowa 64-bitowa), a następnie trunk do Int32 (lub konwertuje na 0, jeśli jest niepoprawna).

  • ToInt32({'/':10,X:30}[c]) może być odczytany jako:
    • jeśli c == '/': wynik wynosi 10;
    • jeśli c == „X”: wynik to 30;
    • w przeciwnym razie: wynikiem jest ToInt32(undefined)-> ToInt32(NaN)-> 0;
  • ToInt32(c) możliwe:
    • jeśli c == „1” ... „9”: wynikiem jest 1 .. 9;
    • jeśli c == '': Number(c)wynosi 0, wynikiem jest 0;
    • w przeciwnym razie: Number(c)jest NaN, wynikiem jest 0;
  • Bitowy lub tutaj jest taki sam jak „dodaj”, ponieważ jednym z jego argumentów będzie 0

Suma

  • [c,...s] = sniech c = s[0]i s = s.slice(1);
    • jeśli s jest pustym łańcuchem, c jest niezdefiniowany ;
    • w przeciwnym razie c jest pierwszą literą s
  • undefined jest fałszem, niepusty ciąg znaków (w tym spacja) jest prawdziwy
tsh
źródło
1
Czy potrafisz wyjaśnić swój kod? wygląda naprawdę dobrze
Luis Felipe De Jesus Munoz
@LuisfelipeDejesusMunoz Właśnie dodał kilka.
tsh
5

Stax , 13 bajtów

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

Uruchom i debuguj

Rozpakowałem, nieprzylepiłem i skomentowałem to w ten sposób.

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)

Uruchom ten

rekurencyjny
źródło
3

Python 2 , 55 bajtów

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

Wypróbuj online!

Oparty na podejściu indeksowym wielu rozwiązań.

xnor
źródło
3

Java 8, 64 59 46 bajtów

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

-5 bajtów dzięki @Neil .
-13 bajtów dzięki @ OlivierGrégoire .

Wyjaśnienie:

Wypróbuj online.

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
źródło
1
("123456789//"+1e6+1e6+"X")wydaje się oszczędzać 5 bajtów.
Neil
To sprytna technika tworzenia łańcucha wypełniającego.
Makotosan
1
46 bajtów
Olivier Grégoire
3

F #, 106 103 bajtów

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

Wypróbuj online!

Myślę, że ta łamigłówka (bez gry w golfa) byłaby świetnym pytaniem dla przewodnika „Programowanie funkcjonalne dla początkujących”. I powinienem wiedzieć!

-3 od Kevina Cruijssena, za wykrycie, że białe spacje między „a” wtedy można usunąć. Dzięki!

Rozwiązanie rekurencyjne Staxa wykorzystujące indeksy łańcuchowe jest bardzo dobre. Jeśli przeniesiesz go do F #, możesz uzyskać go za 77 bajtów :

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

Wypróbuj to online!

Ciaran_McCarthy
źródło
1
Nie znam zbyt dobrze F #, ale wygląda na to, że możesz upuścić spacje po '-3 bajtach.
Kevin Cruijssen
Ani ja! Ale masz rację, dobrze zauważony! Dzięki!
Ciaran_McCarthy
2
@Ciaran_McCarthy: Nie mam nic przeciwko, jeśli skopiujesz moje rozwiązanie, jeśli chcesz je również dołączyć. Ludzie tutaj są ogólnie dość otwarci na tego rodzaju rzeczy. Wspólny wysiłek polega na znalezieniu najmniejszego kodu, nawet jeśli formalnie jest to konkurs.
rekurencyjny
1
Dzięki rekursywnie. Uwzględnię to, ponieważ jest to bardzo fajne rozwiązanie i interesujące jest zobaczyć, jak to wygląda w różnych językach.
Ciaran_McCarthy
2

Galaretka , 17 bajtów

ḟ⁾ -“X0/⁵”yV€o30S

Monadyczny link akceptujący listę znaków i zwracający liczbę całkowitą

Wypróbuj online!

W jaki sposób?

ḟ⁾ -“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

Również o 17:

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

Spróbuj tego

Jonathan Allan
źródło
2

Siatkówka , 17 bajtów

X
///
/
55
\d
*
_

Wypróbuj online!

Nie jestem na bieżąco z najnowszymi zmianami w Retinie. Przyjrzę się im bardziej, kiedy będę miał szansę i sprawdzę, czy są jakieś nowe sztuczki do gry w golfa. Kod zamienia wszystkie ostrzeżenia w trzy części zamienne, wszystkie części zamienne w dziesięć punktów, a następnie wszystkie punkty w odpowiednią liczbę znaków podkreślenia. Następnie zlicza liczbę znaków podkreślenia.

PunPun1000
źródło
2

Perl 5 -pF , 30 27 bajtów

-3 bajty dzięki Xcali

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

Wypróbuj online!

Ton Hospel
źródło
Możesz wyciąć dwa bajty, używając /X/zamiast y/X//i jeszcze jeden, używając m%/%zamiast y%/%%: Wypróbuj online!
Xcali
@Xcali Ah, oczywiście. Klasyczna krótkowzroczność golfa, wciąż myślałem o tym, y///kiedy zrobiłem je poza pętlą. Dzięki
Ton Hospel
1

05AB1E , 14 bajtów

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

Wypróbuj online!

Wyjaśnienie

þ`              # 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
źródło
1

J , 33 bajty

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

Wypróbuj online!

Wyjaśnienie:

] wejście

('-123456789',20 1#'/X')dodaje 20 /i jeden Xdo ciągu-123456789

i. znajduje indeksy wejściowe w powyższym ciągu

31|modulo 31 - aby pozbyć się spacji - nie znajdują się w ciągu, więc i.zwraca za nie 31

1#. znajduje sumę wskaźników

Galen Iwanow
źródło
Ponieważ J i Red to dwa zupełnie różne języki, lepiej opublikować dwie oddzielne odpowiedzi, nawet jeśli mogą zrobić to samo. Możesz dodać link z czerwonej odpowiedzi do tej odpowiedzi J, stwierdzając, że jest to port twojej odpowiedzi J.
Kevin Cruijssen
@Kevin Cruijssen - Ok, dzięki - zrobię to. Powodem złożenia ich razem jest to, że oczywiście czerwone rozwiązanie nie jest konkurencyjne (choć bardzo czytelne :))
Galen Iwanow
1

Python 2 , 67 bajtów

-3 bajty dzięki @KevinCruijssen

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

Wypróbuj online!

Dead Possum
źródło
1
Możesz zapisać 3 bajty, zmieniając '-123456789'+'/'*20+'X':sum(p.index(i)na'-123456789/'+'X'*20:sum(p.rfind(i)
Kevin Cruijssen
@KevinCruijssen dzięki, dobrze!
Dead Possum
1

Galaretka , 12 bajtów

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

Wypróbuj online!

Jak to działa

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

Kotlin , 50 bajtów

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

Wypróbuj online!

Mam nadzieję, że odpowiedź na twoje pytanie nie jest sprzeczna z zasadami, ale chciałem dołączyć do zabawy.

Math.Etworzy wartość 2.718281828459045. Używam go, aby utworzyć ciąg wypełniający, aby wypchnąć X do pozycji 30.

indexOfpobiera pozycję (w oparciu o 0) znaku w ciągu „12345 ...”. Jeśli nie zostanie znaleziony, zwraca -1. Dodajemy 1, aby te 0, i to również powoduje, że pozycja oparta na 0 jest wartością ciągu.

Makotosan
źródło
1

PHP, 119 109 bajtów

-10 bajtów dzięki @KevinCruijssen

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

Wypróbuj online!

Jo.
źródło
Można zmienić ($b=='/'?10+(int)$a:((int)$a+(int)$b)), aby (int)$a+($b=='/'?10:(int)$b)do -10 bajtów.
Kevin Cruijssen
@KevinCruijssen Dzięki, wygląda dobrze! Chociaż patrząc na inne odpowiedzi, wygląda na to, że zamierzam to zrobić w niewłaściwy / długi sposób. :)
Jo.
0

Węgiel , 23 bajty

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

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

SNOBOL4 (CSNOBOL4) , 169 151 147 bajtów

	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

Wypróbuj 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
źródło
0

Clojure , 70 bajtów

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

Wypróbuj online!

Podczas reduceprzetwarzania ciągu znaków każdy znak jest w rzeczywistości konwertowany na znak - kto by pomyślał. Ale to wszystko, muszę pisać \spacei to boli więcej niż można sobie wyobrazić. Ponadto podczas tworzenia rzeczywistej liczby z znaku kombinacja biginti strwydaje się być jedyną możliwą do użycia kombinacją.

Poza tymi wszystkimi zmaganiami: funkcja anonimowa, która zwraca wynik jako naturalny.

Jozuego
źródło