Created
November 24, 2015 06:40
-
-
Save cfilipov/1461ac31d59d6a40376c to your computer and use it in GitHub Desktop.
Abusing Swift's CollectionType protocol with Int indexing
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
import Darwin | |
infix operator ** { associativity left precedence 151 } | |
func **(x: Int, n: Int) -> Int { | |
if n == 0 { return 1 } | |
var p = abs(x) | |
for _ in 1..<n { | |
p *= abs(x) | |
} | |
return p | |
} | |
extension Int { | |
var numDigits: Int { | |
if self == 0 { return 1 } | |
if self == Int.min { return Int(log10(Double(abs(self + 1))) + 1) } | |
return Int(log10(Double(abs(self))) + 1) | |
} | |
} | |
// We've accomplised the goal of getting the nth digit (indexed starting from the least-significant digit), but where's the fun in that? If we can index into an Int, why not make it a CollectionType? | |
extension Int: CollectionType { | |
public var startIndex: Int { | |
return 0 | |
} | |
public var endIndex: Int { | |
return numDigits | |
} | |
public subscript(i: Int) -> Int { | |
let p = 10 ** i | |
precondition(abs(self) / p > 0) | |
return (abs(self) / p) % 10 | |
} | |
} | |
let n = 1234 | |
// Now we can use subscripts to get the nth digit starting from the least-significant digit | |
print(n[0]) // prints "4" | |
// Surprisingly, this even works on integer literals | |
print(5678[1]) // prints "7" | |
for d in 987654321 { | |
print(d) | |
} // prints "123456789" | |
// of course we should make sure it handles edge cases | |
print((-5678)[1]) // prints "7" | |
Int.max[4] // prints "7" | |
Int.min[4] // fails due to overflow |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment