Created
April 8, 2016 19:26
-
-
Save kevbuchanan/e8e929f033b1306dca727b56c93902ee to your computer and use it in GitHub Desktop.
Bowling Swift
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
class Frame { | |
var one: Int | |
var two: Int? | |
var extras: [Int] | |
init(one: Int, two: Int?) { | |
self.one = one | |
self.two = two | |
self.extras = [Int]() | |
} | |
func score() -> Int { | |
return rolls() + self.extras.reduce(0) { $0 + $1 } | |
} | |
func close(following: Frame) -> Frame { | |
if isClosed() { | |
return self | |
} else { | |
return takeExtras(following) | |
} | |
} | |
private func isClosed() -> Bool { | |
return (rolls() < 10) || | |
(self.one == 10 && self.extras.count == 2) || | |
(self.one != 10 && rolls() == 10 && self.extras.count == 1) | |
} | |
private func rolls() -> Int { | |
if (self.two == nil) { | |
return self.one | |
} else { | |
return self.one + self.two! | |
} | |
} | |
private func takeExtras(following: Frame) -> Frame { | |
if (self.one == 10) { | |
self.extras.append(following.one) | |
if (following.two != nil && self.extras.count != 2) { | |
self.extras.append(following.two!) | |
} | |
return self | |
} else { | |
self.extras.append(following.one) | |
return self | |
} | |
} | |
} | |
func newFrame(one: Int, _ two: Int) -> Frame { | |
return Frame(one: one, two: two) | |
} | |
func newFrame(one: Int) -> Frame { | |
return Frame(one: one, two: nil) | |
} | |
typealias Score = (frames: [Int], total: Int) | |
func bowlingScore(frames: [Frame]) -> Score { | |
let scores = frames.reduce([Frame]()) { (prev, frame) in | |
return prev.map { (f) in f.close(frame) } + [frame] | |
}.map { $0.score() }[0...9] | |
return Score(Array(scores), scores.reduce(0) { $0 + $1 }) | |
} | |
let game1 = [Frame](count: 10, repeatedValue: newFrame(0, 0)) | |
print(bowlingScore(game1)) | |
let game2 = [Frame](count: 10, repeatedValue: newFrame(0, 1)) | |
print(bowlingScore(game2)) | |
let game3 = [Frame](count: 12, repeatedValue: newFrame(10)) | |
print(bowlingScore(game3)) | |
let game4 = [ | |
newFrame(10), // 30 | |
newFrame(10), // 28 | |
newFrame(10), // 18 | |
newFrame(8, 0), // 8 | |
newFrame(0, 8), // 8 | |
newFrame(7, 1), // 8 | |
newFrame(9, 1), // 17 | |
newFrame(7, 1), // 8 | |
newFrame(7, 1), // 8 | |
newFrame(5, 0) // 5 | |
] // 138 | |
print(bowlingScore(game4)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment