summation multiplication algorithm

Asked

Viewed 659 times

4

I’m doing a job that I need to create an algorithm that turns product into sum or difference and I can only use the signals +, - and the commands else, if, print, while and input. I was able to make it work in multiplication of positive numbers, but I can’t optimize (Ex: 4x2= 2+2+2+2 is not optimized, and 4+4 is optimized) and correct the signal in the multiplication of numbers, negative with negative and positive with negative (Ex: -10x-2= -20, something that’s wrong).

Follow below the lines of code I managed to make:

N1 = int(input('Digite um número'))
N2= int(input('Digite um número'))

if ((N1==0) or (N2==0)):
    print('0')
else:
    if (N1<0) != (N2<0):
     N1
    if N1<0:
     N1 =-N1
    if N1<0:
     N2=-N2
    if N1>N2:
        maior=N1
        menor=N2
    else:
        maior=N2
        menor=N1

    result=0
    Count=0

    if (menor>0):
        while (Count<menor):
            result=result+maior
            Count=Count+1
    else:
        while (Count>menor):
            result=result-maior
            Count=Count-1
    print(result)
    print(Count)
  • I saw a logical error, right at the beginning, you have the inversions of the signs of the numbers read. You first check if N1 is negative and reverse if it is, then you check if N1 is negative again to be able to reverse or not N2. This I think ends up being the cause of your error of -10 x -2 = -20

  • Take a look here.

2 answers

1

TL;DR

def mul_to_add(x, y):
    if x == 0 or y == 0:
        return '0'

    negativo = (x * y) < 0
    x, y = abs(x), abs(y)
    x, y = min(x, y), max(x, y)
    op = '-' if negativo else '+'

    result = f'-{y}' if negativo else f'{y}'

    for _ in range(x - 1):
        result += f" {op} {y}"

    return result


n1 = int(input('Digite um coeficiente: '))
n2 = int(input('Digite outro coeficiente: '))
parcelas = mul_to_add(n1, n2)

print(f'{n1} * {n2} = {parcelas}')

Code running on Repl.it


I followed the following steps to create my code:

  1. Define whether the result will be positive or negative.

    In summary, if the signs of the operands are equal, the result is positive, if not negative. Simple example to facilitate understanding:

    (+1) * (+1) = +1
    (-1) * (-1) = +1
    (+1) * (-1) = -1
    (-1) * (+1) = -1
    

    To calculate I simply multiplied the numbers and check if the result is negative.

    negativo = (x * y) < 0
    
    # também poderia ser
    negativo = (x > 0) != (y > 0)
    
  2. Save the operator I will use to separate the operands in the results

    op = '-' if negativo else '+'
    

    I’m wearing a conditional expression (see more on PEP-0308 or in the documentation) but you could use a if normally.

  3. Take the absolute value of the numbers using the function abs, I won’t need the signals because I’m going to print the signals manually.

    x, y = abs(x), abs(y)
    

    Note: If you think it is "cheating" you can define your own function that would work for this example:

    def abs(valor):
        if valor > 0:
            return valor
    
        return -valor
    
  4. Define which is the largest and the smallest number of operands.

    This way we guarantee the "optimization" that you mentioned in the question, thus ensuring the fewest repetitions possible.

    x, y = min(x, y), max(x, y)
    

    Note: If you think it is "cheating" you can define your own function that would work for this example:

    def min(valor_1, valor_2):
        if valor_1 < valor_2:
            return valor_1
    
        return valor_2
    
    def max(valor_1, valor_2):
        if valor_1 > valor_2:
            return valor_1
    
        return valor_2
    
  5. Finally, repeat as many as possible (y) for the least number of times (x).

    In my code I created a string with the first number, and used a range to store the remaining operands.

    # cria string que será retornada como resultado da função
    result = f'-{y}' if negativo else f'{y}'
    
    # (x - 1) pois o primeiro operador já foi inserido
    # quando a string foi criada
    for _ in range(x - 1):
        # concatena os operandos no resultado
        result += f" {op} {y}"
    

Code with comments

def mul_to_add(x, y):
    # se algum operando é zero, já retorna o resultado
    if x == 0 or y == 0:
        return '0'

    # booleano se o resultado é negativo
    negativo = (x * y) < 0

    # remove sinal do número pois serão printados manualmente
    x, y = abs(x), abs(y)

    # garante que x seja menos que y (garante resultado "otimizado")
    x, y = min(x, y), max(x, y)

    # operador para "juntar" os operandos
    op = '-' if negativo else '+'

    # cria string que será retornada como resultado da função
    result = f'-{y}' if negativo else f'{y}'

    # (x - 1) pois o primeiro operador já foi inserido
    # quando a string foi criada
    for _ in range(x - 1):
        # concatena os operandos no resultado
        result += f" {op} {y}"

    return result


n1 = int(input('Digite um coeficiente: '))
n2 = int(input('Digite outro coeficiente: '))

parcelas = mul_to_add(n1, n2)

print(f'{n1} * {n2} = {parcelas}')

0

I managed to break my head here and think that I solved the problem besides optimizing a little the code.

N1 = int(input('Digite um número'))
print()
N2 = int(input('Digite um número'))
print()

if ((N1==0) or (N2==0)):
    print('0')
else:
    maior, menor = [N1,N2] if N1 >= N2 else [N2,N1]

    result=0
    Count=0

    # print('menor = {} e maior = {}'.format(menor, maior)) # Puramente debug

    if (menor>0):
        while (Count<menor):
            result=result+maior
            Count = Count + 1
    else:
        while (Count>menor):
            result=result-maior
            Count = Count - 1
        Count = -Count
    print('Resultado = {}'.format(result))
    print('Repetições = {}'.format(Count))

Functional link on ideone

What have I changed:

  1. I simplified the initialization: it is totally unnecessary to check if both numbers are negative and convert each one into positive.
  2. I removed the signal changes from the numbers: It was causing almost all the bugs in the program.
  3. Third IF within the ELSE will never be run if you continue with the same test, because N1 was negative and was converted to positive, then it would fail the same test.
  • I think it would be better to include the code you changed directly in the answer, but still keep the link to Ideone

  • 1

    You can improve the condition that checks which is higher: maior, menor = [N1, N2] if N1 >= N2 else [N2, N1]

  • Improved @Noobsaibot Thanks for Tip :D

Browser other questions tagged

You are not signed in. Login or sign up in order to post.