保龄球
* * * *
拉格朗日计划
* * * *
保龄球

给定一系列保龄球的记分表,按以下传统规则计算并输出总得分。

每局分为十轮,每轮玩家都可以发两次球,以击倒赛道尽头的全部十个瓶子为目标。

每轮的结果在记分表中都用以下符号中的一个来表示:

X:大满贯(Strike)在每轮的第一次发球就击倒了全部十个瓶子。
/:小满贯(Spare) 在每轮的第二次发球击倒了全部十个瓶子。
d:d是1到9之间的数字,表示本轮击倒的瓶子数。
c:c是5到8之间的带圈数字,例如⑤,称为分屏(Split)以描述一种特殊局面,圈中的数字表示本轮击倒的瓶子数。
-:本轮未击倒任何瓶子。
F:犯规。
每轮的得分即该轮击倒的瓶子数(因此犯规和未命中的轮次得$0$分)。

若玩家在前九局中打出大满贯,则该局直接结束,并额外计入后两次发球的得分作为本轮的奖励分。

例:前三轮连续三次大满贯,第四轮分别得1分和2分,则第一次大满贯得10分+奖励分20分,第二次大满贯得10分+奖励分11分,第二次大满贯得10分+奖励分3分,第四轮得3分,四轮总分67分。

若玩家在第十局打出大满贯,则增加两次发球机会,这两次发球的得分作为该大满贯轮的奖励分,这两次发球的得分不再另外计入总分。

若玩家在前九局中打出小满贯,则额外计入下一次发球的得分作为本轮的奖励分。 若玩家在第十局打出小满贯,则增加一次发球机会,这次发球的得分作为该小满贯轮的奖励分,同时这次发球的得分不再另外计入总分。

本题的每条输入数据都是一局游戏的记分表,轮与轮之间用一个空格隔开,注意若最后一轮为大满贯或小满贯,那么奖励的两次或一次发球与最后一轮的记分之间并无空格隔开。

此外,前九局的大满贯记作空格+“X”,即“ X”,第十局及之后的大满贯用一个单独的“X”表示。若第十局是大满贯且玩家在第二次奖励发球中击倒了全部瓶子,那么该次发球的得分仍会被记作“/”。

每局游戏的总得分单独打印一行。

本题难度:



解答

先算一遍基础分,“/”以外的字符用字典加字符串查找换算得分,“/”根据前一项计算,然后算一遍奖励分,两者相加即可。

最终代码有四行。

代码长度:283字节 vs. 全站第一:129字节。

import sys
x=lambda k:dict(zip('F⑤⑥⑦⑧X',[0,5,6,7,8,10])).get(k,'-123456789'.find(k))
p,q=''.join,enumerate
for a in sys.argv[1:]:s=a.split();t=p(s);c=[[x(j),10-x(t[i-1])][j=='/']for i,j in q(t)];print(sum([c[i+1],c[i+1]+c[i+2],0]['/X'.find(j)]for i,j in q(p(s[:-1])))+sum(c))