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,4 @@
2/3 in Rationals;
# true
2/3 + 3/4;
# 17/12

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

View file

@ -0,0 +1,34 @@
procedure main()
limit := 2^19
write("Perfect numbers up to ",limit," (using rational arithmetic):")
every write(is_perfect(c := 2 to limit))
write("End of perfect numbers")
# verify the rest of the implementation
zero := makerat(0) # from integer
half := makerat(0.5) # from real
qtr := makerat("1/4") # from strings ...
one := makerat("1")
mone := makerat("-1")
verifyrat("eqrat",zero,zero)
verifyrat("ltrat",zero,half)
verifyrat("ltrat",half,zero)
verifyrat("gtrat",zero,half)
verifyrat("gtrat",half,zero)
verifyrat("nerat",zero,half)
verifyrat("nerat",zero,zero)
verifyrat("absrat",mone,)
end
procedure is_perfect(c) #: test for perfect numbers using rational arithmetic
rsum := rational(1, c, 1)
every f := 2 to sqrt(c) do
if 0 = c % f then
rsum := addrat(rsum,addrat(rational(1,f,1),rational(1,integer(c/f),1)))
if rsum.numer = rsum.denom = 1 then
return c
end

View file

@ -0,0 +1,61 @@
procedure verifyrat(p,r1,r2) #: verification tests for rational procedures
return write("Testing ",p,"( ",rat2str(r1),", ",rat2str(\r2) | &null," ) ==> ","returned " || rat2str(p(r1,r2)) | "failed")
end
procedure makerat(x) #: make rational (from integer, real, or strings)
local n,d
static c
initial c := &digits++'+-'
return case type(x) of {
"real" : real2rat(x)
"integer" : ratred(rational(x,1,1))
"string" : if x ? ( n := integer(tab(many(c))), ="/", d := integer(tab(many(c))), pos(0)) then
ratred(rational(n,d,1))
else
makerat(numeric(x))
}
end
procedure absrat(r1) #: abs(rational)
r1 := ratred(r1)
r1.sign := 1
return r1
end
invocable all # for string invocation
procedure xoprat(op,r1,r2) #: support procedure for binary operations that cross denominators
local numer, denom, div
r1 := ratred(r1)
r2 := ratred(r2)
return if op(r1.numer * r2.denom,r2.numer * r1.denom) then r2 # return right argument on success
end
procedure eqrat(r1,r2) #: rational r1 = r2
return xoprat("=",r1,r2)
end
procedure nerat(r1,r2) #: rational r1 ~= r2
return xoprat("~=",r1,r2)
end
procedure ltrat(r1,r2) #: rational r1 < r2
return xoprat("<",r1,r2)
end
procedure lerat(r1,r2) #: rational r1 <= r2
return xoprat("<=",r1,r2)
end
procedure gerat(r1,r2) #: rational r1 >= r2
return xoprat(">=",r1,r2)
end
procedure gtrat(r1,r2) #: rational r1 > r2
return xoprat(">",r1,r2)
end
link rational

View file

@ -0,0 +1,15 @@
record rational(numer, denom, sign) # rational type
addrat(r1,r2) # Add rational numbers r1 and r2.
divrat(r1,r2) # Divide rational numbers r1 and r2.
medrat(r1,r2) # Form mediant of r1 and r2.
mpyrat(r1,r2) # Multiply rational numbers r1 and r2.
negrat(r) # Produce negative of rational number r.
rat2real(r) # Produce floating-point approximation of r
rat2str(r) # Convert the rational number r to its string representation.
real2rat(v,p) # Convert real to rational with precision p (default 1e-10). Warning: excessive p gives ugly fractions
reciprat(r) # Produce the reciprocal of rational number r.
str2rat(s) # Convert the string representation (such as "3/2") to a rational number
subrat(r1,r2) # Subtract rational numbers r1 and r2.
gcd(i, j) # returns greatest common divisor of i and j

View file

@ -0,0 +1,2 @@
3r4*2r5
3r10

View file

