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