I'm trying to solve the following Kata from Codewars in Python.
My code produces the desired result for all the tests, yet it is not optimal, so it takes too much time to accomplish the big tests.
def set_var(pol_1, pol_2):
if any(char.isalpha() for char in pol_1):
for char in pol_1:
if char.isalpha():
return char
elif any(char.isalpha() for char in pol_2):
for char in pol_2:
if char.isalpha():
return char
# if there is only a constant term
return 'x'
def str_to_dict(polynomial, var):
# exclude spaces
pol_no_space = ''.join([char for char in polynomial if not char.isspace()])
# replace '-' with '+-' to separate terms lates
pol_sep = pol_no_space.replace('-', '+-')
# split into terms using '+' as a separator
pol_terms = pol_sep.split('+')
pol_terms = [term for term in pol_terms if term]
# add powers 1 and 0
for i in range(len(pol_terms)):
if pol_terms[i][-1].isalpha():
pol_terms[i] += '^1'
elif pol_terms[i].lstrip('-').isdigit():
pol_terms[i] += var + '^0'
# add coefficient 1 to those terms that don't have it
for i in range(len(pol_terms)):
# if 0th char is a variable
if pol_terms[i].lstrip('-')[0].isalpha():
if pol_terms[i][0] == '-':
pol_terms[i] = pol_terms[i].replace('-', '-1')
else:
pol_terms[i] = '1' + pol_terms[i]
sep = var + '^'
pol_dict = {}
for term in pol_terms:
coeff, power = term.split(sep)
pol_dict[int(power)] = int(coeff)
return dict(sorted(pol_dict.items(), key=lambda item: item[0], reverse=True))
def mult_pol(p1, p2):
res = {}
for power1, coeff1 in p1.items():
for power2, coeff2 in p2.items():
power = power1 + power2
coeff = coeff1 * coeff2
if coeff != 0:
if power in res:
if res[power] + coeff == 0:
del res[power]
else:
res[power] += coeff
else:
res[power] = coeff
return dict(sorted(res.items(), key=lambda item: item[0], reverse=True))
def dict_to_str(mult_res, var):
if len(mult_res) == 0:
return '0'
else:
res_str = ''
for power in mult_res:
if len(res_str):
if mult_res[power] > 1:
res_str += '+' + str(mult_res[power])
elif mult_res[power] == 1:
if power != 0:
res_str += '+'
else:
res_str += '+' + str(mult_res[power])
elif mult_res[power] == -1:
if power != 0:
res_str += '-'
else:
res_str += str(mult_res[power])
else:
res_str += str(mult_res[power])
else:
if mult_res[power] == 1 or mult_res[power] == -1:
if power > 0:
res_str += str(mult_res[power]).replace('1', '')
else:
res_str += str(mult_res[power])
else:
res_str += str(mult_res[power])
if power > 1:
res_str += var + '^' + str(power)
elif power == 1:
res_str += var
return res_str
def polynomial_product(polynomial_1: str, polynomial_2: str) -> str:
# get the variable used in a polynomial
var = set_var(polynomial_1, polynomial_2)
# get dicts
pol1_dict = str_to_dict(polynomial_1, var)
pol2_dict = str_to_dict(polynomial_2, var)
# multiply dicts
res_dict = mult_pol(pol1_dict, pol2_dict)
# get the string representation
return dict_to_str(res_dict, var)
The main function here is polynomial_product(polynomial_1, polynomial_2). I want to use only built-in functions and methods (e.g. I don't want to use the module re or something like that).
Any suggestions on how to improve the code are of great help.
if any(char.isalpha() for char in pol_1):
at all. Just loop, and if nothing is found - you'll go further. I'd also replacefor i in range(len(pol_terms)):
withfor i, term in enumerate(pol_terms)
to save a couple of lookups and some typing. \$\endgroup\$