-1

Hello I am trying to find the GCD of a list of numbers in Prolog, but I cannot manage to do it. Could you please help?

I am not even barely close so I wont share any of my work till now. PP: In the process of trying to solve this I've encountered another problem that I can't solve, if you can help with this one too I will be grateful. It's finding all the common divisors of two numbers.

Thanks!

lurker
  • 56,987
  • 9
  • 69
  • 103
  • Of interest: [RosettaCode - GCD - Prolog](http://rosettacode.org/wiki/Greatest_common_divisor#Prolog) – Guy Coder Jan 19 '17 at 13:34
  • You can do a search of this site for Prolog GCD. I'm sure you'll find something. – lurker Jan 19 '17 at 14:34
  • 2
    Have you decided on a general arithmetic strategy for how you want to compute your GCD? There are several ways to do it, independent of Prolog. – lurker Jan 19 '17 at 14:35
  • I've found a lot of ways to find GSD, but it's only for two numbers and not a list. Currently I've made an algorithm that finds if a number is a delimiter to all elements of a list and I want to test with all numbers from 1 to the minimal element of the list and record the biggest success. But I have troubles performing it correctly. – Dimitur Epitropov Jan 19 '17 at 14:39
  • 3
    There are ways of computing GCD for a list in a pair-wise manner (see for example, [this](http://stackoverflow.com/questions/1231733/euclidean-greatest-common-divisor-for-more-than-two-numbers) or [this](http://stackoverflow.com/questions/4885537/what-is-the-fastest-way-to-find-the-gcd-of-n-numbers)). You can just combine the two principles of GCD of two numbers with simple Prolog recursive list processing. Without showing some code and exactly where you're stuck, this question is too vague. It's unclear whether you need help with an algorithm in general, or with a specific Prolog concept. – lurker Jan 19 '17 at 14:52

2 Answers2

1

Thanks to Lurker! I wasn't using the proper algorithm. I thought of finding GCD of two numbers and then GCD of the result and the next one, but I am not sure why I got confused that this won't work.

Anyway, here is the code:

gcd(0,X,X):- X > 0, !.
gcd(X,Y,Z):- X>=Y, X1 is X -Y, gcd(X1,Y,Z).
gcd(X,Y,Z):- X<Y, X1 is Y-X, gcd(X1,X,Z).
gcdL([H,H1|T],Z):-gcd(H,H1,X),gcdL([X|T],Z).
gcdL([H1,H2],Z):-gcd(H1,H2,Z).

And for the curious here is the retarded approach I was trying to achieve. And I was almost there as the first answer the script gives is correct, but it continues to backtrack. Anyway it's ugly, long, hard and inefficient:

minel([X],X).
minel([H,H1|T],X):-H>H1,minel([H1|T],X).
minel([H,H1|T],X):-H=<H1,minel([H|T],X).
gcdL(L,X):-gcdL(L,X,1).
gcdL(L,X,C):-minel(L,M),C<M,delAll(L,C),Temp is C,C1 is C + 1,gcdL(L,R,C1),X is max(Temp,R).
gcdL(L,X,C):-minel(L,M),C1 is C + 1,C1=<M,gcdL(L,X,C1).
gcdL(L,X,C):-minel(L,M),C=:=M,X is 1. 
delAll([T],X):- 0 is mod(T,X).
delAll([H|T],X):- 0 is mod(H,X),delAll(T,X)

Note taken: First find the most proper algorithm, then try to script the problem.

  • 1
    If you wanted to be a little more general, you could add a couple of clauses to `gcd/3` to make it work with negative numbers. The GCD of negatives is the GCD of the absolute value of those numbers. – lurker Jan 19 '17 at 17:30
  • Thanks, I will tinker with that if i have some spare time. – Dimitur Epitropov Jan 19 '17 at 21:32
-1

I believe this link will help you https://math.stackexchange.com/questions/8611/number-of-common-divisors-between-two-given-numbers insist of count you can store the numbers to a table for example.

Community
  • 1
  • 1
Dora
  • 25
  • 2
  • 2
    I am not sure this answer has enough detail; just providing a link is definitely not enough. –  Jan 19 '17 at 14:31