Skor game Bowling

25

Tugas Anda adalah untuk meringkas dan menghasilkan skor satu pemain dalam permainan bowling 10-pin setelah hingga 21 gulungan .

Gulungan direpresentasikan sebagai urutan bilangan bulat dalam metode input pilihan Anda . Setiap bilangan bulat sesuai dengan jumlah pin yang dirobohkan dalam gulungan itu.

Mencetak gol

Setelah setiap putaran , jumlah pin yang dijatuhkan di babak itu dihitung menjadi skor akhir. Jika seorang pemain merobohkan semua sepuluh pin pada putaran pertama dari sebuah ronde, ini adalah pukulan , dan ronde itu telah berakhir. Kalau tidak, putaran berlangsung untuk satu roll lagi. Jika gulungan kedua dari putaran merobohkan semua pin yang tersisa, ini merupakan cadangan .

Untuk setiap serangan ada bonus yang sama dengan jumlah pin yang dirobohkan dalam dua gulungan berikutnya. Untuk setiap cadangan ada bonus sama dengan jumlah pin yang dirobohkan dalam gulungan berikutnya.

Babak ke-10 dan terakhir, pemain dapat diberikan gulungan ekstra: Dalam hal terjadi pemogokan, pemain mendapat dua gulungan lagi untuk membuat bonus serangannya. Dalam hal cadangan, pemain mendapat satu gulungan lagi.

Contohnya

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

Aturan

  • Anda dapat mengasumsikan bahwa input tersebut valid.
  • Sesuai komentar Mego, saya telah melonggarkan persyaratan untuk metode input / output untuk memenuhi standar kami saat ini .
  • Jawaban dalam bahasa yang lebih baru daripada tantangan diizinkan
  • Kode terpendek menang!
daniero
sumber
Apakah saya ingat benar bahwa bonus tidak ditumpuk?
Titus
@ Titus Saya tidak begitu yakin apa yang Anda maksud, tetapi tidak, bonus tidak "menumpuk", yaitu, untuk pemogokan Anda menambahkan jumlah pin yang dirobohkan dalam dua gulungan berikutnya , terlepas dari apakah itu mogok atau tidak. Jadi skor maksimum untuk satu serangan adalah 30 poin, dan maksimum untuk seluruh pertandingan adalah 300.
daniero
Apakah argumen baris perintah yang berbeda memenuhi syarat space separated integers?
Titus
1
@Titus yakin. Ini adalah pos lama - Konsensus hari ini tentang metode input yang dapat diterima tidak ditetapkan pada saat ini. Sebenarnya, saya tidak mengerti sekarang mengapa standar hari ini tidak berlaku untuk ini (termasuk parameter fungsi dll), meskipun saya bukan penggemar mengubah aturan tantangan secara surut.
daniero
1
@daniero Saran yang biasa adalah bahwa dapat diterima untuk melonggarkan aturan agar sesuai dengan standar modern, selama itu tidak secara drastis mengubah tantangan.
Mego

Jawaban:

6

GolfScript, 50 41 karakter

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

Upaya lain di GolfScript ( jalankan online ).

Penjelasan kode berikut. Solusinya memanfaatkan sifat tumpukan masalah (mengkonsumsi gulungan satu demi satu) tetapi karena itu input harus dibalik.

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

Versi sebelumnya:

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

Python, 116 110 105 103 100 99 karakter

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)

Menghabiskan 30 karakter pada input sangat menjengkelkan. Saran diterima.

Terima kasih banyak kepada Howard untuk perbaikan.

Steven Rumbalski
sumber
Anda dapat mengganti 1+(z[i]!=10)dengan 2-(z[i]>9)untuk menyimpan satu char.
Howard
@ Howard: Saran yang sangat baik. Saya telah memasukkannya ke dalam jawaban saya. Ini menyelamatkan dua karakter.
Steven Rumbalski
Dan dua lagi jika Anda menghapus isepenuhnya (set ke 0) dan bukannya i+=...menggunakanz=z[2-(z[0]>9)::];
Howard
@ Howard: Terima kasih lagi. Menyimpan tiga karakter.
Steven Rumbalski
Standar untuk I / O umumnya lebih fleksibel sekarang sehingga z=input()harus baik-baik saja (secara efektif mengambil representasi string dari daftar intdan evalmemasukkannya). Namun program penuh harus menampilkan suatu tempat (saya pikir ini juga terjadi saat itu juga). Karena itu saya percaya ini dapat diubah ke program 78 byte ini
Jonathan Allan
4

