I have made two programs to find the prime factors of a number, one in python and one in pascal. I would like to factorize 600851475143; the python program factorizes it instantly. However, the pascal one does't finish in a reasonable amount of time. Is it to do with the different programming language or how I coded the one in Pascal? I used recursion in the python one but not in the pascal one. Why does the pascal program not also complete instantly?
python:
def findLowestFactor(num, factors=None):
if factors:
start = factors[-1]
else:
start = 2
for i in range(start, int(num)):
if num%i == 0:
return i
else:
return False
def findPrimeFactors(num, factors=None):
if factors is None:
factors = []
factor = findLowestFactor(num, factors)
if factor:
factors.append(factor)
findPrimeFactors(num/factor, factors)
return factors
else:
factors.append(int(num))
return factors
if __name__ == "__main__":
while True:
num = int(input("Please enter a number: "))
factors = findPrimeFactors(num)
print(*factors)
Pascal:
program Primes;
var
input:string;
num:integer;
error:integer;
factor:integer;
factors:array of integer;
found: boolean;
start:integer;
x:integer;
begin
writeln(600851475143);
(*Repeat untill exit*)
while true do
begin
(*Repeat untill valid input*)
repeat
write('Enter a number: ');
readln(input);
val(input, num, error);
if error = 1 then
writeln('Not an integer');
until error = 0;
writeln;
(*set up list*)
SetLength(factors, 0);
factor := 0;
found := false;
(*while num is not prime*)
while found = false do
begin
(*start from largest factor found for efficiency*)
if length(factors) > 0 then
start := factors[length(factors)-1]
else
start := 2;
(*loop through numbers from number in start var to current num*)
for factor := start to num do
begin
(*if there are no more factors*)
if num / factor = 1 then
begin;
(*add final factor to list*)
SetLength(factors, length(factors)+1);
factors[length(factors)-1] := factor;
(*break out of the loop*)
found := True;
end
(*if factor is found*)
else if num mod factor = 0 then
begin
(*divide num by found factor*)
num := num div factor;
(*add the factor*)
SetLength(factors, length(factors)+1);
factors[length(factors)-1] := factor;
(*break for efficiency*)
Break;
end;
end;
end;
write('Prime Factors: ');
for x:= 0 to length(factors)-1 do
write(factors[x], ' ');
writeln;
writeln;
end;
end.
I translated your Python code to Pascal. I used Delphi, but it should compile in FreePascal too. It returns instantaneously:
type
TIntArray = array of Integer; // Delphi: TArray<Integer>;
function findLowestFactor(num: Int64; factors: TIntArray): Integer;
var
start: Integer;
i: Int64;
begin
if Length(factors) > 0 then
start := factors[High(factors)] // factors[-1] in Python, i.e. last entry.
else
start := 2;
i := start;
while i < num do // Int64 can not be used as index in for-loop...
begin // ... so I use while loop.
if num mod i = 0 then // Python: if num % i == 0:
Exit(i); // return i
Inc(i);
end;
Exit(0);
end;
procedure findPrimeFactors(num: Int64; var factors: TIntArray);
var
factor: Integer;
begin
factor := findLowestFactor(num, factors);
if factor > 0 then
begin
// Delphi: factors := factors + [factor];
SetLength(factors, Length(factors) + 1);
factors[High(factors)] := factor;
findPrimeFactors(num div factor, factors);
end
else
begin
// Delphi: factors := factors + [Integer(num)];
SetLength(factors, Length(factors) + 1);
factors[High(factors)] := Integer(num);
end;
end;
const
testValue: Int64 = 600851475143;
var
factors: TIntArray;
i: Integer;
result: Int64;
begin
// Instead of user input, I use the testValue above.
Writeln('test value: ', testValue);
findPrimeFactors(testValue, factors);
result := 1;
for i in factors do
begin
Write(i:8);
result := result * i;
end;
Writeln;
Writeln('multiplied: ', result);
Readln;
end.
Note that I had to use Int64 in some places. I assume Python does this automatically, but not Pascal. Perhaps the use of Integers in some places made your code so slow.
I omitted the user input parts of the code (Readln etc.), just used the constant value you gave. But, as I said, it returns instantaneously, with the right values (see variable result).