% If we list all the numbers below 10 that are multiples of 3 or 5,
% we get 3, 5, 6 and 9. The sum of these multiples is 23.
% Find the sum of all the multiples of 3 or 5 below 1000.
:- initialization(goal).
makeList(SL,[H|SL],_) :- H >= 1000.
makeList(L,[H|SL],Fak) :- Mult is H * Fak, makeList(L,[Mult,H,SL],Fak).
euler1(Sol) :-
makeList(L3,[3],3), makeList(L5,[5],5),
sumlist(L3,S3), sumlist(L5,S5), Sol is S3 + S5.
goal :-
% trace,
write('Euler Problem # 1'), nl,
% write('-----------------'), nl,
write('Solution: '), euler1(Sol), write(Sol).
But SWI-Prolog complains
ERROR: d:/prog/prolog/euler1.pl:9: Initialization goal raised exception:
ERROR: '.'/2: Type error: `[]' expected, found `[[81, [27, [9, [3,
[]]]]]]' ("x" must hold one character)
true.
I really can't figure out what is wrong. The error message is of no help
either as it does not indicate the line number.
Thanks for any hints
Andreas
> Hi
> I am trying to learn a bit of Prolog with the following simple proggie:
>
> % If we list all the numbers below 10 that are multiples of 3 or 5, % we
> get 3, 5, 6 and 9. The sum of these multiples is 23. % Find the sum of
> all the multiples of 3 or 5 below 1000.
>
> :- initialization(goal).
>
> makeList(SL,[H|SL],_) :- H >= 1000.
> makeList(L,[H|SL],Fak) :- Mult is H * Fak, makeList(L,[Mult,H,SL],Fak).
the [Mult,H,SL] should be [Mult,H|SL]
make sure you understand why
I am not saying this solves all your problems, but it is essential
Cheers
Bart Demoen
Thanks Bart
I hope to have got it now.
But would not [Mult|[H|SL]] have been better?
Andreas
> But would not [Mult|[H|SL]] have been better? Andreas
?- [m|[h|s]] = [m,h|s].
true.
Two syntactic forms for the same thing.
Which one is "better" ?
Make sure you understand this - and if not ask.
Cheers
Bart Demoen
the sum is 33 for numbers below 10.
> % Find the sum of all the multiples of 3 or 5 below 1000.
> Thanks for any hints
Thanks for the fun problem. With the help of the Prolog IRC channel
(particularly ski), here's the solution:
% Find the sum of all the multiples of 3 or 5 below 'maxNum'
% load and type goal(X) to run
maxNum(1000).
goal(Sum) :- getMults(Ns), sumNumbers(Ns, Sum).
validMultiple(N) :- N rem 5 =:= 0.
validMultiple(N) :- N rem 3 =:= 0.
neededNumber(X) :- maxNum(M), between(1,M, X), validMultiple(X).
getMults(Xs) :- bagof(X, neededNumber(X), Xs).
sumNumbers(Ns, Sum) :- sumNumbers_(Ns, 0, Sum).
sumNumbers_([], Acc, Acc).
sumNumbers_([Head|Tail], Acc, X) :- NewAcc is Acc + Head, sumNumbers_
(Tail, NewAcc, X).
% Find the sum of all the multiples of 3 or 5 below 'maxNum'
% load and type goal(X) to run
max_num(1000).
valid_multiple(N) :- N rem 5 =:= 0.
valid_multiple(N) :- N rem 3 =:= 0.
needed_number(X) :- max_num(M), between(1,M, X), valid_multiple(X).
get_mults(Xs) :- bagof(X, needed_number(X), Xs).
goal(Sum) :- get_mults(Ns), sum_numbers(Ns, Sum).
sum_numbers(Ns, Sum) :- sum_numbers_(Ns, 0, Sum).
sum_numbers_([], Acc, Acc).
sum_numbers_([Head|Tail], Acc, X) :- NewAcc is Acc + Head, sum_numbers_
(Tail, NewAcc, X).
> here's the solution:
The following solution uses SWI-Prolog's library(clpfd):
?- N in 1..999, N mod 5 #= 0 #\/ N mod 3 #= 0,
findall(N, indomain(N), Ns), sum(Ns, #=, Sum).
yielding:
%@ Sum = 233168
For 1..1000, it yields 234168; your program instead yields 267333.
--
comp.lang.prolog FAQ: http://www.logic.at/prolog/faq/
> For 1..1000, it yields 234168; your program instead yields 267333.
yes, I was using bagof and getting repeats for numbers which where
divisible by both 3 and 5. It now yields the same result:
% Find the sum of all the multiples of 3 or 5 below 'maxNum'
% load and type goal(X) to run
goal(MaxNum, Sum) :- get_mults(MaxNum, Ns), sum_numbers(Ns, Sum).
get_mults(MaxNum, Xs) :- setof(X, needed_number(MaxNum, X), Xs).
needed_number(MaxNum, X) :- between(1,MaxNum, X), valid_multiple(X).
valid_multiple(N) :- N rem 5 =:= 0.
valid_multiple(N) :- N rem 3 =:= 0.
sum_numbers(Ns, Sum) :- sum_numbers_(Ns, 0, Sum).
sum_numbers_([], Acc, Acc).
sum_numbers_([Head|Tail], Acc, X) :- NewAcc is Acc + Head, sum_numbers_
(Tail, NewAcc, X).
deb :- visible(+all), leash(-exit).