Jacobi Symbol (Erlang)
From LiteratePrograms
The Jacobi symbol satisfies the six properties listed below, and these can be used to compute the Jacobi symbol in polynomial time.
-
<<property 1>>= jacobi(A, N) when A rem 2 =:= 0 -> jacobi(2, N) * jacobi(A div 2 + A rem 2, N);
-
For ,.
<<property 2>>= jacobi(A, N) when A >= N -> jacobi(A rem N, N);
- For odd coprimes a and n, .
<<property 3>>= jacobi(A, N) when A rem 4 =:= 3, N rem 4 =:= 3 -> -jacobi(N, A); jacobi(A, N) -> jacobi(N, A).
- .
<<property 4>>= jacobi(1, _N) -> 1;
- .
<<property 5>>= jacobi(2, N) -> case (N rem 8) of 1 -> 1; 3 -> -1; 5 -> -1; 7 -> 1 end;
- .
<<property 6>>= jacobi(0, _N) -> 0;
From these properties we can come up with a polynomial time algorithm.
The function always complete as property 1 can be used to remove all even factors, and these will end at property 4. The odd factors will be reduced by property 2 if and if a < n property 3 will swap a and n and property 2 will again reduce a until it matches property 4 or property 6.
<<jacobi symbol>>= property 4 property 5 property 6 property 1 property 2 property 3
This is an escript, it can be run from the command line on unix type computers.
<<jacobi>>= #!/usr/bin/env escript main([A, P]) -> io:fwrite("~p~n", [xjacobi(string:to_integer(A), string:to_integer(P))]). xjacobi({A, _}, {B, _}) -> jacobi(A, B). jacobi symbol
Download code |