Skip to content

Instantly share code, notes, and snippets.

@lanserxt
Last active November 30, 2018 21:39
Show Gist options
  • Save lanserxt/2d08ca8de2ca8f416973741a0cce498a to your computer and use it in GitHub Desktop.
Save lanserxt/2d08ca8de2ca8f416973741a0cce498a to your computer and use it in GitHub Desktop.
class Fraction: ExpressibleByStringLiteral {
private(set) var n: Int
private(set) var d: Int
init(numerator: Int, denominator:Int) {
self.n = numerator
self.d = denominator
}
required public convenience init(stringLiteral string: String) {
if string.contains("/"), string.split(separator: "/").count == 2{
let parts = string.split(separator: "/")
self.init(numerator: Int(parts[0]) ?? 1, denominator: Int(parts[1]) ?? 1)
} else {
self.init(numerator: Int(string) ?? 1, denominator: 1)
}
}
var value: Double {
get { return Double(n) / Double(d) }
}
var isImproper: Bool {
get { return n >= d }
}
var wholePart: Int {
get { return n / d }
}
var mixedPart: Int {
get { return n % d }
}
}
extension Fraction: CustomStringConvertible {
var description: String {
if isImproper {
return mixedPart > 0 ? "\(wholePart) \(mixedPart)/\(d)" : "\(wholePart)"
}
return d == 1 ? "\(n)" : "\(n)/\(d)"
}
}
// 最大公約数
func greatestCommonDenominator(_ first: Int, _ second: Int) -> Int {
return second == 0 ? first : greatestCommonDenominator(second, first % second)
}
func * (left: Fraction, right: Fraction) -> Fraction {
var n = left.n * right.n
var d = left.d * right.d
let g = greatestCommonDenominator(n, d)
n /= g
d /= g
return Fraction(numerator: n, denominator: d)
}
func * (left: Int, right: Fraction) -> Fraction {
return Fraction(numerator: left, denominator: 1) * right
}
func * (left: Fraction, right: Int) -> Fraction {
return left * Fraction(numerator: right, denominator: 1)
}
func / (left: Fraction, right: Fraction) -> Fraction {
var n = left.n * right.d
var d = left.d * right.n
let g = greatestCommonDenominator(n, d)
n /= g
d /= g
return Fraction(numerator: n, denominator: d)
}
func / (left: Int, right: Fraction) -> Fraction {
return Fraction(numerator: left, denominator: 1) / right
}
func / (left: Fraction, right: Int) -> Fraction {
return left / Fraction(numerator: right, denominator: 1)
}
func + (left: Fraction, right: Fraction) -> Fraction {
var n = left.n * right.d + right.n * left.d
var d = left.d * right.d
let g = greatestCommonDenominator(n, d)
n /= g
d /= g
return Fraction(numerator: n, denominator: d)
}
func + (left: Int, right: Fraction) -> Fraction {
return Fraction(numerator: left, denominator: 1) + right
}
func + (left: Fraction, right: Int) -> Fraction {
return left + Fraction(numerator: right, denominator: 1)
}
func - (left: Fraction, right: Fraction) -> Fraction {
var n = left.n * right.d - right.n * left.d
var d = left.d * right.d
let g = greatestCommonDenominator(n, d)
n /= g
d /= g
return Fraction(numerator: n, denominator: d)
}
func - (left: Int, right: Fraction) -> Fraction {
return Fraction(numerator: left, denominator: 1) - right
}
func - (left: Fraction, right: Int) -> Fraction {
return left - Fraction(numerator: right, denominator: 1)
}
let f1: Fraction = "3/4"
let f2 = Fraction(numerator: 1, denominator: 4)
print(f1 + f2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment