Sepuluh pin skor bowling - edisi World Bowling

20

Skor dunia Bowling

Banyak orang telah pergi ke pusat bowling lokal mereka untuk memainkan beberapa permainan bowling, dan banyak orang terus berjuang untuk menghitung skor mereka. World Bowling telah memperkenalkan sistem penilaian yang disederhanakan untuk menarik lebih banyak orang ke olahraga. Sistem penilaian ini digunakan dalam permainan internasional.

Sistem penilaian bekerja seperti ini (dari Wikipedia ):

Sistem penilaian Bowling Dunia — digambarkan sebagai "penilaian bingkai saat ini" [32] —menuju pin sebagai berikut:

  • strike: 30 (terlepas dari hasil rolls berikutnya)
  • cadangan: 10 plus pinfall pada gulungan pertama dari frame saat ini
  • open: pinfall total untuk frame saat ini

Jika Anda tidak terbiasa dengan bowling sepuluh pin, inilah rekapnya.

Ada 10 pin di ujung jalur bowling di mana tujuannya adalah untuk menjatuhkan mereka semua dengan bola bowling. Anda mendapatkan 2 gulungan bola untuk menjatuhkan mereka semua, lebih baik menjatuhkan mereka dengan gulungan pertama (dikenal sebagai pukulan ). Jika Anda mendapatkan pukulan, maka frame itu selesai dan Anda tidak perlu melempar bola untuk kedua kalinya. Pemogokan bernilai 30.

Jika Anda tidak meruntuhkan kesepuluh, Anda mendapatkan satu gulungan lagi. Jika Anda merobohkan semua pin yang tersisa, itu dikenal sebagai cadangan . Skor ini bernilai 10 pin + jumlah pin yang dirobohkan pada gulungan pertama. Misalnya, jika saya merobohkan 7 pin, maka berhasil merobohkan 3 pin yang tersisa, itu akan bernilai 17.

Jika setelah roll kedua Anda gagal merobohkan semua sepuluh, itu dikenal sebagai bingkai terbuka . Skor ini sebanding dengan jumlah total pin yang dirobohkan untuk frame itu.

Ada 10 frame dalam game . Jika Anda terbiasa dengan skor bowling tradisional, Anda tidak mendapatkan rol tambahan di frame 10 dengan World Bowling Scoring. Dalam penilaian bowling tradisional, dibutuhkan 12 serangan berurutan untuk mendapatkan skor sempurna 300, sedangkan skor World Bowling hanya membutuhkan 10 serangan berurutan.

Tantangan

Tantangan Anda adalah menghitung nilai yang diberikan nilai dari lembar skor.

Pada lembar skor, kehilangan ditandai dengan tanda hubung ( - ), serangan dengan X , dan cadangan dengan garis miring ( / ). Jika ini tidak berlaku, maka jumlah pinfall hanya ditunjukkan dengan angka (1-9). Pelanggaran dan pemecahan juga dicatat pada lembar skor tetapi Anda tidak perlu khawatir tentang ini.

Memasukkan

Anda akan diberi string yang terdiri dari skor untuk setiap frame, dan akan memiliki total sepuluh frame. Setiap frame akan memiliki hingga dua nilai, atau nilai minimal 1 jika ada serangan. Input Anda dapat berupa parameter string ke suatu fungsi, membaca dari file, atau dari STDIN.

Misalnya, jika saya merobohkan 1 pin pada gulungan pertama saya, lalu menjatuhkan 2, bingkai akan terlihat seperti "12". Ini tidak berarti 12 (dua belas), tetapi berarti 1 dan 2, dengan total 3.

Jika saya melewatkan setiap pin dengan kedua gulungan (talang bola), akan terlihat seperti ini "-" (skor 0).

Setiap frame akan dipisahkan oleh spasi.

Masukan sampel

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

