code to return divisors and compare common ones

I am trying to create a code that returns me the common divisors between 2 variables that receive integers. And then show the common dividers.

To return me the divisors I'm using this code for testing:

import numpy as np

def divisores(num):

n = np.arange(1,num)

d = num % n

zeros = d == 0

print (n[zeros])

divisores(30) 

But I need this function to return me the divisors of 2 values and not just one. In addition to comparing the common divisors between them, as I could not think of a way to do.

Author: Rosário Pereira Fernandes, 2018-03-18

3 answers

We can leave the solution a little more generic. Let's imagine that we can define an unbounded amount of values to determine the common divisors between them. We can do this through the function:

def divisores(*numeros):
    ...

Thus, if we want the common divisors of 5 and 10, we can call divisores(5, 10), and if we want the divisors of 42, 100 and 999, we just call divisores(42, 100, 999). If we consider, for example, the input 42, 100 and 999, it is easy to notice that all the common divisors of the three numbers will be divisor of each number individually, which implies that all divisors must be less than or equal to the smallest of the input values, since it does not have as a value greater than 42 to be divisor of 42. Thus, we know that it is enough to walk through all values between 1 and the smallest value of the input:

def divisores(*numeros):
    menor = min(numeros)
    for i in range(1, menor+1):
        ...

And to define if i is a divisor of all the numbers in the input, we can use the function all and check if the remainder of dividing all the input numbers by i is 0.

def divisores(*numeros):
    menor = min(numeros)
    for i in range(1, menor+1):
        if all(numero % i == 0 for numero in numeros):
            yield i

With the yield we return a generator that iterates over the divisors of all input numbers.

print('Divisores de 5 e 10:', list(divisores(5, 10)))  # [1, 5]
print('Divisores de 42, 100 e 999:', list(divisores(42, 100, 999)))  # [1]
print('Divisores de 14, 38 e 74:', list(divisores(14, 38, 74)))  # [1, 2]

See working on Repl.it | Ideone

 4
Author: Woss, 2018-03-19 00:08:16

Taking advantage of the function you have to calculate the divisors, you are short of completing the problem. In order to re-use the function that has the best option is to turn print into return:

def divisores(num):
    n = np.arange(1,num)
    d = num % n
    zeros = d == 0
    return n[zeros]

In fact it is always better to do this because it makes the function can be used anywhere without necessarily having to force a write.

Now just build a function that receives two numbers, call the divisores for each of these numbers and get the common numbers of each set. There are many ways to get the common numbers of each set and I will opt for the intersection of set:

def divisores_comuns(num1, num2):
    divs1 = set(divisores(num1)) # obtendo os divisores e transformando em set
    divs2 = set(divisores(num2)) # obtendo os divisores e transformando em set
    return divs1 & divs2 # & é a intereseção de dois sets

See this code working on Ideone

 1
Author: Isac, 2018-03-18 23:46:51

Ana,

To receive two values, one must either consider N as a list of integers, or receive two arguments in the function signature, such as:

def divisores(num1, num2):

Although your procedure works, notice the following:

  1. you test the division of all numbers between 0 - received number, even if the smallest possible Division (2) happens in num / 2;
  2. you test, again, the entire numpy array if the rest of the division is 0;

Although it's not a very charming algorithm, one way you do fewer iterations is as follows:

div_1 = set() #Cria um set vazio
for i in range(1, int(num1/2+1)): #itera de 1 até metade do valor numérico
    if num1%i == 0: #testa se mod é zero.
        div_1.add(i) #anexa o valor de i ao set de divisores do primeiro numero

It is worth remembering, that this function, as well as its code, does not return the value itself as a possible divisor (in the case, when you enter 30, the values obtained will be:{1, 2, 3, 5, 6, 10, 15} ) (30 excluded). In addition, it is possible to consider using the "set" object instead of lists, since numbers should not repeat.

In the case if the function if only find the intersection of the common values of division, you could include everything in the same loop, as it is not, a simplistic approach is to run another iteration in to identify the same divisors of the other number (num2).

For the intersection, you could perform the following:

lista_divisores_comuns = div_1.intersection(div_2)

The final code would look like:

def divisores(num1, num2):    
    div_1 = set()
    div_2 = set()
    for i in range(1, int(num1/2+1)):
        if num1%i == 0:
            div_1.add(i)

    for i in range(1, int(num2/2+1)):
        if num2%i == 0:
            div_2.add(i)


    lista_divisores_comuns = div_1.intersection(div_2)

    return div_1, div_2, lista_divisores_comuns
 0
Author: Nicolas Vieira, 2018-03-18 23:51:09