Skip to content

Instantly share code, notes, and snippets.

@natecook1000
Created February 9, 2018 08:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natecook1000/838b533ce04d6df33f1bbb2636e0cbc3 to your computer and use it in GitHub Desktop.
Save natecook1000/838b533ce04d6df33f1bbb2636e0cbc3 to your computer and use it in GitHub Desktop.
/// Performs an exponential search to find the number of steps from `start` to `end`
/// without using division.
func count<T: Numeric & Comparable>(from start: T, to end: T, by step: T) -> Int {
var count = 1
var current = start
var stepMultipliers = [1]
while current < end {
count += stepMultipliers.last!
current += step * T(exactly: stepMultipliers.last!)!
stepMultipliers.append(stepMultipliers.last! * 2)
}
_ = stepMultipliers.removeLast()
while current >= end {
let subtract = stepMultipliers.removeLast()
let test = current - step * T(exactly: subtract)!
if test >= end {
current = test
count -= subtract
continue
}
if end - test <= step {
count -= subtract
break
}
}
return count
}
let start = 0
let end = 10_000
let step = 3
print("count:", Array(stride(from: start, to: end, by: step)).count)
print("calculated:", count(from: start, to: end, by: step))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment