Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -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}"
}
}

View file

@ -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)
}
}

View file

@ -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 }

View 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 }