Untuk menjabarkan contoh ini,

  • Frame 1 (-) - kedua gulungan tidak terjawab. mencetak 0
  • Bingkai 2 (9-) - merobohkan 9 gulungan pertama, terlewatkan pada gulungan kedua. Skor 9
  • Frame 3 (-9) - Melewatkan semua pada yang pertama, mendapat 9 pada yang kedua. Skor 9
  • Frame 4 (X) - Strike, merobohkan semua sepuluh. Skor 30
  • Frame 5 (- /) - Spare, ketinggalan semua pada yang pertama, merobohkan semua dengan gulungan ke-2. Nilai 10 + 0 = 10
  • Frame 6 (8 /) - Spare, 8 pin pada roll pertama, menjatuhkan 2 lainnya dengan roll kedua. Nilai 10 + 8 = 18
  • Frame 7 (71) - bingkai terbuka, 7 pin pada gulungan pertama, 1 pin pada gulungan kedua. Skor 7 + 1 = 8
  • Bingkai 8,9,10 ikuti contoh yang sama seperti di atas.

Keluaran

Output hanya akan menjadi nilai yang memiliki jumlah skor dari semua 10 frame. Menggunakan input sampel, output akan menjadi 128. Output Anda mungkin berupa string atau tipe numerik. Ini bisa berupa nilai pengembalian fungsi, atau ditulis ke STDOUT.

Aturan

  • Asumsikan bahwa input akan selalu valid. Misalnya, bingkai yang tidak valid adalah "/ 8", "XX", "123", "0", dll.
  • Anda tidak perlu khawatir tentang perpecahan atau pelanggaran.
  • Kode Anda dapat berupa program lengkap atau fungsi yang mengambil string dan mengembalikan skor.
  • Kode Anda tidak boleh membuang pengecualian.
  • Ini adalah kode golf, jawabannya dengan jumlah byte terkecil yang menang.
  • Bahasa yang menggunakan termasuk atau impor harus menyertakan pernyataan impor sebagai bagian dari kode mereka dan dihitung terhadap jumlah byte.

Uji Kasus

"-- 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
sumber
21
Saya kecewa ini bukan tantangan kode-bowling
Jo King
13
Contoh cadangan Anda yang pertama mengatakan bahwa nilainya adalah 13, tapi saya pikir seharusnya 17.
Jo.
@ Jo. Tangkapan yang bagus. Saya telah memperbarui pertanyaan untuk memperbaiki kesalahan itu.
Makotosan
@JoKing Saya berpikir ini adalah tantangan kode-bowling yang terdiri dari 10 sub-tantangan ketika saya pertama kali melihat judulnya.
Weijun Zhou
1
Salah satu tantangan terdokumentasi dan tertulis terbaik yang pernah saya lihat.
Joshua

Jawaban:

7

05AB1E , 12 11 byte

Kode

S'/T:'X30:O

Cobalah online!

Penjelasan

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
sumber
7

JavaScript, 43 byte

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

Bagaimana itu bekerja

Kami mengkonversi setiap karakter ke intinya:

  • 'X' bernilai 30 poin
  • '/' bernilai 10 poin
  • '1' .. '9' bernilai 1 .. 9 poin
  • karakter lain bernilai 0 poin

Kemudian jumlah semua poin.

Mengubah

Bitwise ATAU operator |mengonversi operan ke Int32 sebelum beroperasi. Saat mengonversi ke Int32, nilai terlebih dahulu dikonversi ke format Angka (angka float 64bit), kemudian trunk ke Int32 (atau dikonversi ke 0 jika tidak valid).

  • ToInt32({'/':10,X:30}[c]) dapat dibaca sebagai:
    • jika c == '/': hasilnya adalah 10;
    • jika c == 'X': hasilnya 30;
    • jika tidak: hasilnya adalah ToInt32(undefined)-> ToInt32(NaN)-> 0;
  • ToInt32(c) bisa jadi:
    • jika c == '1' ... '9': hasilnya adalah 1 .. 9;
    • jika c == '': Number(c)adalah 0, hasilnya adalah 0;
    • jika tidak: Number(c)adalah NaN, hasilnya adalah 0;
  • Bitwise atau di sini sama dengan "add", karena salah satu operandnya adalah 0

Jumlah

  • [c,...s] = sbiarkan c = s[0], dan s = s.slice(1);
    • jika s adalah string kosong, c tidak terdefinisi ;
    • jika tidak, c adalah huruf pertama dari s
  • undefined adalah falsy, string yang tidak kosong (termasuk spasi) adalah benar
