#!/usr/bin/ruby
#
## A very basic Fraction() class, implementing a few symbolic relations.
#
class Fraction(num, den) {
method +(Number o) {
self + Fraction(o, 1)
}
method +(Fraction o) {
Fraction(
num*o.den + o.num*den,
den*o.den
)
}
method -(Number o) {
self + -o
}
method -(Fraction o) {
self + -o
}
method *(Number o) {
Fraction(num*o, den)
}
method *(Fraction o) {
Fraction(num*o.num, den*o.den)
}
method /(Number o) {
Fraction(
num,
den * o
)
}
method /(Fraction o) {
Fraction(
num * o.den,
den * o.num,
)
}
method **(Number o) {
if (o < 0) {
var a = o.abs
Fraction(den**a, num**a)
}
else {
Fraction(num**o, den**o)
}
}
method neg {
Fraction(-num, den)
}
method to_s {
"Fraction(#{num}, #{den})"
}
}
class Number {
method +(Fraction o) {
o + self
}
method -(Fraction o) {
-o + self
}
method *(Fraction o) {
o * self
}
method /(Fraction o) {
o**(-1) * self
}
}
var r = 42+Fraction(3,4)
assert_eq(r.num, 171)
assert_eq(r.den, 4)
assert_eq(42 + 3/4, r.num/r.den)
r = 42*Fraction(3, 4)
assert_eq(r.num, 42*3)
assert_eq(r.den, 4)
r = 1/Fraction(3,4)
assert_eq(r.num, 4)
assert_eq(r.den, 3)
r = 12-Fraction(3, 4)
assert_eq(r.num, 45)
assert_eq(r.den, 4)
#
## sum(f(n)) = e, as n->oo.
#
func f((0)) { Fraction(1, 1) }
func f(n) { f(n-1) / n }
assert_eq(f(10).den, 10!)
func num(n) { (-1)**n }
func den(n) { (2*n + 1)**2 }
#
## sum(num(n)/den(n)) = Catalan's constant, as n->oo.
#
var sum
for i in (0 .. 5) {
var f = Fraction(num(i), den(i))
defined(sum) ? (sum += f) : (sum = f)
say sum
}
assert_eq(sum.num, 98607816)
assert_eq(sum.den, 108056025)