Kos
Kos

Reputation: 83

Find the LCM for up to 5 numbers

I'm trying to write a program that will calculate the LCM of up to five numbers.
I've written this code so far:

a = b = True
while a == True:
    x = input('\nEnter two to five numbers separated by commas: ').split(',')
    if x.index(0) == True:
        print('\nNo zeroes.')
    if len(x) < 2:
        while b == True:
            x.append(input('\nTwo numbers are needed. Enter one more: '))
            b = False
    if len(x) > 5:
        print('\nDon\'t enter more than five numbers.')
        continue
    a = False

When I try to run the code I get this error:

Enter two to five numbers separated by commas: 0
Traceback (most recent call last):

  File "/home/mint/.config/spyder-py3/lcm.py", line 4, in <module>
    if x.index(0) == True:

ValueError: 0 is not in list

How is this possible? My input was 0.

Upvotes: 1

Views: 538

Answers (3)

kederrac
kederrac

Reputation: 17322

you can do first the prime factorization then compute the LSM:

from collections import Counter, defaultdict
from functools import reduce

def prime_factors(n):
    primes = []

    i = 2
    while n > 1:
        while n % i == 0:
            n = n / i
            primes.append(i)
        i = i + 1
    if primes:
        return primes

    return [n] # if n is a prime

def lcm(my_list):
    f = [Counter(prime_factors(e)) for e in my_list]

    lcm_primes =  Counter()
    for d in f:
        for prime, count in d.items():
            lcm_primes[prime] = max((lcm_primes[prime], count))

    return reduce(lambda x, y: x * (y[0] ** y[1]),  lcm_primes.items(), 1)

lcm([3, 15, 9, 6, 2])

output:

90

Upvotes: 1

You&#39;re awesome
You&#39;re awesome

Reputation: 301

Because x is a list of string not integers. To do your check, you can convert x to list of integers.

a=b=True
while a:
    # Map x to list of integers
    x = list(map(int, input('\nEnter two to five numbers separated by commas: ').split(',')))   
    # Check if there is zero or any negative number in x.
    if len(list(filter(lambda e: e <= 0, x))) > 0:
        print('\n No zeroes or negative numbers')
        continue
    if len(x)<2:
        while b==True:
            x.append(input('\nTwo numbers are needed. Enter one more: '))
            b=False
    if len(x)>5:
        print('\nDon\'t enter more than five numbers.')
        continue
    a=False

Upvotes: 3

solid.py
solid.py

Reputation: 2812

Maybe something like this, might be suitable for your purposes:

from functools import reduce
from math import gcd

x = []
while len(x) < 2 and len(x) <= 5: # Using this condition removes unneccesary break code:
    x = [int(i) for i in input('\nEnter two to five numbers separated by commas: ').split(',')]
    if x[0] == 0:
        print('\nNo zeroes.')
    if len(x) > 5:
        print('\nDon\'t enter more than five numbers.')
    if len(x) < 2:
        x.append(int(input('\nTwo numbers are needed. Enter one more: ')))

lcm = reduce(lambda x, y: x * y // gcd(x, y), x) # lcm = x * y / gcd(x, y)
print(lcm)

When run this prints the lcm, of the 5 inputted numbers.

Enter two to five numbers separated by commas: 1, 2, 3, 4, 5
60

Upvotes: 1

Related Questions