69
69
# Returns all factors of n, i.e., all numbers between 1 and n that divide
71
# FIXME: this is a naive implementation. Better would be to compute
72
# the prime factorization for n and then combine it in all possible ways.
70
# n. For small n does a naive implementation by trying all factors
71
# up to square root, for large numbers does Factorize first and then
72
# combines the factors in all possible ways.
73
73
SetHelp("Factors", "number_theory", "Return all factors of a number")
74
function Factors(n) = (
76
75
if not IsInteger(n) then
77
76
(error("Factors: argument not an integer");bailout);
78
77
if n == 0 then return null;
88
for loop = 1 to floor(sqrt(n-1)) do
90
if Divides(loop,n) then
92
front_list=[front_list,loop];
93
back_list=[n/loop,back_list]
97
if IsPerfectSquare(n) then
98
r = [front_list,sqrt(n),back_list]
100
r = [front_list,back_list];
104
SetHelp("FermatFactorization", "number_theory", "Attempt fermat factorization of n into (t-s)*(t+s), returns t and s as a vector if possible, null otherwise")
86
# for small n do naive implementation which is faster
90
for loop = 1 to floor(sqrt(n-1)) do (
91
if Divides(loop,n) then (
93
back_list=[n/loop,back_list]
97
if IsPerfectSquare(n) then
98
r = [list,sqrt(n),back_list]
100
r = [list,back_list];
103
fnc = fn = Factorize (n);
104
for j=2 to columns(fnc) do fnc@(2,j) = 0;
107
list = [list, (prod j=2 to columns(fnc) do fnc@(1,j)^fnc@(2,j))];
110
for j = 2 to columns(fnc) do (
111
if fnc@(2,j) < fn@(2,j) then (
115
) else ( #fnc@(2,j) == fn@(2,j)
124
SetHelp("FermatFactorization", "number_theory", "Attempt Fermat factorization of n into (t-s)*(t+s), returns t and s as a vector if possible, null otherwise")
105
125
function FermatFactorization(n,tries) = (
106
126
if not IsPositiveInteger(n) or not IsPositiveInteger(tries) then
107
127
(error("FermatFactorization: arguments not positive integers");bailout);