UNPKG

algebrite

Version:

Computer Algebra System in Coffeescript

122 lines (87 loc) 1.38 kB
# 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()