R, 101 byte

Saya tidak yakin mengapa tantangan ini terbentur, tetapi saya menyukainya, jadi saya akan terlambat menjawab.

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)

Cobalah online!

Tidak Disatukan:

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

Fungsi rekursif. Diambil xsebagai input, yang menyimpan skor. Menginisialisasi sinti dan cmemperkirakan jumlah putaran yang dilemparkan.

Pernyataan if memeriksa apakah 10 putaran dilemparkan, atau jika xkosong. Jika itu masalahnya, skor dikembalikan. Jika tidak, fungsi akan memanggil dirinya sendiri sebagai berikut:

Ini menghapus lemparan dari x, dengan memeriksa apakah itu serangan atau tidak. Jika demikian, entri pertama dihapus, atau dua entri pertama. (S=x[1]!=10)memeriksa pemogokan. Kami menghapus ( -) indeks 0:S, di mana S1 jika mogok, dan 0 jika tidak. Dan kemudian kita menambahkan satu: -(0:(x[1]!=10)+1). Kami meneruskan xpanggilan singkat ke panggilan berikutnya.

Adapun skor, ini ditemukan dengan mengambil x[1:2]jika itu adalah giliran reguler, dan x[1:3]jika itu adalah serangan atau cadangan. Kami memeriksa apakah sum(x[1:2])lebih besar atau sama dengan 10. Jika itu adalah pemogokan, jelas ini masalahnya. Jika itu cadangan, maka ini berfungsi juga. Jadi, jika ini BENAR, kami menambah x[3]jumlahnya. Ini kemudian ditambahkan ke s.

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

EDIT : Sebuah penulisan ulang yang lumayan, tanpa malu-malu menjiplak pendekatan berbasis stack Howard yang hebat. Saya yakin lebih banyak yang dapat dihapus untuk mengakses elemen terakhir dari array tanpa merusaknya ...

Johno
sumber
1

Ruby, 252 byte

Menerima input ke dalam array, tambahkan semua elemen terlebih dahulu, lalu cari bonus cadangan dan teguran

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

PHP, 82 byte

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

mengambil input dari argumen baris perintah; jalankan dengan -nratau coba online .

kerusakan

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

Perl 5 , 65 + 2 = 67 byte

Membutuhkan -apbendera

$\+=(($"=shift@F)<10?$"+=shift@F:10+$F[1])+$F[0]*(9<$")for 0..9}{

Cobalah online!

Xcali
sumber
1

Jelly ,  36  35 byte

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

Tautan monadik yang menerima daftar bilangan bulat dan mengembalikan bilangan bulat.

Cobalah online!

Bagaimana?

Hitung skor setiap putaran tumpang tindih dari tiga mangkuk seolah-olah itu adalah yang dimulai pada awal bingkai dan secara opsional menambahkan tanda pengenal pemogokan ( -1), meratakan daftar hasil ini, membaginya pada pengidentifikasi pemogokan, kemudian membuang setiap detik hasil dari setiap chunk (menghapus skor run yang tidak benar-benar dimulai dengan awal frame).

Untuk memenuhi kerangka akhir, nol pertama ditambahkan ke input (untuk memungkinkan pengiris 3-bijaksana untuk memungkinkan bingkai untuk memulai pada apa yang merupakan mangkuk kedua dari belakang) dan skor yang dihasilkan dipotong ke sepuluh pertama (untuk menghapus sekarang mungkin bingkai 11 palsu) sebelum menyimpulkannya.

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

Perl, 140?

Percobaan pertama:

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

Sedihnya, ada beberapa kasus dimana gagal. Saya akan datang dan mengulanginya nanti.

o_o
sumber