import Foundation
func printTimeElapsedWhenRunningCode(title:String, operation:()->()) {
let startTime = CFAbsoluteTimeGetCurrent()
operation()
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
println("Time elapsed for \(title): \(timeElapsed) s")
}
func squaresSummed(first: Int, second: Int) -> Int {
return (first + (second * second))
}
func solution6() {
let firstHundredInts = [Int](1 ... 100)
let summed = firstHundredInts.reduce(0) { 0ドル + 1ドル }
let summedSquared = summed * summed
let squaredSummed = firstHundredInts.reduce(0, combine: squaresSummed)
let answer = summedSquared - squaredSummed
println(String(answer))
}
printTimeElapsedWhenRunningCode("Sum square difference", solution6)
Some of the built in Swift stuff made this quite nice. The syntax for declaring an array which is a simple list of integers is very convenient. It runs faster than iterating through a loop to set all the values, types faster and reads better than typing all the values out by hand.
I quite like the reduce
function on Swift arrays.
What could make this more Swift...-onic? What needs improvement?
1 Answer 1
First, I would suggest that the solution6()
function takes a parameter for
the upper bound, and returns the result instead of printing it (as also
suggested by @user16547 while I was writing this answer):
func solution6(upper : Int) -> Int {
let firstInts = [Int](1 ... upper)
let summed = firstInts.reduce(0) { 0ドル + 1ドル }
let summedSquared = summed * summed
let squaredSummed = firstInts.reduce(0, combine: squaresSummed)
return summedSquared - squaredSummed
}
printTimeElapsedWhenRunningCode("Sum square difference") {
let answer = solution6(10_000)
println(answer)
}
Then you use an auxiliary function squaresSummed
for computing the second
sum, but not for the first (and the name of that function is not very descriptive). In my opinion it is easier to understand if the shorthand notation is used
for both summations:
func solution6(upper : Int) -> Int {
let firstInts = [Int](1 ... upper)
let summed = firstInts.reduce(0) { 0ドル + 1ドル }
let squaredSummed = firstInts.reduce(0) { 0ドル + 1ドル * 1ドル }
return summed * summed - squaredSummed
}
For an upper bound of 10,000, this took about 0.001 seconds on my MacBook Pro in Release mode.
But [Int](1 ... upper)
creates an array of all that numbers, which costs time
and memory. If you use a range instead
func solution6(upper : Int) -> Int {
let firstInts = 1 ... upper
let summed = reduce(firstInts, 0) { 0ドル + 1ドル }
let squaredSummed = reduce(firstInts, 0) { 0ドル + 1ドル * 1ドル }
return summed * summed - squaredSummed
}
the time is reduced to about 0.0002 seconds. This is about the same time needed for a simple loop
func solution6(upper : Int) -> Int {
var summed = 0
var squaredSummed = 0
for i in 1 ... upper {
summed += i
squaredSummed += i * i
}
return summed * summed - squaredSummed
}
which would be the most straightforward implementation of the algorithm.
Of course the fastest and shortest solution to the PE problem would be to
Find the closed formula for 1 + 2 + ... + n and 1^2 + 2^2 + ... + n^2 and use that instead of a loop.
Explore related questions
See similar questions with these tags.
println
s etc. in the methods that solve the problem. I don't want to include them in my time measurements. \$\endgroup\$wift
in Sonic. \$\endgroup\$