tsh
sumber
1
Bisakah Anda menjelaskan kode Anda? terlihat sangat bagus
Luis felipe De jesus Munoz
@LuisfelipeDejesusMunoz Baru saja menambahkan beberapa.
tsh
5

Stax , 13 byte

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

Jalankan dan debug itu

Membongkar, tidak bertunas, dan berkomentar demikian.

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)

Jalankan yang ini

rekursif
sumber
3

Python 2 , 55 byte

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

Cobalah online!

Didasarkan pada pendekatan string-index dari banyak solusi.

Tidak
sumber
3

Java 8, 64 59 46 byte

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

-5 byte terima kasih kepada @Neil .
-13 byte berkat @ OlivierGrégoire .

Penjelasan:

Cobalah 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
sumber
1
("123456789//"+1e6+1e6+"X")tampaknya menghemat 5 byte.
Neil
Itu teknik yang pintar untuk membuat beberapa string pengisi.
Makotosan
1
46 byte
Olivier Grégoire
3

F #, 106 103 byte

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

Cobalah online!

Saya pikir teka-teki ini (tanpa bermain golf) akan menjadi pertanyaan yang bagus untuk panduan "Pemrograman fungsional untuk pemula". Dan saya harus tahu!

-3 dari Kevin Cruijssen, untuk mengetahui bahwa spasi putih antara 'dan "maka" dapat dihapus. Terima kasih!

solusi Stax rekursif menggunakan indeks string sangat sangat baik. Jika Anda porting ke F # Anda bisa mendapatkannya untuk 77 byte :

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

Coba ini secara online!

Ciaran_McCarthy
sumber
1
Saya tidak tahu F # dengan sangat baik, tetapi sepertinya Anda dapat menghapus spasi setelah '-3 byte.
Kevin Cruijssen
Saya juga tidak! Tapi kau benar, terlihat jelas! Terima kasih!
Ciaran_McCarthy
2
@Ciaran_McCarthy: Saya tidak keberatan jika Anda menyalin solusi saya jika Anda ingin memasukkannya juga. Orang-orang di sini pada umumnya cukup terbuka tentang hal semacam ini. Ini adalah upaya kerja sama untuk menemukan semua kode terkecil, meskipun secara resmi merupakan kompetisi.
rekursif
1
Terima kasih rekursif. Saya akan memasukkannya, karena ini solusi yang sangat bagus, dan menarik untuk melihat tampilannya dalam berbagai bahasa.
Ciaran_McCarthy
2

Jelly , 17 byte

ḟ⁾ -“X0/⁵”yV€o30S

Tautan monadik yang menerima daftar karakter dan mengembalikan integer

Cobalah online!

Bagaimana?

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

Juga di 17:

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

Coba itu

Jonathan Allan
sumber
2

Perl 6 , 30 byte

{TR'-/X '0㉈㉊'.univals.sum}

Cobalah online!

nwellnhof
sumber
2

Retina , 17 byte

X
///
/
55
\d
*
_

Cobalah online!

Saya tidak cukup tahu tentang perubahan Retina terbaru. Saya akan melihat lebih dalam ketika saya mendapat kesempatan dan melihat apakah ada trik baru untuk bermain golf ini. Kode mengubah semua teguran menjadi tiga suku cadang, semua suku cadang menjadi sepuluh poin, lalu semua poin ke jumlah garis bawah yang sesuai. Kemudian ia menghitung jumlah garis bawah.

PunPun1000
sumber
2

Perl 5 -pF , 30 27 byte

-3 byte terima kasih kepada Xcali

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

Cobalah online!

Ton Hospel
sumber
Anda dapat memotong dua byte dengan menggunakan /X/alih-alih y/X//dan satu lagi dengan menggunakan m%/%alih-alih y%/%%: Coba online!
Xcali
@Xcali Ah, tentu saja. Kepicikan golf klasik, saya masih berpikir dalam hal y///dari ketika saya melakukannya di luar lingkaran. Terima kasih
Ton Hospel
1

05AB1E , 14 byte

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

Cobalah online!

Penjelasan

þ`              # 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
sumber
1

J , 33 byte

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

Cobalah online!

Penjelasan:

] input

('-123456789',20 1#'/X')menambahkan 20 /dan satu Xke string-123456789

i. menemukan indeks input dalam string di atas

31| modulo 31 - untuk menghilangkan spasi - mereka tidak ditemukan dalam string, jadi i. kembalikan 31 untuk mereka

1#. menemukan jumlah indeks

Galen Ivanov
sumber
Karena J dan Red adalah dua bahasa yang sangat berbeda, lebih baik memposting dua jawaban yang terpisah, meskipun mereka mungkin melakukan hal yang sama. Anda dapat menambahkan tautan dari jawaban Merah ke jawaban J ini, dengan menyatakan itu adalah port jawaban J Anda.
Kevin Cruijssen
@Kevin Cruijssen - Ok, terima kasih - saya akan melakukannya. Alasan untuk mempostingnya bersama adalah karena solusi Merah jelas tidak kompetitif (walaupun banyak yang bisa dibaca :))
Galen Ivanov
1

Python 2 , 67 byte

-3 byte terima kasih kepada @KevinCruijssen

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

Cobalah online!

Possum Mati
sumber
1
Anda dapat menyimpan 3 byte dengan mengubah '-123456789'+'/'*20+'X':sum(p.index(i)ke'-123456789/'+'X'*20:sum(p.rfind(i)
Kevin Cruijssen
@KevinCruijssen terima kasih, bagus!
Dead Possum
1

Jelly , 12 byte

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

Cobalah online!

Bagaimana itu bekerja

⁾/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
sumber
1

Kotlin , 50 byte

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

Cobalah online!

Mudah-mudahan tidak melanggar aturan untuk menjawab pertanyaan Anda sendiri, tetapi saya ingin ikut bersenang-senang.

Math.E menghasilkan nilai 2.718281828459045 . Saya menggunakannya untuk membuat beberapa string pengisi untuk mendorong X ke posisi 30.

indexOfmendapatkan posisi (berbasis-0) dari karakter dalam string "12345 ...". Jika tidak ditemukan, ia mengembalikan -1. Kami menambahkan 1 untuk membuat 0 ini, dan itu juga menjadikan posisi berbasis 0 nilai dari string.

Makotosan
sumber
1

PHP, 119 109 byte

-10 byte terima kasih kepada @KevinCruijssen

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

Cobalah online!

Jo.
sumber
Anda dapat mengubah ($b=='/'?10+(int)$a:((int)$a+(int)$b))ke (int)$a+($b=='/'?10:(int)$b)untuk -10 byte.
Kevin Cruijssen
@KevinCruijssen Terima kasih, terlihat bagus! Meskipun, melihat jawaban yang lain, sepertinya saya akan melakukan ini dengan cara yang salah / jauh. :)
Jo.
0

Arang , 23 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

  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
sumber
0

Merah , 93 byte

func[b][s: 0
foreach c trim/all b[s: s - 1 + index? find{-123456789/...................X}c]s]

Cobalah online!

Galen Ivanov
sumber
0

C # (.NET Core) , 40 + 18 = 58 byte

using System.Linq;
s=>s.Sum(c=>c>87?30:c<46?0:c<48?10:c-48)

Cobalah online!

raznagul
sumber
0

SNOBOL4 (CSNOBOL4) , 169 151 147 byte

	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

Cobalah 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
sumber
0

Clojure , 70 byte

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

Cobalah online!

Ketika reducemenggunakan String, masing-masing char sebenarnya diubah menjadi char - yang akan berpikir. Tapi ini berarti, saya harus menulis \spacedan itu menyakitkan lebih dari yang bisa dibayangkan. Juga, ketika membuat angka aktual dari char, kombinasi bigintdan strtampaknya merupakan satu-satunya kombinasi yang dapat digunakan.

Nah, terlepas dari semua perjuangan ini: Fungsi anonim yang mengembalikan skor sebagai hal yang wajar.

Joshua
sumber