MAKS_Enjoyer

I have been drafted into the russian army as an S-400 missile operator

Apr 14th, 2023 (edited)
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.25 KB | Source Code | 0 0
  1. import sympy
  2. import re
  3.  
  4. """
  5.     Also btw this wont work with things like Si(SO4)2
  6.    However if it is given a chemical compound like Na2SO4
  7.    It will return a dict of element counts like {"Na":2, "S":1, "O":4}
  8. """
  9. def solver(eqtn):
  10.     ELEMENT_CLAUSE = re.compile("([A-Z][a-z]?)([0-9]*)")
  11.     def reformatter(equation):
  12.         eqtin = equation.replace(' ', '|').replace("+", " + ")
  13.         return eqtin
  14.     def understand(compound):
  15.         assert "(" not in compound, "This parser doesn't support subclauses"
  16.         return {el: (int(num) if num else 1) for el, num in ELEMENT_CLAUSE.findall(compound)}
  17.    
  18.     #Here is the shitfuck starting
  19.     lhs = eqtn.split(" = ")[0]
  20.     lhs_strings = lhs.split(" + ")
  21.     lhs_compounds = [understand(compound) for compound in lhs_strings]
  22.  
  23.     rhs = eqtn.split(" = ")[1]
  24.     rhs_strings = rhs.split(" + ")
  25.     rhs_compounds = [understand(compound) for compound in rhs_strings]
  26.  
  27.     # Get canonical list of elements
  28.     els = sorted(set().union(*lhs_compounds, *rhs_compounds))
  29.     els_index = dict(zip(els, range(len(els))))
  30.  
  31.     # Build matrix to solve
  32.     w = len(lhs_compounds) + len(rhs_compounds)
  33.     h = len(els)
  34.     A = [[0] * w for _ in range(h)]
  35.     # load with element coefficients
  36.     for col, compound in enumerate(lhs_compounds):
  37.         for el, num in compound.items():
  38.             row = els_index[el]
  39.             A[row][col] = num
  40.     for col, compound in enumerate(rhs_compounds, len(lhs_compounds)):
  41.         for el, num in compound.items():
  42.             row = els_index[el]
  43.             A[row][col] = -num   # invert coefficients for RHS
  44.  
  45.     # Solve using Sympy for absolute-precision math
  46.     A = sympy.Matrix(A)
  47.     # find first basis vector == primary solution
  48.     coeffs = A.nullspace()[0]
  49.     # find the least common denominator, multiply through to convert to integer solution
  50.     coeffs *= sympy.lcm([term.q for term in coeffs])
  51.  
  52.     # Display result
  53.     lhs = reformatter("+".join(["{} {}".format(coeffs[i], s) for i, s in enumerate(lhs_strings)]))
  54.     rhs = reformatter("+".join(["{} {}".format(coeffs[i], s) for i, s in enumerate(rhs_strings, len(lhs_strings))]))
  55.     return "{} = {}".format(lhs, rhs)
  56.  
  57. formula = input("Input your chemical reaction: ")
  58. print(solver(formula))
  59.  
Add Comment
Please, Sign In to add comment