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:
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)
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.
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
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
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}')
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
– mutlei
Take a look here.
– Solkarped