@ -0,0 +1 @@
is_perfect_rational=: 2 = (1 + i.) +/@:%@([ #~ 0 = |) ]

View file

@ -0,0 +1,2 @@
factors=: */&>@{@((^ i.@>:)&.>/)@q:~&__
is_perfect_rational=: 2= +/@:%@,@factors

View file

@ -0,0 +1,4 @@
I.is_perfect_rational@"0 i.2^19
6 28 496 8128
I.is_perfect_rational@x:@"0 i.2^19x
6 28 496 8128

View file

@ -0,0 +1,2 @@
(#~ is_perfect_rational"0) (* <:@+:) 2^i.10x
6 28 496 8128

View file

@ -0,0 +1,120 @@
n=2^19
for testNumber=1 to n
sum$=castToFraction$(0)
for factorTest=1 to sqr(testNumber)
if GCD(factorTest,testNumber)=factorTest then sum$=add$(sum$,add$(reciprocal$(castToFraction$(factorTest)),reciprocal$(castToFraction$(testNumber/factorTest))))
next factorTest
if equal(sum$,castToFraction$(2))=1 then print testNumber
next testNumber
end
function abs$(a$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
bNumerator=abs(aNumerator)
bDenominator=abs(aDenominator)
b$=str$(bNumerator)+"/"+str$(bDenominator)
abs$=simplify$(b$)
end function
function negate$(a$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
bNumerator=-1*aNumerator
bDenominator=aDenominator
b$=str$(bNumerator)+"/"+str$(bDenominator)
negate$=simplify$(b$)
end function
function add$(a$,b$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
bNumerator=val(word$(b$,1,"/"))
bDenominator=val(word$(b$,2,"/"))
cNumerator=(aNumerator*bDenominator+bNumerator*aDenominator)
cDenominator=aDenominator*bDenominator
c$=str$(cNumerator)+"/"+str$(cDenominator)
add$=simplify$(c$)
end function
function subtract$(a$,b$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
bNumerator=val(word$(b$,1,"/"))
bDenominator=val(word$(b$,2,"/"))
cNumerator=(aNumerator*bDenominator-bNumerator*aDenominator)
cDenominator=aDenominator*bDenominator
c$=str$(cNumerator)+"/"+str$(cDenominator)
subtract$=simplify$(c$)
end function
function multiply$(a$,b$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
bNumerator=val(word$(b$,1,"/"))
bDenominator=val(word$(b$,2,"/"))
cNumerator=aNumerator*bNumerator
cDenominator=aDenominator*bDenominator
c$=str$(cNumerator)+"/"+str$(cDenominator)
multiply$=simplify$(c$)
end function
function divide$(a$,b$)
divide$=multiply$(a$,reciprocal$(b$))
end function
function simplify$(a$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
gcd=GCD(aNumerator,aDenominator)
if aNumerator<0 and aDenominator<0 then gcd=-1*gcd
bNumerator=aNumerator/gcd
bDenominator=aDenominator/gcd
b$=str$(bNumerator)+"/"+str$(bDenominator)
simplify$=b$
end function
function reciprocal$(a$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
reciprocal$=str$(aDenominator)+"/"+str$(aNumerator)
end function
function equal(a$,b$)
if simplify$(a$)=simplify$(b$) then equal=1:else equal=0
end function
function castToFraction$(a)
do
exp=exp+1
a=a*10
loop until a=int(a)
castToFraction$=simplify$(str$(a)+"/"+str$(10^exp))
end function
function castToReal(a$)
aNumerator=val(word$(a$,1,"/"))
aDenominator=val(word$(a$,2,"/"))
castToReal=aNumerator/aDenominator
end function
function castToInt(a$)
castToInt=int(castToReal(a$))
end function
function GCD(a,b)
if a=0 then
GCD=1
else
if a>=b then
while b
c = a
a = b
b = c mod b
GCD = abs(a)
wend
else
GCD=GCD(b,a)
end if
end if
end function

View file

@ -0,0 +1,8 @@
> a := 3 / 5;
a := 3/5
> numer( a );
3
> denom( a );
5

View file

@ -0,0 +1,2 @@
> b := 4 / 6;
b := 2/3

View file

@ -0,0 +1,21 @@
> a + b;
19
--
15
> a * b;
2/5
> a / b;
9/10
> a - b;
-1
--
15
> a + 1;
8/5
> a - 1;
-2/5

View file

@ -0,0 +1,6 @@
> evalf( 22 / 7 ); # default is 10 digits
3.142857143
> evalf[100]( 22 / 7 ); # 100 digits
3.142857142857142857142857142857142857142857142857142857142857142857\
142857142857142857142857142857143

View file

@ -0,0 +1,26 @@
4/16
3/8
8/4
4Pi/2
16!/10!
Sqrt[9/16]
Sqrt[3/4]
(23/12)^5
2 + 1/(1 + 1/(3 + 1/4))
1/2+1/3+1/5
8/Pi+Pi/8 //Together
13/17 + 7/31
Sum[1/n,{n,1,100}] (*summation of 1/1 + 1/2 + 1/3 + 1/4+ .........+ 1/99 + 1/100*)
1/2-1/3
a=1/3;a+=1/7
1/4==2/8
1/4>3/8
Pi/E >23/20
1/3!=123/370
Sin[3]/Sin[2]>3/20
Numerator[6/9]
Denominator[6/9]

View file

@ -0,0 +1,3 @@
c/(2 c)
(b^2 - c^2)/(b - c) // Cancel
1/2 + b/c // Together

View file

@ -0,0 +1,3 @@
1/2
b+c
(2 b+c) / (2 c)

View file

@ -0,0 +1 @@
1+2*{1,2,3}^3

View file

@ -0,0 +1 @@
{3, 17, 55}

View file

@ -0,0 +1,4 @@
found={};
CheckPerfect[num_Integer]:=If[Total[1/Divisors[num]]==2,AppendTo[found,num]];
Do[CheckPerfect[i],{i,1,2^25}];
found

View file

@ -0,0 +1 @@
{6, 28, 496, 8128, 33550336}

View file

@ -0,0 +1,30 @@
/* Rational numbers are builtin */
a: 3 / 11;
3/11
b: 117 / 17;
117/17
a + b;
1338/187
a - b;
-1236/187
a * b;
351/187
a / b;
17/429
a^5;
243/161051
num(a);
3
denom(a);
11
ratnump(a);
true