2008脚本大赛PowerShell初级组Event 10解题及分析

来源:互联网 发布:风油精 知乎 肛门 编辑:程序博客网 时间:2024/05/21 21:35

中文题目: http://www.microsoft.com/technet/scriptcenter/funzone/games/games08/chs/bevent10.mspx

官方解题: http://www.microsoft.com/technet/scriptcenter/funzone/games/solutions08/bpssol10.mspx

我只玩过1次保龄球, 对规则也不了解. 通过初级组的整场比赛, 我还是多少了解了保龄的积分规则. 题目涉及的是简单保龄球规则, 规则指出, 当我们strike时(第一次roll就击倒所有pin), 我们需要累加家下来两轮的积分, 而spare时(), 我们需要累加下一轮的积分. 我们可以分析所有可能的得分序列, 下面, 我们用D代表数字, /表示spare, X表示strike. 我们知道/一定跟随在D的后面:

D  D 两轮, 或一轮没有将Pin都击倒 D  / spare情况 D  X 两轮, 第二轮strike /  D 两轮 /  X 两轮, 第二轮strike X  D  D strike后, 没有全部击倒 X  D  / strike后, 第二轮spare X  X  D strike后, strike, 接下来没有全中 X  X  X 连续3轮strike

通过上面的情况, 我们可以在遇到数字时, 记录改数值, 并直接将结果计入总和. 当遇到spare情况时, 我们将/和下一个字符, 以及相对spare上一次roll的结果通过函数scores处理.

如果遇到strike,我们将X和接下来两次的roll结果都传入scores处理.

我们知道strike一定是10分, 因此简单的将所有 X 替换为 10即可. spare一定是跟随在D的后面, 因此我们可以简单的将D / 替换为一个整体 10 分. 如果遇到 / D 或者 / X 时,  我们只需要简单将 / 换成与同一轮中补中的分数, 就是10 - $last. 这里, 我们将连续的数值使用 + 进行连接, 这样 Invoke-Expression 就能帮我们计算出结果. 代码如下, 理解上多少有些复杂, 官方答案比较简单. 这里每个人思路不同, 所以大家相互学习就好, 也许我的办法过于复杂, 不过无论如何, 它都能正常工作.

$arrFrames = 2,5,7,"/",8,1,"X",9,"/",5,3,7,0,4,5,"X",2,0
$score = 0
function scores (
$exp, $cur) {
  
$exp = $exp -replace "X", 10
  
$exp = $exp -replace "/d/+/", 10
  
$exp = $exp -replace "/", $cur
  Invoke
-Expression $exp
}
$ofs = "+"
for ($p = 0$p -lt $arrFrames.Count; $p++) {
  switch 
-regex ($arrFrames[$p]) {
    
"d" { $score += $_$last = $_ }
    
"/"  { $cur = 10 - $last$score += scores "$($arrFrames[$p..($p+1)])" $cur;$last = 0 }
    
"X"  { $score += scores "$($arrFrames[$p..($p+2)])" $cur;$last = 0 }
  }
}
$score
 
原创粉丝点击