64 lines
1.7 KiB
Prolog
64 lines
1.7 KiB
Prolog
chowla(1, 0).
|
|
chowla(2, 0).
|
|
chowla(N, C) :-
|
|
N > 2,
|
|
Max is floor(sqrt(N)),
|
|
findall(X, (between(2, Max, X), N mod X =:= 0), Xs),
|
|
findall(Y, (member(X1, Xs), Y is N div X1, Y \= Max), Ys),
|
|
!,
|
|
sum_list(Xs, S1),
|
|
sum_list(Ys, S2),
|
|
C is S1 + S2.
|
|
|
|
prime_count(Upper, Upper, Count, Count) :-
|
|
!.
|
|
|
|
prime_count(Lower, Upper, Add, Count) :-
|
|
chowla(Lower, 0),
|
|
!,
|
|
Lower1 is Lower + 1,
|
|
Add1 is Add + 1,
|
|
prime_count(Lower1, Upper, Add1, Count).
|
|
|
|
prime_count(Lower, Upper, Add, Count) :-
|
|
Lower1 is Lower + 1,
|
|
prime_count(Lower1, Upper, Add, Count).
|
|
|
|
perfect_numbers(Upper, Upper, AccNums, Nums) :-
|
|
!,
|
|
reverse(AccNums, Nums).
|
|
|
|
perfect_numbers(Lower, Upper, AccNums, Nums) :-
|
|
Perfect is Lower - 1,
|
|
chowla(Lower, Perfect),
|
|
!,
|
|
Lower1 is Lower + 1,
|
|
AccNums1 = [Lower|AccNums],
|
|
perfect_numbers(Lower1, Upper, AccNums1, Nums).
|
|
|
|
perfect_numbers(Lower, Upper, AccNums, Nums) :-
|
|
Lower1 is Lower + 1,
|
|
perfect_numbers(Lower1, Upper, AccNums, Nums).
|
|
|
|
main :-
|
|
% Chowla numbers
|
|
forall(between(1, 37, N), (
|
|
chowla(N, C),
|
|
format('chowla(~D) = ~D\n', [N, C])
|
|
)),
|
|
|
|
% Prime numbers
|
|
Ranges = [100, 1000, 10000, 100000, 1000000, 10000000],
|
|
forall(member(Range, Ranges), (
|
|
prime_count(2, Range, 0, PrimeCount),
|
|
format('There are ~D primes less than ~D.\n', [PrimeCount, Range])
|
|
)),
|
|
|
|
% Perfect numbers
|
|
Limit = 35000000,
|
|
perfect_numbers(2, Limit, [], Nums),
|
|
forall(member(Perfect, Nums), (
|
|
format('~D is a perfect number.\n', [Perfect])
|
|
)),
|
|
length(Nums, PerfectCount),
|
|
format('There are ~D perfect numbers < ~D.\n', [PerfectCount, Limit]).
|