Skip to content

Instantly share code, notes, and snippets.

@kristopherjohnson
Created July 29, 2014 03:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristopherjohnson/eb7dc5b6af06eb42ef38 to your computer and use it in GitHub Desktop.
Save kristopherjohnson/eb7dc5b6af06eb42ef38 to your computer and use it in GitHub Desktop.
A Swift translation of the Rational type from Chapter 6 of "Programming in Scala, 2nd Edition" by Martin Odersky, Lex Spoon, and Bill Venners
// Based upon Chapter 6 of Programming in Scala, Second Edition, by Martin Odersky, Lex Spoon, and Bill Venners
public struct Rational {
public let numer: Int
public let denom: Int
public init(_ numerator: Int, _ denominator: Int = 1) {
assert(denominator != 0)
let g = Rational.gcd(abs(numerator), abs(denominator))
numer = numerator / g
denom = denominator / g
}
private static func gcd(a: Int, _ b: Int) -> Int {
return b == 0 ? a : gcd(b, a % b)
}
}
extension Rational: Printable {
public var description: String { return "\(numer)/\(denom)" }
}
func + (lhs: Rational, rhs: Rational) -> Rational {
return Rational(
lhs.numer * rhs.denom + rhs.numer * lhs.denom,
lhs.denom * rhs.denom
)
}
func + (lhs: Rational, rhs: Int) -> Rational {
return lhs + Rational(rhs)
}
func + (lhs: Int, rhs: Rational) -> Rational {
return Rational(lhs) + rhs
}
func - (lhs: Rational, rhs: Rational) -> Rational {
return Rational(
lhs.numer * rhs.denom - rhs.numer * lhs.denom,
lhs.denom * rhs.denom
)
}
func - (lhs: Rational, rhs: Int) -> Rational {
return lhs - Rational(rhs)
}
func - (lhs: Int, rhs: Rational) -> Rational {
return Rational(lhs) - rhs
}
func * (lhs: Rational, rhs: Rational) -> Rational {
return Rational(
lhs.numer * rhs.numer,
lhs.denom * rhs.denom
)
}
func * (lhs: Rational, rhs: Int) -> Rational {
return lhs * Rational(rhs)
}
func * (lhs: Int, rhs: Rational) -> Rational {
return Rational(lhs) * rhs
}
func / (lhs: Rational, rhs: Rational) -> Rational {
return Rational(
lhs.numer * rhs.denom,
lhs.denom * rhs.numer
)
}
func / (lhs: Rational, rhs: Int) -> Rational {
return lhs / Rational(rhs)
}
func / (lhs: Int, rhs: Rational) -> Rational {
return Rational(lhs) / rhs
}
func < (lhs: Rational, rhs: Rational) -> Bool {
return lhs.numer * rhs.denom < rhs.numer * lhs.denom
}
// Examples
let oneHalf = Rational(1, 2)
oneHalf.description // "1/2"
let twoThirds = Rational(2, 3)
twoThirds.description // "2/3"
let sum = oneHalf + twoThirds
sum.description // "7/6"
let product = oneHalf * twoThirds
product.description // "1/3"
let expr = oneHalf + oneHalf * twoThirds
expr.description // "5/6"
let y = Rational(3)
y.description // "3/1"
let frac = Rational(66, 42)
frac.description // "11/7"
let sumInt = oneHalf + 1
sumInt.description // "3/2"
let neg = Rational(1, -2)
neg.description // "1/-2"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment