I'm trying to solve project Euler problem 9 using prolog. I'm a 100% n00b with prolog and I'm just trying to understand the basics right now.
I'm trying to use findall to get all triplets that would add up to 1000, but I can't really figure out the syntax.
What I'm hoping for is something like:
pythag_trip(A, B, C, D) :- D is (A * A) + (B * B) + (C * C).
one_thou_pythag(A, B, C) :- pythag_trip(A, B, C, 1000).
product_trip(A, B, C, D) :- D is A * B * C.
findall([A, B, C], one_thou_pythag(A, B, C) , Bag)).
writeln(Bag).
I know that doesn't work because it's saying Bag is not instantiated. But there are still some basics that I don't understand about the language, too.
1: can I even do this? With multiple moving pieces at once? Can I find all triplets satisfying a condition? Do I need to go down a completely different like like using clpfd?
2: What is supposed to be going in that last argument where I put Bag?
3: Is it possible to create data types? I was thinking it might be good to create a triplet set type and an operation to get the pythagorean triplet sum of them if I have to find some way to generate all the possibilities on my own
Basically those questions and then, I could use some pointing in the right direction if anyone has tips
Sorry but I don't answer your questions. It seems to me that you're trying not a prolog-like approach.
You should try to solve it logically.
So do this problem from the top to bottom. We want to have 3 numbers that sum to 1000.
between(1,1000,A), between(A,1000,B), between(B,1000,C), C is 1000-A-B.
In that case, we will have them sorted and we won't take permutations.
So let's go a step further. We want them to be pythagorem triplet.
between(1,1000,A), between(A,1000,B), between(B,1000,C), C is 1000-A-B, is_triplet(A,B,C).
But we don't have is_triplet/3
predicate, so let's create it
is_triplet(A,B,C) :- D is C*C - A*A -B*B, D=0.
And that's actually it.
So let's sum it up
is_triple(A, B, C) :- D is C*C - A*A - B*B, D = 0.
triplet(A,B,C) :- between(1,1000,A), between(A,1000,B), C is 1000-A-B, between(B,1000,C), C is 1000-A-B, is_triple(A,B,C).
When you call triplet(A,B,C)
you should get an answer.
Notice one thing, that at the end I've swapped C is 1000-A-B
with between(B,1000,C)
. It makes the program much faster, try to think why.