6
\$\begingroup\$

I found this one a little bit easier than the previous problems, but I was already familiar with the GCD/LCM formulas.

import Foundation

func printTimeElapsedWhenRunningCode(title:String, operation:()->()) {
    let startTime = CFAbsoluteTimeGetCurrent()
    operation()
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    println("Time elapsed for \(title): \(timeElapsed) s")
}

func greatestCommonDenominator(a: Int, b: Int) -> Int {
    return b == 0 ? a : greatestCommonDenominator(b, a % b)
}

func leastCommonMultiple(a: Int, b: Int) -> Int {
    return a * (b / greatestCommonDenominator(a, b))
}

func leastCommonMultiple(input: [Int]) -> Int {
    var result: Int = input[0]
    for value in input {
        result = leastCommonMultiple(result, value)
    }
    return result
}

func solution5() {
    let firstTwentyInts: [Int] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
    let answer: Int = leastCommonMultiple(firstTwentyInts)

    println(String(answer))
}

printTimeElapsedWhenRunningCode("Least Common Multiple", solution5)

And for the record, I know that solution5() is ugly as a function, but for the purposes of this review, you should think of that more like you might think of main in another programming language. Ultimately, I've only packaged those lines of code into a function so I can throw it in printTimeElapsedWhenRunningCode() which is a nice way to time my solutions.

This particular solution consistently runs in under 0.001 seconds (some times as low as 0.0004 seconds) for me.

\$\endgroup\$
  • 2
    \$\begingroup\$ Minor suggestion: let firstTwentyInts = [Int](1 ... 20). \$\endgroup\$ – Martin R Aug 26 '14 at 17:54
  • \$\begingroup\$ I was wondering if there was an easier way, but couldn't easily find it. \$\endgroup\$ – nhgrif Aug 26 '14 at 21:32
1
\$\begingroup\$

In general, I like it; nice solution. Functions are well separated and I understood what it was doing right away, just from the function names.

You can get rid of one of your leastCommonMultiple functions (and make it more Swifty I think) by passing it a Range instead of an Array and by using reduce():

func greatestCommonDenominator(a: Int, b: Int) -> Int {
    return b == 0 ? a : greatestCommonDenominator(b, a % b)
}

func leastCommonMultiple(range: Range<Int>) -> Int {
    return reduce(range, 1) { (a, b) in a * (b / greatestCommonDenominator(a, b)) }
}

func solution5() {
    let answer = leastCommonMultiple(1...20)
    println(answer)
}

That change also seems to speed it up significantly. On my machine it changed the average run time from 0.0001 seconds to 0.00002 seconds; I believe that's simply from not having to create the Array though.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.