2

Problem is as follows:

Create a function that takes 2 inputs, a number n and a list lst. The function should return a list of all the numbers in lst that share no common factors with n (other than 1). n and all numbers in lst will be positive integers greater than or equal to 0.

My attempt

def no_common_factors (n, lst):

    def uf(n):  #get a set of factors
        factors = []
        i = 2
        while n > 1: 
            if n % i == 0: 
                factors += [i]
                n = n / i
            else: 
                i += 1
        return set(factors)

    factors_n = uf(n)
    no_common = []

    for i in range(0, len(lst)): 
        factors_i = uf(i)
        if factors_n.isdisjoint(factors_i): 
            no_common += [lst[i]]
        else: 
            continue

    return no_common

doesn't work:

In [41]: no_common_factors(15, [72,27,32,61,77,11,40])
Out[41]: [72, 27, 32, 77]

when it should return [32, 61, 77, 11].

I stare at it but can't see what I'm doing wrong, it's supposed to be really simple. Please help!

P. Prunesquallor
  • 561
  • 1
  • 10
  • 26

2 Answers2

5

I would do it using math.gcd which returns the greatest common divisor of two numbers:

import math

def no_shared_factors(num, items):
    return [item for item in items if math.gcd(item, num) == 1]

which outputs the correct result:

>>> no_shared_factors(15, [72, 27, 32, 61, 77, 11, 40])
[32, 61, 77, 11]

If math.gcd is too much of a black box, you could write your own implementation or peek the math code (see Code for Greatest Common Divisor in Python):

def gcd(a, b):
    """
    Calculate the Greatest Common Divisor of a and b.

    Unless b==0, the result will have the same sign as b (so that when
    b is divided by it, the result comes out positive).
    """
    while b:
        a, b = b, a % b
    return a

Take a look at the GCD page on Wikipedia for many more alternative algorithms.

norok2
  • 25,683
  • 4
  • 73
  • 99
3

Your bug is in the factors_i calculation.

Replace:

factors_i = uf(i)

By:

factors_i = uf(lst[i])

By the way, you can simplify your code:

def no_common_factors(n, lst):
    factors_n = uf(n)
    no_common = []

    for integer in lst:
        factors_i = uf(integer)
        if factors_n.isdisjoint(factors_i):
            no_common.append(integer)

    return no_common
Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103