某日某所にてボウリングのスコアを計算するプログラミングフィッシュボウルが行われていたのですが、 都合が付かずに参加できなくてくやしい思いをしたので、同じ課題をHaskellで書いてみました。
問題
ボウリングのスコアシートの上の部分が与えられたときに、その最終スコアを計算せよ。
入力
- ボウリングのスコアシートの上の部分を示す文字列
20文字程度長さのの文字列で、入力として可能な文字は次の通りです。
-
はガター/
はスペアX
はストライク1
〜9
は倒したピン数
出力
ゲームのスコアを表す整数
入出力例
- 入力「’XXXXXXXXXXXX’」は全ストライクなので、出力は「300」
- 入力「
9-9-9-9-9-9-9-9-9-9-
」は全フレームで「1投目で9本倒すが2投目はガター」なので、出力は「90」
なお、ボウリングのスコア計算法は数多くのサイトで紹介されているので、ここでは割愛します。自分では次のページを参照しました。
Haskelltの回答例
- スペアの処理にちょっと手間がかかります
- それによって最終フレームがややこしくなりました
- フレームごとに分けるとストライクのボーナスである次の2投分の計算がややこしくなるので避けたほうがよいです
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
score' :: Int -> Char -> Int | |
score' _ '-' = 0 | |
score' b '/' = 10 - b | |
score' _ 'X' = 10 | |
score' _ '1' = 1 | |
score' _ '2' = 2 | |
score' _ '3' = 3 | |
score' _ '4' = 4 | |
score' _ '5' = 5 | |
score' _ '6' = 6 | |
score' _ '7' = 7 | |
score' _ '8' = 8 | |
score' _ '9' = 9 | |
score = score' 0 | |
calc :: Int -> [Char] -> Int | |
calc 10 ('X':'X':x:[]) = 20 + (score x) | |
calc 10 ('X':x:y:[]) = 10 + (score x) + (score y) | |
calc 10 (x:'/':y:[]) = 10 + (score y) | |
calc 10 (x:y:[]) = (score x) + (score y) | |
calc f ('X':xs) = 10 + b1 + b2 + (calc (f+1) xs) | |
where b1 = score (head xs) | |
b2 = score' b1 (head (tail xs)) | |
calc f (x:'/':xs) = 10 + b1 + (calc (f+1) xs) | |
where b1 = score (head xs) | |
calc f (x:y:xs) = t1 + t2 + (calc (f+1) xs) | |
where t1 = score x | |
t2 = score' t1 y | |
printTest (testCase, result) = do | |
putStrLn $ (if (calc 1 testCase) == result then "CLEAR" else "FAIL") ++ " " ++ testCase | |
testCases = [ | |
("9-9-9-9-9-9-9-9-9-9-", 90), | |
("X54----------------", 28), | |
("1/5-----------------", 20), | |
("1/5-2/-/8-----------", 56), | |
("------XX----------", 30), | |
("------XXX--------", 60), | |
("XXXXXXXXXXXX", 300), | |
("--------------------", 0), | |
("-------------------/5", 15), | |
("------------------X54", 19), | |
("5/5/5/5/5/5/5/5/5/5/5", 150) | |
] | |
test = mapM_ printTest testCases | |
main = test | |
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。