Skip to content

Instantly share code, notes, and snippets.

@AK-10
Created October 18, 2019 21:01
Show Gist options
  • Save AK-10/98e9108b61084c5c3ccc1001b2bf02b1 to your computer and use it in GitHub Desktop.
Save AK-10/98e9108b61084c5c3ccc1001b2bf02b1 to your computer and use it in GitHub Desktop.
分数型
import Foundation
struct Fractional: CustomStringConvertible, Equatable {
let value: (Int, Int)
var num: Int {
return value.0
}
var den: Int {
return value.1
}
var description: String {
return "\(num)/\(den)"
}
var reciprocal: Self {
return Fractional(den, num)
}
init(_ fraction: Int, _ denominator: Int) {
if denominator == 0 {
fatalError("zero denominator")
}
let isNegative = fraction * denominator < 0
let absFraction = abs(fraction)
let absDenominator = abs(denominator)
let gcd = Self.gcd(absDenominator, absFraction)
value = isNegative
? (-(absFraction/gcd), (absDenominator/gcd))
: ((absFraction/gcd), (absDenominator/gcd))
}
static func == (lhs: Fractional, rhs: Fractional) -> Bool {
let eqNum = lhs.num == rhs.num
let eqDen = rhs.den == rhs.den
return eqNum && eqDen
}
static func + (lhs: Self, rhs: Self) -> Self {
let denominator = Self.lcm(lhs.den, rhs.den)
let lFraction = lhs.num * (denominator / lhs.den)
let rFraction = rhs.num * (denominator / rhs.den)
return Fractional(lFraction + rFraction, denominator)
}
static func - (lhs: Self, rhs: Self) -> Self {
let denominator = Self.lcm(lhs.den, rhs.den)
let lFraction = lhs.num * (denominator / lhs.den)
let rFraction = rhs.num * (denominator / rhs.den)
return Fractional(lFraction - rFraction, denominator)
}
static func * (lhs: Self, rhs: Self) -> Self {
let numeric = lhs.num * rhs.num
let denominator = lhs.den * rhs.den
return Fractional(numeric, denominator)
}
static func / (lhs: Self, rhs: Self) -> Self {
return lhs * rhs.reciprocal
}
static private func gcd(_ x: Int, _ y: Int) -> Int {
// Euclidean Algorithm
if y > x {
return gcd(y, x)
}
return y != 0 ? gcd(y, x % y) : x
}
static private func lcm(_ x: Int, _ y: Int) -> Int {
// x*y = gcd(x, y) * lcm(x * y)
return x * y / gcd(x, y)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment