This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,130 @@
class Rational implements Comparable {
final BigInteger numerator, denominator
static final Rational ONE = new Rational(1, 1)
static final Rational ZERO = new Rational(0, 1)
Rational(BigInteger whole) { this(whole, 1) }
Rational(BigDecimal decimal) {
this(
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]
}
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)
[num.intdiv(commonFactor) * sign, denom.intdiv(commonFactor)]
}
public Rational toLeastTerms() {
def reduced = reduce(numerator, denominator)
new Rational(reduced[0], reduced[1])
}
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) { new Rational(numerator*r.denominator + r.numerator*denominator, denominator*r.denominator) }
Rational plus (BigInteger n) { new Rational(numerator + n*denominator, denominator) }
Rational next () { new Rational(numerator + denominator, denominator) }
Rational minus (Rational r) { new Rational(numerator*r.denominator - r.numerator*denominator, denominator*r.denominator) }
Rational minus (BigInteger n) { new Rational(numerator - n*denominator, denominator) }
Rational previous () { new Rational(numerator - denominator, denominator) }
Rational multiply (Rational r) { new Rational(numerator*r.numerator, denominator*r.denominator) }
Rational multiply (BigInteger n) { new Rational(numerator*n, denominator) }
Rational div (Rational r) { new Rational(numerator*r.denominator, denominator*r.numerator) }
Rational div (BigInteger n) { new Rational(numerator, denominator*n) }
BigInteger intdiv (BigInteger n) { numerator.intdiv(denominator*n) }
Rational negative () { new Rational(-numerator, denominator) }
Rational abs () { new Rational(numerator.abs(), denominator) }
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) }
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)
}
}
boolean equals(o) {
compareTo(o) == 0
}
int compareTo(o) {
o instanceof Rational \
? compareTo(o as Rational) \
: o instanceof Number \
? compareTo(o as Number)\
: (Double.NaN as int)
}
int compareTo(Rational r) { numerator*r.denominator <=> denominator*r.numerator }
int compareTo(Number n) { numerator <=> denominator*(n as BigInteger) }
int hashCode() { [numerator, denominator].hashCode() }
String toString() {
def reduced = reduce(numerator, denominator)
"${reduced[0]}//${reduced[1]}"
}
}

View file

@ -0,0 +1,74 @@
def x = new Rational(5, 20)
def y = new Rational(9, 12)
def z = new Rational(0, 10000)
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
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 }

View file

@ -0,0 +1,26 @@
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 }
if (lowfactors.isEmpty()) {
return [1L, target]
}
def nhalf = lowfactors.size() - ((lowfactors[-1] == targetSqrt) ? 1 : 0)
return ([1L] + lowfactors + ((nhalf-1)..0).collect { target.intdiv(lowfactors[it]) } + [target]).unique()
}
1.upto(2**19) {
if ((it % 100000) == 0) { println "HT" }
else if ((it % 1000) == 0) { print "." }
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]) }
}