Arithmetic/Rational: Difference between revisions

Add Swift
(→‎{{header|Julia}}: Updated for Julia 1.2)
(Add Swift)
Line 4,104:
]
].</lang>
 
=={{header|Swift}}==
 
<lang swift>import Foundation
 
extension BinaryInteger {
@inlinable
public func gcd(with other: Self) -> Self {
var gcd = self
var b = other
 
while b != 0 {
(gcd, b) = (b, gcd % b)
}
 
return gcd
}
 
@inlinable
public func lcm(with other: Self) -> Self {
let g = gcd(with: other)
 
return self / g * other
}
}
 
public struct Frac: Equatable {
fileprivate var _num: Int
fileprivate var _dom: Int
 
fileprivate init(_num: Int, _dom: Int) {
self._num = _num
self._dom = _dom
}
 
public init(numerator: Int, denominator: Int) {
let divisor = numerator.gcd(with: denominator)
 
self._num = numerator / divisor
self._dom = denominator / divisor
}
 
public static func + (lhs: Frac, rhs: Frac) -> Frac {
let multiplier = lhs._dom.lcm(with: rhs.denominator)
 
return Frac(
numerator: lhs._num * multiplier / lhs._dom + rhs._num * multiplier / rhs._dom,
denominator: multiplier
)
}
 
public static func += (lhs: inout Frac, rhs: Frac) {
lhs = lhs + rhs
}
 
public static func - (lhs: Frac, rhs: Frac) -> Frac {
return lhs + -rhs
}
 
public static func -= (lhs: inout Frac, rhs: Frac) {
lhs = lhs + -rhs
}
 
public static func * (lhs: Frac, rhs: Frac) -> Frac {
return Frac(numerator: lhs._num * rhs._num, denominator: lhs._dom * rhs._dom)
}
 
public static func *= (lhs: inout Frac, rhs: Frac) {
lhs = lhs * rhs
}
 
public static func / (lhs: Frac, rhs: Frac) -> Frac {
return lhs * Frac(_num: rhs._dom, _dom: rhs._num)
}
 
public static func /= (lhs: inout Frac, rhs: Frac) {
lhs = lhs / rhs
}
 
prefix static func - (rhs: Frac) -> Frac {
return Frac(_num: -rhs._num, _dom: rhs._dom)
}
}
 
extension Frac {
public var numerator: Int {
get { _num }
set {
let divisor = newValue.gcd(with: denominator)
 
_num = newValue / divisor
_dom = denominator / divisor
}
}
 
public var denominator: Int {
get { _dom }
set {
let divisor = newValue.gcd(with: numerator)
 
_num = numerator / divisor
_dom = newValue / divisor
}
}
}
 
extension Frac: CustomStringConvertible {
public var description: String {
return "Frac(\(numerator) / \(denominator))"
}
}
 
extension Frac: Comparable {
public static func <(lhs: Frac, rhs: Frac) -> Bool {
return lhs._num * rhs._dom < lhs._dom * rhs._num
}
}
 
extension Frac: ExpressibleByIntegerLiteral {
public init(integerLiteral value: Int) {
self._num = value
self._dom = 1
}
}
 
for candidate in 2..<1<<19 {
var sum = Frac(numerator: 1, denominator: candidate)
 
let m = Int(ceil(Double(candidate).squareRoot()))
 
for factor in 2..<m where candidate % factor == 0 {
sum += Frac(numerator: 1, denominator: factor)
sum += Frac(numerator: 1, denominator: candidate / factor)
}
 
if sum == 1 {
print("\(candidate) is perfect")
}
}</lang>
 
{{out}}
 
<pre>6 is perfect
28 is perfect
496 is perfect
8128 is perfect</pre>
 
=={{header|Tcl}}==