Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,11 +1,11 @@
|
|||
import std.bigint, std.traits, std.conv;
|
||||
|
||||
// std.numeric.gcd doesn't work with BigInt.
|
||||
T gcd(T)(in T a, in T b) pure /*nothrow*/ {
|
||||
T gcd(T)(in T a, in T b) pure nothrow {
|
||||
return (b != 0) ? gcd(b, a % b) : (a < 0) ? -a : a;
|
||||
}
|
||||
|
||||
T lcm(T)(in T a, in T b) pure /*nothrow*/ {
|
||||
T lcm(T)(in T a, in T b) pure nothrow {
|
||||
return a / gcd(a, b) * b;
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ struct RationalT(T) if (!isUnsigned!T) {
|
|||
den = 1UL;
|
||||
}
|
||||
|
||||
this(U, V)(in U n, in V d) pure /*nothrow*/ {
|
||||
this(U, V)(in U n, in V d) pure nothrow {
|
||||
num = toT(n);
|
||||
den = toT(d);
|
||||
const common = gcd(num, den);
|
||||
|
|
@ -71,7 +71,7 @@ struct RationalT(T) if (!isUnsigned!T) {
|
|||
return ((num < 0) ? "-" : "+") ~ "infRat";
|
||||
}
|
||||
|
||||
real toReal() pure const /*nothrow*/ {
|
||||
real toReal() pure const nothrow {
|
||||
static if (is(T == BigInt))
|
||||
return num.toLong / real(den.toLong);
|
||||
else
|
||||
|
|
@ -79,7 +79,7 @@ struct RationalT(T) if (!isUnsigned!T) {
|
|||
}
|
||||
|
||||
RationalT opBinary(string op)(in RationalT r)
|
||||
const pure /*nothrow*/ if (op == "+" || op == "-") {
|
||||
const pure nothrow if (op == "+" || op == "-") {
|
||||
T common = lcm(den, r.den);
|
||||
T n = mixin("common / den * num" ~ op ~
|
||||
"common / r.den * r.num" );
|
||||
|
|
@ -87,28 +87,28 @@ struct RationalT(T) if (!isUnsigned!T) {
|
|||
}
|
||||
|
||||
RationalT opBinary(string op)(in RationalT r)
|
||||
const pure /*nothrow*/ if (op == "*") {
|
||||
const pure nothrow if (op == "*") {
|
||||
return RationalT(num * r.num, den * r.den);
|
||||
}
|
||||
|
||||
RationalT opBinary(string op)(in RationalT r)
|
||||
const pure /*nothrow*/ if (op == "/") {
|
||||
const pure nothrow if (op == "/") {
|
||||
return RationalT(num * r.den, den * r.num);
|
||||
}
|
||||
|
||||
RationalT opBinary(string op, U)(in U r)
|
||||
const pure /*nothrow*/ if (isIntegral!U && (op == "+" ||
|
||||
const pure nothrow if (isIntegral!U && (op == "+" ||
|
||||
op == "-" || op == "*" || op == "/")) {
|
||||
return opBinary!op(RationalT(r));
|
||||
}
|
||||
|
||||
RationalT opBinary(string op)(in size_t p)
|
||||
const pure /*nothrow*/ if (op == "^^") {
|
||||
const pure nothrow if (op == "^^") {
|
||||
return RationalT(num ^^ p, den ^^ p);
|
||||
}
|
||||
|
||||
RationalT opBinaryRight(string op, U)(in U l)
|
||||
const pure /*nothrow*/ if (isIntegral!U) {
|
||||
const pure nothrow if (isIntegral!U) {
|
||||
return RationalT(l).opBinary!op(RationalT(num, den));
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ struct RationalT(T) if (!isUnsigned!T) {
|
|||
}
|
||||
|
||||
RationalT opUnary(string op)()
|
||||
const pure /*nothrow*/ if (op == "+" || op == "-") {
|
||||
const pure nothrow if (op == "+" || op == "-") {
|
||||
return RationalT(mixin(op ~ "num"), den);
|
||||
}
|
||||
|
||||
|
|
@ -133,10 +133,10 @@ struct RationalT(T) if (!isUnsigned!T) {
|
|||
return num == rhs.num && den == rhs.den;
|
||||
}
|
||||
|
||||
int opCmp(U)(in U r) const pure {
|
||||
int opCmp(U)(in U r) const pure nothrow {
|
||||
auto rhs = RationalT(r);
|
||||
if (type() == Type.NaRAT || rhs.type() == Type.NaRAT)
|
||||
throw new Exception("Compare involve a NaRAT.");
|
||||
throw new Error("Compare involve a NaRAT.");
|
||||
if (type() != Type.NORMAL ||
|
||||
rhs.type() != Type.NORMAL) // for infinite
|
||||
return (type() == rhs.type()) ? 0 :
|
||||
|
|
@ -154,12 +154,12 @@ struct RationalT(T) if (!isUnsigned!T) {
|
|||
}
|
||||
}
|
||||
|
||||
RationalT!U rational(U)(in U n) pure /*nothrow*/ {
|
||||
RationalT!U rational(U)(in U n) pure nothrow {
|
||||
return typeof(return)(n);
|
||||
}
|
||||
|
||||
RationalT!(CommonType!(U1, U2))
|
||||
rational(U1, U2)(in U1 n, in U2 d) pure /*nothrow*/ {
|
||||
rational(U1, U2)(in U1 n, in U2 d) pure nothrow {
|
||||
return typeof(return)(n, d);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,113 +1,102 @@
|
|||
class Rational implements Comparable {
|
||||
final BigInteger numerator, denominator
|
||||
final BigInteger num, denom
|
||||
|
||||
static final Rational ONE = new Rational(1, 1)
|
||||
|
||||
static final Rational ZERO = new Rational(0, 1)
|
||||
|
||||
Rational(BigInteger whole) { this(whole, 1) }
|
||||
static final Rational ONE = new Rational(1)
|
||||
static final Rational ZERO = new Rational(0)
|
||||
|
||||
Rational(BigDecimal decimal) {
|
||||
this(
|
||||
decimal.scale() < 0 ? decimal.unscaledValue()*10**(-decimal.scale()) : decimal.unscaledValue(),
|
||||
decimal.scale() < 0 ? 1 : 10**(decimal.scale())
|
||||
)
|
||||
decimal.scale() < 0 ? decimal.unscaledValue()*10**(-decimal.scale()) : decimal.unscaledValue(),
|
||||
decimal.scale() < 0 ? 1 : 10**(decimal.scale()))
|
||||
}
|
||||
|
||||
Rational(num, denom) {
|
||||
assert denom != 0 : "Denominator must not be 0"
|
||||
def values = denom > 0 ? [num, denom] : [-num, -denom] //reduce(num, denom)
|
||||
|
||||
numerator = values[0]
|
||||
denominator = values[1]
|
||||
Rational(BigInteger n, BigInteger d = 1) {
|
||||
if (!d || n == null) { n/d }
|
||||
(num, denom) = reduce(n, d)
|
||||
}
|
||||
|
||||
private List reduce(BigInteger num, BigInteger denom) {
|
||||
BigInteger sign = ((num < 0) != (denom < 0)) ? -1 : 1
|
||||
num = num.abs()
|
||||
denom = denom.abs()
|
||||
BigInteger commonFactor = gcd(num, denom)
|
||||
private List reduce(BigInteger n, BigInteger d) {
|
||||
BigInteger sign = ((n < 0) != (d < 0)) ? -1 : 1
|
||||
(n, d) = [n.abs(), d.abs()]
|
||||
BigInteger commonFactor = gcd(n, d)
|
||||
|
||||
[num.intdiv(commonFactor) * sign, denom.intdiv(commonFactor)]
|
||||
[n.intdiv(commonFactor) * sign, d.intdiv(commonFactor)]
|
||||
}
|
||||
|
||||
public Rational toLeastTerms() {
|
||||
def reduced = reduce(numerator, denominator)
|
||||
new Rational(reduced[0], reduced[1])
|
||||
public Rational toLeastTerms() { reduce(num, denom) as Rational }
|
||||
|
||||
private BigInteger gcd(BigInteger n, BigInteger m) {
|
||||
n == 0 ? m : { while(m%n != 0) { (n, m) = [m%n, n] }; n }()
|
||||
}
|
||||
|
||||
private BigInteger gcd(BigInteger n, BigInteger m) { n == 0 ? m : { while(m%n != 0) { def t=n; n=m%n; m=t }; n }() }
|
||||
Rational plus(Rational r) { [num*r.denom + r.num*denom, denom*r.denom] }
|
||||
Rational plus(BigInteger n) { [num + n*denom, denom] }
|
||||
Rational plus(Number n) { this + ([n] as Rational) }
|
||||
|
||||
Rational plus (Rational r) { new Rational(numerator*r.denominator + r.numerator*denominator, denominator*r.denominator) }
|
||||
Rational next() { [num + denom, denom] }
|
||||
|
||||
Rational plus (BigInteger n) { new Rational(numerator + n*denominator, denominator) }
|
||||
Rational minus(Rational r) { [num*r.denom - r.num*denom, denom*r.denom] }
|
||||
Rational minus(BigInteger n) { [num - n*denom, denom] }
|
||||
Rational minus(Number n) { this - ([n] as Rational) }
|
||||
|
||||
Rational next () { new Rational(numerator + denominator, denominator) }
|
||||
Rational previous() { [num - denom, denom] }
|
||||
|
||||
Rational minus (Rational r) { new Rational(numerator*r.denominator - r.numerator*denominator, denominator*r.denominator) }
|
||||
Rational multiply(Rational r) { [num*r.num, denom*r.denom] }
|
||||
Rational multiply(BigInteger n) { [num*n, denom] }
|
||||
Rational multiply(Number n) { this * ([n] as Rational) }
|
||||
|
||||
Rational minus (BigInteger n) { new Rational(numerator - n*denominator, denominator) }
|
||||
|
||||
Rational previous () { new Rational(numerator - denominator, denominator) }
|
||||
Rational div(Rational r) { new Rational(num*r.denom, denom*r.num) }
|
||||
Rational div(BigInteger n) { new Rational(num, denom*n) }
|
||||
Rational div(Number n) { this / ([n] as Rational) }
|
||||
|
||||
Rational multiply (Rational r) { new Rational(numerator*r.numerator, denominator*r.denominator) }
|
||||
BigInteger intdiv(BigInteger n) { num.intdiv(denom*n) }
|
||||
|
||||
Rational multiply (BigInteger n) { new Rational(numerator*n, denominator) }
|
||||
Rational negative() { [-num, denom] }
|
||||
|
||||
Rational div (Rational r) { new Rational(numerator*r.denominator, denominator*r.numerator) }
|
||||
Rational abs() { [num.abs(), denom] }
|
||||
|
||||
Rational div (BigInteger n) { new Rational(numerator, denominator*n) }
|
||||
Rational reciprocal() { new Rational(denom, num) }
|
||||
|
||||
BigInteger intdiv (BigInteger n) { numerator.intdiv(denominator*n) }
|
||||
Rational power(BigInteger n) {
|
||||
def (nu, de) = (n < 0 ? [denom, num] : [num, denom])*.power(n.abs())
|
||||
new Rational (nu, de)
|
||||
}
|
||||
|
||||
Rational negative () { new Rational(-numerator, denominator) }
|
||||
boolean asBoolean() { num != 0 }
|
||||
|
||||
Rational abs () { new Rational(numerator.abs(), denominator) }
|
||||
BigDecimal toBigDecimal() { (num as BigDecimal)/(denom as BigDecimal) }
|
||||
|
||||
Rational reciprocal() { new Rational(denominator, numerator) }
|
||||
|
||||
Rational power(BigInteger n) { new Rational(numerator ** n, denominator ** n) }
|
||||
|
||||
boolean asBoolean() { numerator != 0 }
|
||||
|
||||
BigDecimal toBigDecimal() { (numerator as BigDecimal)/(denominator as BigDecimal) }
|
||||
|
||||
BigInteger toBigInteger() { numerator.intdiv(denominator) }
|
||||
BigInteger toBigInteger() { num.intdiv(denom) }
|
||||
|
||||
Double toDouble() { toBigDecimal().toDouble() }
|
||||
|
||||
double doubleValue() { toDouble() as double }
|
||||
|
||||
Float toFloat() { toBigDecimal().toFloat() }
|
||||
|
||||
float floatValue() { toFloat() as float }
|
||||
|
||||
Integer toInteger() { toBigInteger().toInteger() }
|
||||
|
||||
int intValue() { toInteger() as int }
|
||||
|
||||
Long toLong() { toBigInteger().toLong() }
|
||||
|
||||
long longValue() { toLong() as long }
|
||||
|
||||
Object asType(Class type) {
|
||||
switch (type) {
|
||||
case this.getClass(): return this
|
||||
case Boolean.class: return asBoolean()
|
||||
case BigDecimal.class: return toBigDecimal()
|
||||
case BigInteger.class: return toBigInteger()
|
||||
case Double.class: return toDouble()
|
||||
case Float.class: return toFloat()
|
||||
case Integer.class: return toInteger()
|
||||
case Long.class: return toLong()
|
||||
case String.class: return toString()
|
||||
default: throw new ClassCastException("Cannot convert from type Rational to type " + type)
|
||||
case this.getClass(): return this
|
||||
case [Boolean.class,Boolean.TYPE]: return asBoolean()
|
||||
case BigDecimal.class: return toBigDecimal()
|
||||
case BigInteger.class: return toBigInteger()
|
||||
case [Double.class,Double.TYPE]: return toDouble()
|
||||
case [Float.class,Float.TYPE]: return toFloat()
|
||||
case [Integer.class,Integer.TYPE]: return toInteger()
|
||||
case [Long.class,Long.TYPE]: return toLong()
|
||||
case String.class: return toString()
|
||||
default: throw new ClassCastException("Cannot convert from type Rational to type " + type)
|
||||
}
|
||||
}
|
||||
|
||||
boolean equals(o) {
|
||||
compareTo(o) == 0
|
||||
}
|
||||
boolean equals(o) { compareTo(o) == 0 }
|
||||
|
||||
int compareTo(o) {
|
||||
o instanceof Rational \
|
||||
|
|
@ -116,15 +105,12 @@ class Rational implements Comparable {
|
|||
? compareTo(o as Number)\
|
||||
: (Double.NaN as int)
|
||||
}
|
||||
int compareTo(Rational r) { num*r.denom <=> denom*r.num }
|
||||
int compareTo(Number n) { num <=> denom*(n as BigInteger) }
|
||||
|
||||
int compareTo(Rational r) { numerator*r.denominator <=> denominator*r.numerator }
|
||||
|
||||
int compareTo(Number n) { numerator <=> denominator*(n as BigInteger) }
|
||||
|
||||
int hashCode() { [numerator, denominator].hashCode() }
|
||||
int hashCode() { [num, denom].hashCode() }
|
||||
|
||||
String toString() {
|
||||
def reduced = reduce(numerator, denominator)
|
||||
"${reduced[0]}//${reduced[1]}"
|
||||
"${num}//${denom}"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,14 @@
|
|||
def x = new Rational(5, 20)
|
||||
def y = new Rational(9, 12)
|
||||
def z = new Rational(0, 10000)
|
||||
import org.codehaus.groovy.runtime.DefaultGroovyMethods
|
||||
|
||||
println x
|
||||
println y
|
||||
println z
|
||||
println (x <=> y)
|
||||
println ((x as Rational).compareTo(y))
|
||||
assert x*3 == y
|
||||
assert (z + 1) <= y*4
|
||||
assert x != y
|
||||
class RationalCategory {
|
||||
static Rational plus (Number a, Rational b) { ([a] as Rational) + b }
|
||||
static Rational minus (Number a, Rational b) { ([a] as Rational) - b }
|
||||
static Rational multiply (Number a, Rational b) { ([a] as Rational) * b }
|
||||
static Rational div (Number a, Rational b) { ([a] as Rational) / b }
|
||||
|
||||
println "x + y == ${x} + ${y} == ${x + y}"
|
||||
println "x + z == ${x} + ${z} == ${x + z}"
|
||||
println "x - y == ${x} - ${y} == ${x - y}"
|
||||
println "x - z == ${x} - ${z} == ${x - z}"
|
||||
println "x * y == ${x} * ${y} == ${x * y}"
|
||||
println "y ** 3 == ${y} ** 3 == ${y ** 3}"
|
||||
println "x * z == ${x} * ${z} == ${x * z}"
|
||||
println "x / y == ${x} / ${y} == ${x / y}"
|
||||
try { print "x / z == ${x} / ${z} == "; println "${x / z}" }
|
||||
catch (Throwable t) { println t.message }
|
||||
|
||||
println "-x == -${x} == ${-x}"
|
||||
println "-y == -${y} == ${-y}"
|
||||
println "-z == -${z} == ${-z}"
|
||||
|
||||
print "x as int == ${x} as int == "; println x.intValue()
|
||||
print "x as double == ${x} as double == "; println x.doubleValue()
|
||||
print "1 / x as int == 1 / ${x} as int == "; println x.reciprocal().intValue()
|
||||
print "1.0 / x == 1.0 / ${x} == "; println x.reciprocal().doubleValue()
|
||||
print "y as int == ${y} as int == "; println y.intValue()
|
||||
print "y as double == ${y} as double == "; println y.doubleValue()
|
||||
print "1 / y as int == 1 / ${y} as int == "; println y.reciprocal().intValue()
|
||||
print "1.0 / y == 1.0 / ${y} == "; println y.reciprocal().doubleValue()
|
||||
print "z as int == ${z} as int == "; println z.intValue()
|
||||
print "z as double == ${z} as double == "; println z.doubleValue()
|
||||
try { print "1 / z as int == 1 / ${z} as int == "; println z.reciprocal().intValue() }
|
||||
catch (Throwable t) { println t.message }
|
||||
try { print "1.0 / z == 1.0 / ${z} == "; println z.reciprocal().doubleValue() }
|
||||
catch (Throwable t) { println t.message }
|
||||
|
||||
println "++x == ++ ${x} == ${++x}"
|
||||
println "++y == ++ ${y} == ${++y}"
|
||||
println "++z == ++ ${z} == ${++z}"
|
||||
println "-- --x == -- -- ${x} == ${-- (--x)}"
|
||||
println "-- --y == -- -- ${y} == ${-- (--y)}"
|
||||
println "-- --z == -- -- ${z} == ${-- (--z)}"
|
||||
println x
|
||||
println y
|
||||
println z
|
||||
|
||||
println (x <=> y)
|
||||
assert x*3 == y
|
||||
assert (z + 1) <= y*4
|
||||
assert (x < y)
|
||||
|
||||
println (new Rational(25))
|
||||
println (new Rational(25.0))
|
||||
println (new Rational(0.25))
|
||||
|
||||
println Math.PI
|
||||
println (new Rational(Math.PI))
|
||||
println ((new Rational(Math.PI)).toBigDecimal())
|
||||
println ((new Rational(Math.PI)) as BigDecimal)
|
||||
println ((new Rational(Math.PI)) as Double)
|
||||
println ((new Rational(Math.PI)) as double)
|
||||
println ((new Rational(Math.PI)) as boolean)
|
||||
println (z as boolean)
|
||||
try { println ((new Rational(Math.PI)) as Date) }
|
||||
catch (Throwable t) { println t.message }
|
||||
try { println ((new Rational(Math.PI)) as char) }
|
||||
catch (Throwable t) { println t.message }
|
||||
static <T> T asType (Number a, Class<T> type) {
|
||||
type == Rational \
|
||||
? [a] as Rational
|
||||
: DefaultGroovyMethods.asType(a, type)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,87 @@
|
|||
def factorize = { target ->
|
||||
if (target == 1L) {
|
||||
return [1L]
|
||||
} else if ([2L, 3L].contains(target)) {
|
||||
return [1L, target]
|
||||
}
|
||||
def targetSqrt = Math.ceil(Math.sqrt(target)) as long
|
||||
def lowfactors = (2L..(targetSqrt)).findAll { (target % it) == 0 }
|
||||
Number.metaClass.mixin RationalCategory
|
||||
|
||||
if (lowfactors.isEmpty()) {
|
||||
return [1L, target]
|
||||
}
|
||||
def x = [5, 20] as Rational
|
||||
def y = [9, 12] as Rational
|
||||
def z = [0, 10000] as Rational
|
||||
|
||||
def nhalf = lowfactors.size() - ((lowfactors[-1] == targetSqrt) ? 1 : 0)
|
||||
println x
|
||||
println y
|
||||
println z
|
||||
println (x <=> y)
|
||||
println (x.compareTo(y))
|
||||
assert x < y
|
||||
assert x*3 == y
|
||||
assert x*5.5 == 5.5*x
|
||||
assert (z + 1) <= y*4
|
||||
assert x + 1.3 == 1.3 + x
|
||||
assert 24 - y == -(y - 24)
|
||||
assert 3 / y == (y / 3).reciprocal()
|
||||
assert x != y
|
||||
|
||||
return ([1L] + lowfactors + ((nhalf-1)..0).collect { target.intdiv(lowfactors[it]) } + [target]).unique()
|
||||
}
|
||||
println "x + y == ${x} + ${y} == ${x + y}"
|
||||
println "x + z == ${x} + ${z} == ${x + z}"
|
||||
println "x - y == ${x} - ${y} == ${x - y}"
|
||||
println "x - z == ${x} - ${z} == ${x - z}"
|
||||
println "x * y == ${x} * ${y} == ${x * y}"
|
||||
println "y ** 3 == ${y} ** 3 == ${y ** 3}"
|
||||
println "y ** -3 == ${y} ** -3 == ${y ** -3}"
|
||||
println "x * z == ${x} * ${z} == ${x * z}"
|
||||
println "x / y == ${x} / ${y} == ${x / y}"
|
||||
try { print "x / z == ${x} / ${z} == "; println "${x / z}" }
|
||||
catch (Throwable t) { println t.message }
|
||||
|
||||
1.upto(2**19) {
|
||||
if ((it % 100000) == 0) { println "HT" }
|
||||
else if ((it % 1000) == 0) { print "." }
|
||||
println "-x == -${x} == ${-x}"
|
||||
println "-y == -${y} == ${-y}"
|
||||
println "-z == -${z} == ${-z}"
|
||||
|
||||
def factors = factorize(it)
|
||||
def isPerfect = factors.collect{ factor -> new Rational( factor ).reciprocal() }.sum() == new Rational(2)
|
||||
if (isPerfect) { println() ; println ([perfect: it, factors: factors]) }
|
||||
}
|
||||
print "x as int == ${x} as int == "; println x.intValue()
|
||||
print "x as double == ${x} as double == "; println x.doubleValue()
|
||||
print "1 / x as int == 1 / ${x} as int == "; println x.reciprocal().intValue()
|
||||
print "1.0 / x == 1.0 / ${x} == "; println x.reciprocal().doubleValue()
|
||||
print "y as int == ${y} as int == "; println y.intValue()
|
||||
print "y as double == ${y} as double == "; println y.doubleValue()
|
||||
print "1 / y as int == 1 / ${y} as int == "; println y.reciprocal().intValue()
|
||||
print "1.0 / y == 1.0 / ${y} == "; println y.reciprocal().doubleValue()
|
||||
print "z as int == ${z} as int == "; println z.intValue()
|
||||
print "z as double == ${z} as double == "; println z.doubleValue()
|
||||
try { print "1 / z as int == 1 / ${z} as int == "; println z.reciprocal().intValue() }
|
||||
catch (Throwable t) { println t.message }
|
||||
try { print "1.0 / z == 1.0 / ${z} == "; println z.reciprocal().doubleValue() }
|
||||
catch (Throwable t) { println t.message }
|
||||
|
||||
println "++x == ++ ${x} == ${++x}"
|
||||
println "++y == ++ ${y} == ${++y}"
|
||||
println "++z == ++ ${z} == ${++z}"
|
||||
println "-- --x == -- -- ${x} == ${-- (--x)}"
|
||||
println "-- --y == -- -- ${y} == ${-- (--y)}"
|
||||
println "-- --z == -- -- ${z} == ${-- (--z)}"
|
||||
println x
|
||||
println y
|
||||
println z
|
||||
|
||||
println (x <=> y)
|
||||
assert x*3 == y
|
||||
assert (z + 1) <= y*4
|
||||
assert (x < y)
|
||||
|
||||
println 25 as Rational
|
||||
println 25.0 as Rational
|
||||
println 0.25 as Rational
|
||||
|
||||
def ε = 0.000000001 // tolerance (epsilon): acceptable "wrongness" to account for rounding error
|
||||
|
||||
def π = Math.PI
|
||||
def α = π as Rational
|
||||
assert (π - (α as BigDecimal)).abs() < ε
|
||||
println π
|
||||
println α
|
||||
println (α.toBigDecimal())
|
||||
println (α as BigDecimal)
|
||||
println (α as Double)
|
||||
println (α as double)
|
||||
println (α as boolean)
|
||||
println (z as boolean)
|
||||
try { println (α as Date) }
|
||||
catch (Throwable t) { println t.message }
|
||||
try { println (α as char) }
|
||||
catch (Throwable t) { println t.message }
|
||||
|
|
|
|||
25
Task/Arithmetic-Rational/Groovy/arithmetic-rational-4.groovy
Normal file
25
Task/Arithmetic-Rational/Groovy/arithmetic-rational-4.groovy
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Number.metaClass.mixin RationalCategory
|
||||
|
||||
def factorize = { target ->
|
||||
assert target > 0
|
||||
if (target == 1L) { return [1L] }
|
||||
if ([2L, 3L].contains(target)) { return [1L, target] }
|
||||
def targetSqrt = Math.sqrt(target)
|
||||
def lowFactors = (2L..targetSqrt).findAll { (target % it) == 0 }
|
||||
|
||||
if (!lowFactors) { return [1L, target] }
|
||||
def highFactors = lowFactors[-1..0].findResults { target.intdiv(it) } - lowFactors[-1]
|
||||
|
||||
return [1L] + lowFactors + highFactors + [target]
|
||||
}
|
||||
|
||||
def perfect = {
|
||||
def factors = factorize(it)
|
||||
2 as Rational == factors.sum{ factor -> new Rational(1, factor) } \
|
||||
? [perfect: it, factors: factors]
|
||||
: null
|
||||
}
|
||||
|
||||
def trackProgress = { if ((it % (100*1000)) == 0) { println it } else if ((it % 1000) == 0) { print "." } }
|
||||
|
||||
(1..(2**19)).findResults { trackProgress(it); perfect(it) }.each { println(); print it }
|
||||
246
Task/Arithmetic-Rational/PL-I/arithmetic-rational.pli
Normal file
246
Task/Arithmetic-Rational/PL-I/arithmetic-rational.pli
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
*process source attributes xref or(!);
|
||||
arat: Proc Options(main);
|
||||
/*--------------------------------------------------------------------
|
||||
* Rational Arithmetic
|
||||
* (Mis)use the Complex data type to represent fractions
|
||||
* real(x) is used as numerator
|
||||
* imag(x) is used as denominator
|
||||
* Output:
|
||||
* a=-3/7 b=9/2
|
||||
* a*b=-27/14
|
||||
* a+b=57/14
|
||||
* a-b=-69/14
|
||||
* a/b=-2/21
|
||||
* -3/7<9/2
|
||||
* 9/2>-3/7
|
||||
* -3/7=-3/7
|
||||
* 26.01.2015 handle 0/0
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (abs,imag,mod,real,sign,trim) Builtin;
|
||||
Dcl sysprint Print;
|
||||
Dcl (candidate,max2,factor) Dec Fixed(15);
|
||||
Dcl sum complex Dec Fixed(15);
|
||||
Dcl one complex Dec Fixed(15);
|
||||
|
||||
one=mk_fr(1,1);
|
||||
Put Edit('First solve the task at hand')(Skip,a);
|
||||
Do candidate = 2 to 10000;
|
||||
sum = mk_fr(1, candidate);
|
||||
max2 = sqrt(candidate);
|
||||
Do factor = 2 to max2;
|
||||
If mod(candidate,factor)=0 Then Do;
|
||||
sum=fr_add(sum,mk_fr(1,factor));
|
||||
sum=fr_add(sum,mk_fr(1,candidate/factor));
|
||||
End;
|
||||
End;
|
||||
If fr_cmp(sum,one)='=' Then Do;
|
||||
Put Edit(candidate,' is a perfect number')(Skip,f(7),a);
|
||||
Do factor = 2 to candidate-1;
|
||||
If mod(candidate,factor)=0 Then
|
||||
Put Edit(factor)(f(5));
|
||||
End;
|
||||
End;
|
||||
End;
|
||||
|
||||
Put Edit('','Then try a few things')(Skip,a);
|
||||
Dcl a Complex Dec Fixed(15);
|
||||
Dcl b Complex Dec Fixed(15);
|
||||
Dcl p Complex Dec Fixed(15);
|
||||
Dcl s Complex Dec Fixed(15);
|
||||
Dcl d Complex Dec Fixed(15);
|
||||
Dcl q Complex Dec Fixed(15);
|
||||
Dcl zero Complex Dec Fixed(15);
|
||||
zero=mk_fr(0,1); Put Edit('zero=',fr_rep(zero))(Skip,2(a));
|
||||
a=mk_fr(0,0); Put Edit('a=',fr_rep(a))(Skip,2(a));
|
||||
/*--------------------------------------------------------------------
|
||||
a=mk_fr(-3333,0); Put Edit('a=',fr_rep(a))(Skip,2(a));
|
||||
=> Request mk_fr(-3333,0)
|
||||
Denominator must not be 0
|
||||
IBM0280I ONCODE=0009 The ERROR condition was raised
|
||||
by a SIGNAL statement.
|
||||
At offset +00000276 in procedure with entry FT
|
||||
*-------------------------------------------------------------------*/
|
||||
a=mk_fr(0,3333); Put Edit('a=',fr_rep(a))(Skip,2(a));
|
||||
Put Edit('-3,7')(Skip,a);
|
||||
a=mk_fr(-3,7);
|
||||
b=mk_fr(9,2);
|
||||
p=fr_mult(a,b);
|
||||
s=fr_add(a,b);
|
||||
d=fr_sub(a,b);
|
||||
q=fr_div(a,b);
|
||||
r=fr_div(b,a);
|
||||
Put Edit('a=',fr_rep(a))(Skip,2(a));
|
||||
Put Edit('b=',fr_rep(b))(Skip,2(a));
|
||||
Put Edit('a*b=',fr_rep(p))(Skip,2(a));
|
||||
Put Edit('a+b=',fr_rep(s))(Skip,2(a));
|
||||
Put Edit('a-b=',fr_rep(d))(Skip,2(a));
|
||||
Put Edit('a/b=',fr_rep(q))(Skip,2(a));
|
||||
Put Edit('b/a=',fr_rep(r))(Skip,2(a));
|
||||
Put Edit(fr_rep(a),fr_cmp(a,b),fr_rep(b))(Skip,3(a));
|
||||
Put Edit(fr_rep(b),fr_cmp(b,a),fr_rep(a))(Skip,3(a));
|
||||
Put Edit(fr_rep(a),fr_cmp(a,a),fr_rep(a))(Skip,3(a));
|
||||
|
||||
mk_fr: Proc(n,d) Recursive Returns(Dec Fixed(15) Complex);
|
||||
/*--------------------------------------------------------------------
|
||||
* make a Complex number
|
||||
* normalize and cancel
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (n,d) Dec Fixed(15);
|
||||
Dcl (na,da) Dec Fixed(15);
|
||||
Dcl res Dec Fixed(15) Complex;
|
||||
Dcl x Dec Fixed(15);
|
||||
na=abs(n);
|
||||
da=abs(d);
|
||||
Select;
|
||||
When(n=0) Do;
|
||||
real(res)=0;
|
||||
imag(res)=1;
|
||||
End;
|
||||
When(d=0) Do;
|
||||
Put Edit('Request mk_fr('!!n_rep(n)!!','!!n_rep(d)!!')')
|
||||
(Skip,a);
|
||||
Put Edit('Denominator must not be 0')(Skip,a);
|
||||
Signal error;
|
||||
End;
|
||||
Otherwise Do;
|
||||
x=gcd(na,da);
|
||||
real(res)=sign(n)*sign(d)*na/x;
|
||||
imag(res)=da/x;
|
||||
End;
|
||||
End;
|
||||
Return(res);
|
||||
End;
|
||||
|
||||
fr_add: Proc(a,b) Returns(Dec Fixed(15) Complex);
|
||||
/*--------------------------------------------------------------------
|
||||
* add 'fractions' a and b
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (a,b,res) Dec Fixed(15) Complex;
|
||||
Dcl (an,ad,bn,bd) Dec Fixed(15);
|
||||
Dcl (rd,rn) Dec Fixed(15);
|
||||
Dcl x Dec Fixed(15);
|
||||
an=real(a);
|
||||
ad=imag(a);
|
||||
bn=real(b);
|
||||
bd=imag(b);
|
||||
rd=ad*bd;
|
||||
rn=an*bd+bn*ad;
|
||||
x=gcd(rd,rn);
|
||||
real(res)=rn/x;
|
||||
imag(res)=rd/x;
|
||||
Return(res);
|
||||
End;
|
||||
|
||||
fr_sub: Proc(a,b) Returns(Dec Fixed(15) Complex);
|
||||
/*--------------------------------------------------------------------
|
||||
* subtract 'fraction' b from a
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (a,b) Dec Fixed(15) Complex;
|
||||
Dcl b2 Dec Fixed(15) Complex;
|
||||
real(b2)=-real(b);
|
||||
imag(b2)=imag(b);
|
||||
Return(fr_add(a,b2));
|
||||
End;
|
||||
|
||||
fr_mult: Proc(a,b) Returns(Dec Fixed(15) Complex);
|
||||
/*--------------------------------------------------------------------
|
||||
* multiply 'fractions' a and b
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (a,b,res) Dec Fixed(15) Complex;
|
||||
real(res)=real(a)*real(b);
|
||||
imag(res)=imag(a)*imag(b);
|
||||
Return(res);
|
||||
End;
|
||||
|
||||
fr_div: Proc(a,b) Returns(Dec Fixed(15) Complex);
|
||||
/*--------------------------------------------------------------------
|
||||
* divide 'fraction' a by b
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (a,b) Dec Fixed(15) Complex;
|
||||
Dcl b2 Dec Fixed(15) Complex;
|
||||
real(b2)=imag(b);
|
||||
imag(b2)=real(b);
|
||||
If real(a)=0 & real(b)=0 Then
|
||||
Return(mk_fr(1,1));
|
||||
Return(fr_mult(a,b2));
|
||||
End;
|
||||
|
||||
fr_cmp: Proc(a,b) Returns(char(1));
|
||||
/*--------------------------------------------------------------------
|
||||
* compare 'fractions' a and b
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (a,b) Dec Fixed(15) Complex;
|
||||
Dcl (an,ad,bn,bd) Dec Fixed(15);
|
||||
Dcl (a2,b2) Dec Fixed(15);
|
||||
Dcl (rd) Dec Fixed(15);
|
||||
Dcl res Char(1);
|
||||
an=real(a);
|
||||
ad=imag(a);
|
||||
If ad=0 Then Do;
|
||||
Put Edit('ad=',ad,'candidate=',candidate)(Skip,a,f(10));
|
||||
Signal Error;
|
||||
End;
|
||||
bn=real(b);
|
||||
bd=imag(b);
|
||||
rd=ad*bd;
|
||||
a2=abs(an*bd)*sign(an)*sign(ad);
|
||||
b2=abs(bn*ad)*sign(bn)*sign(bd);
|
||||
Select;
|
||||
When(a2<b2) res='<';
|
||||
When(a2>b2) res='>';
|
||||
Otherwise Do;
|
||||
res='=';
|
||||
End;
|
||||
End;
|
||||
Return(res);
|
||||
End;
|
||||
|
||||
fr_rep: Proc(f) Returns(char(15) Var);
|
||||
/*--------------------------------------------------------------------
|
||||
* Return the representation of 'fraction' f
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl f Dec Fixed(15) Complex;
|
||||
Dcl res Char(15) Var;
|
||||
Dcl (n,d) Pic'(14)Z9';
|
||||
Dcl x Dec Fixed(15);
|
||||
Dcl s Dec Fixed(15);
|
||||
n=abs(real(f));
|
||||
d=abs(imag(f));
|
||||
x=gcd(n,d);
|
||||
s=sign(real(f))*sign(imag(f));
|
||||
res=trim(n/x)!!'/'!!trim(d/x);
|
||||
If s<0 Then
|
||||
res='-'!!res;
|
||||
Return(res);
|
||||
End;
|
||||
|
||||
n_rep: Proc(x) Returns(char(15) Var);
|
||||
/*--------------------------------------------------------------------
|
||||
* Return the representation of x
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl x Dec Fixed(15);
|
||||
Dcl res Char(15) Var;
|
||||
Put String(res) List(x);
|
||||
res=trim(res);
|
||||
Return(res);
|
||||
End;
|
||||
|
||||
gcd: Proc(a,b) Returns(Dec Fixed(15)) Recursive;
|
||||
/*--------------------------------------------------------------------
|
||||
* Compute the greatest common divisor
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (a,b) Dec Fixed(15) Nonassignable;
|
||||
If b=0 then Return (abs(a));
|
||||
Return(gcd(abs(b),mod(abs(a),abs(b))));
|
||||
End gcd;
|
||||
|
||||
lcm: Proc(a,b) Returns(Dec Fixed(15));
|
||||
/*--------------------------------------------------------------------
|
||||
* Compute the least common multiple
|
||||
*-------------------------------------------------------------------*/
|
||||
Dcl (a,b) Dec Fixed(15) Nonassignable;
|
||||
if a=0 ! b=0 then Return (0);
|
||||
Return(abs(a*b)/gcd(a,b));
|
||||
End lcm;
|
||||
|
||||
End;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
require 'rational' #Only needed in Ruby < 1.9
|
||||
|
||||
for candidate in 2 .. 2**19:
|
||||
for candidate in 2 .. 2**19
|
||||
sum = Rational(1, candidate)
|
||||
for factor in 2 ... candidate**0.5
|
||||
if candidate % factor == 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue