algebrite
Version:
Computer Algebra System in Coffeescript
122 lines (87 loc) • 1.38 kB
text/coffeescript
# factor a polynomial or integer
Eval_factor = ->
push(cadr(p1))
Eval()
push(caddr(p1))
Eval()
p2 = pop()
if (p2 == symbol(NIL))
guess()
else
push(p2)
factor()
# more factoring?
p1 = cdddr(p1)
while (iscons(p1))
push(car(p1))
Eval()
factor_again()
p1 = cdr(p1)
factor_again = ->
save()
p2 = pop()
p1 = pop()
h = tos
if (car(p1) == symbol(MULTIPLY))
p1 = cdr(p1)
while (iscons(p1))
push(car(p1))
push(p2)
factor_term()
p1 = cdr(p1)
else
push(p1)
push(p2)
factor_term()
n = tos - h
if (n > 1)
multiply_all_noexpand(n)
restore()
factor_term = ->
save()
factorpoly()
p1 = pop()
if (car(p1) == symbol(MULTIPLY))
p1 = cdr(p1)
while (iscons(p1))
push(car(p1))
p1 = cdr(p1)
else
push(p1)
restore()
factor = ->
save()
p2 = pop()
p1 = pop()
if (isinteger(p1))
push(p1)
factor_number(); # see pollard.cpp
else
push(p1)
push(p2)
factorpoly()
restore()
# for factoring small integers (2^32 or less)
factor_small_number = ->
i = 0
save()
n = pop_integer()
if (isNaN(n))
stop("number too big to factor")
if (n < 0)
n = -n
for i in [0...MAXPRIMETAB]
d = primetab[i]
if (d > n / d)
break
expo = 0
while (n % d == 0)
n /= d
expo++
if (expo)
push_integer(d)
push_integer(expo)
if (n > 1)
push_integer(n)
push_integer(1)
restore()