I have just started to learn erlang(and functional programming) and I am stuck on a simple program. The object of the program is to find the largest prime factor of a number. This is my program:
lprime(N, L, D) when D == N->
if N rem D == 0 -> D;
true-> L
end;
lprime(N,L,D) ->
if N rem D == 0 ->
lprime(N/D, D, D);
true -> lprime(N, L, D+1)
end.
lprime(N)->
lprime(N,1,2).
Here's how it should run for some inputs:
lprime(3)->lprime(3,1,2)->lprime(3,1,3)->3
lprime(36)->lprime(36,1,2)->lprime(18,2,2)->lprime(9,2,2)->lprime(9,2,3)->lprime(3,3,3)->3
lprime(14)->lprime(14,1,2)->lprime(7,2,2)->lprime(7,2,3)->lprime(7,2,4)->lprime(7,2,5)->lprime(7,2,6)->lprime(7,1,7)->7
But the program always returns the first prime divisor instead. lprime(24)->2, lprime(9)->3
I wrote an equivalent(in my opinion) program in Python which I am more familiar with that performs exactly as expected:
def lprime(N, L=1, D=2):
if D==N:
if N%D == 0: return D
return L
if N%D == 0:
return lprime(N/D, D, D)
return lprime(N, L, D+1)
I also tried another version without a guard(it looks cleaner too) but this one seems to go into an infinite recursion, again the python equivalent(IMO) works as expected:
lprime2(1, L, D) ->
L;
lprime2(N,L,D) ->
if N rem D == 0 ->
lprime2(N/D, D, D);
true -> lprime2(N, L, D+1)
end.
lprime2(N)->
lprime2(N,1,2).
I was trying to debug the program using dbg, the documentation of which is very sparse and I don't understand the steps very well. The steps I used were:
1> dbg:start().
{ok,<0.35.0>}
2> dbg:tracer().
{ok,<0.35.0>}
3> dbg:tp(first,lprime, 1, []).
{ok,[{matched,nonode@nohost,1}]}
4> dbg:tp(first,lprime,3,[]).
{ok,[{matched,nonode@nohost,1}]}
5> dbg:p(all,c).
{ok,[{matched,nonode@nohost,26}]}
6> first:lprime(10).
(<0.33.0>) call first:lprime(10)
2
7> first:lprime(10,1,2).
(<0.33.0>) call first:lprime(10,1,2)
Edit: Emphasis added
I didn't find any useful information from this and I'd appreciate any pointers on how to debug effectively too but mainly I'd like to know what causes the program to fail.