Last active
November 30, 2018 21:39
-
-
Save lanserxt/2d08ca8de2ca8f416973741a0cce498a to your computer and use it in GitHub Desktop.
Fraction extension of https://gist.github.com/takatoshi/29e1c50919e62ac19886 by @takatoshi
This file contains hidden or 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
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