Created
August 18, 2015 18:28
-
-
Save goldsborough/49545cd9bac5ae9e70b9 to your computer and use it in GitHub Desktop.
Polynomial parser and calculator using Horner's rule
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
from collections import namedtuple | |
def split_equation(equation): | |
match = re.match(r'^\s*\w+\((\w+)\)\s*=\s*(.*)$', equation) | |
return match.groups() | |
def find_terms(equation, var='x'): | |
pattern = re.compile(r'(-?\s*\d+)?' # coefficient | |
r'\s*\*?\s*(' + var + r')' # variable | |
r'(?:\s*\^\s*\(?(\d+)\)?)?' # exponent | |
r'|(-?\s*\d+)') # constant | |
Term = namedtuple('Term', ['coef', 'exp']) | |
terms = [] | |
match = pattern.search(equation) | |
while match: | |
coef, var, exp, const = match.groups() | |
coef = coef if coef else const if const else '1' | |
exp = int(exp) if exp else 1 if var else 0 | |
terms.append(Term(float(coef.replace(' ', '')), int(exp))) | |
match = pattern.search(equation, match.end()) | |
return terms | |
def calculate(equation, value): | |
var, polynomial = split_equation(equation) | |
terms = find_terms(polynomial, var) | |
if not terms: | |
raise RuntimeError("Equation is ill-formed!") | |
terms.sort(key=lambda t: t.exp) | |
y = 0 | |
n = max(terms, key=lambda t: t.exp).exp | |
j = len(terms) - 1 | |
for i in range(n, -1, -1): | |
if j >= 0 and terms[j].exp == i: | |
y = float(terms[j].coef) + value * y | |
j -= 1 | |
else: | |
y *= value | |
return y | |
def main(): | |
equation = "f(t) = 5t^2 + 3 t^10 - 5 * t + 2" | |
result = calculate(equation, 2) | |
print(result) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment