import re import math import numpy as np import time DEBUG_TEXT = False TIME_DECIMAL_PLACES = 3 SOLUTION_DECIMAL_PLACES = 10 def parse_equation(equation): pattern = r'([+-]?\d*)\s*([a-zA-Z]?)' lhs, rhs = equation.split('=') rhs = int(rhs.strip()) terms = re.findall(pattern, lhs) if DEBUG_TEXT: print(terms) coefficients = {} for coeff, var in terms: if not (coeff or var): continue if DEBUG_TEXT: print(coeff,var,sep=',',end='!') if coeff in {'','+'}: coefficients[var] = 1 elif coeff == '-': coefficients[var] = -1 else: coefficients[var] = int(coeff) if DEBUG_TEXT: print(coeff, coefficients[var],sep=',',end="$") return coefficients, rhs def convert_to_matrix(equations): vs = set() for eq in equations: eq = "".join(eq.split(" ")) coeffs, _ = parse_equation(eq) vs.update(coeffs.keys()) vs = sorted(vs) A = [] b = [] for eq in equations: coeffs, rhs = parse_equation(eq) row = [coeffs.get(v, 0) for v in vs] A.append(row) b.append(rhs) return np.array(A), np.array(b), vs def round_to_precision(number, places): if number == 0: return 0 an = abs(number) if an < 1: dec_places = math.floor(math.log(an, 10)) ar = round(an, -dec_places+places-1) else: ar = round(an, places) rounded = ar*np.sign(number) return rounded equations = """2a - b + 3c + d - e + 2f - g + h + j = 5 -a + 4b - c + 2d + e - f + g + i - 2j = 3 3a + b - 2c + d + 4e - f + 2g + h - i + j = 10 a - b + c + 3d - e + f - 2g + h + i + 2j = 0 -2a + 3b + c - d + e + f + g - 3h + i - j = -4 a + b - c + d + e + f - g + h - i + j = 7 4a - b + c + d + e - f + g + 2h - i + j = 12 -a + b + c - 2d + e + f + 3g - h + i - j = 1 a + 2b - 3c + d + e - f + g + h - 2i + j = 6 a - b + c + d - e + f - g + h + i + j = 2""" list_eq = equations.split("\n") print("\n".join(list_eq)) print() start = time.time() A, b, v = convert_to_matrix(list_eq) s = np.linalg.solve(A,b) end = time.time() time_elapsed = end-start ls = [float(fs) for fs in s] if DEBUG_TEXT: print(A, b, v, ls, time_elapsed,sep="") print() rs = [round_to_precision(s_i, SOLUTION_DECIMAL_PLACES) for s_i in ls] for var,val in zip(v,rs): print(var,'=',val) rounded_time = round_to_precision(time_elapsed, TIME_DECIMAL_PLACES) print(f"\nTime: {rounded_time} seconds")