SHOW:
|
|
- or go back to the newest paste.
| 1 | def d(s): | |
| 2 | raw_input("----DEBUG----{0}".format(s))
| |
| 3 | ||
| 4 | # Class Molecule: | |
| 5 | # elements: a dictionary of elements and their subscripts | |
| 6 | # count: the coefficient on the molecule | |
| 7 | class Molecule: | |
| 8 | class Atomic: # Represents a {Element}_{Subscript} structure (no coefficient)
| |
| 9 | def __init__(self, el, sub): | |
| 10 | self.element = el | |
| 11 | self.subscript = sub | |
| 12 | def getElement(self): | |
| 13 | return self.element | |
| 14 | def getSubscript(self): | |
| 15 | return self.subscript | |
| 16 | ||
| 17 | def __init__(self): | |
| 18 | self.elements = dict() | |
| 19 | self.count = 1 | |
| 20 | ||
| 21 | def __str__(self): | |
| 22 | ret = "{"+str(self.count)+"}"
| |
| 23 | for el in self.elements: | |
| 24 | ret += "[{0}_{1}]".format(el,self.elements[el])
| |
| 25 | return ret | |
| 26 | ||
| 27 | def getElementTotals(self): | |
| 28 | ret = dict() | |
| 29 | for el in self.elements.keys(): | |
| 30 | ret[el] = self.elements[el] * self.count | |
| 31 | return ret | |
| 32 | ||
| 33 | def add(self, atomic): | |
| 34 | self.add(atomic.getElement(), atomic.getSubscript()) | |
| 35 | ||
| 36 | def add(self, element, subscript): | |
| 37 | # if the molecule already contains this element, just increase the subscript | |
| 38 | if element in self.elements: | |
| 39 | - | self.add(el, mol.elements[el]) |
| 39 | + | |
| 40 | else: # otherwise, add the element and its subscript | |
| 41 | self.elements[element] = subscript | |
| 42 | ||
| 43 | def fold(self, mol): | |
| 44 | for el in mol.elements.keys(): | |
| 45 | self.add(el, mol.elements[el] * mol.count) | |
| 46 | ||
| 47 | def getWord(s,i): # Returns a [isElem, token, lastIndex] list from a string s starting at index i | |
| 48 | if i >= len(s) or i < 0: | |
| 49 | return Nothing | |
| 50 | ||
| 51 | ret = s[i] | |
| 52 | isElem = ret.isalpha() | |
| 53 | i += 1 | |
| 54 | while i < len(s): | |
| 55 | #d(str((isDigit, s[i], i, ret))) | |
| 56 | if not isElem: | |
| 57 | if s[i].isdigit(): | |
| 58 | ret += s[i] | |
| 59 | else: | |
| 60 | return [isElem,ret,i] | |
| 61 | else: | |
| 62 | if s[i].isupper() or s[i].isdigit(): | |
| 63 | return [isElem,ret,i] | |
| 64 | else: | |
| 65 | ret += s[i] | |
| 66 | i = i + 1 | |
| 67 | return [isElem,ret,i] | |
| 68 | ||
| 69 | def tokenize(s): | |
| 70 | l = list() | |
| 71 | i = 0 | |
| 72 | while i < len(s): | |
| 73 | newi = getWord(s, i) | |
| 74 | i = newi[2] | |
| 75 | l.append(newi) | |
| 76 | return l | |
| 77 | ||
| 78 | def standardize(tokens): # inserts implicit subscripts and puts them into ints | |
| 79 | if tokens[0][0]: | |
| 80 | tokens.insert(0,[False,1,0]) | |
| 81 | i = 0 | |
| 82 | while i < len(tokens): | |
| 83 | if tokens[i][0]: # if this is an element | |
| 84 | if i+1 == len(tokens): | |
| 85 | tokens.append([False,1,tokens[i][2]]) | |
| 86 | elif tokens[i+1][0]: # if the next is also an element (ie not a subscript) | |
| 87 | tokens.insert(i+1,[False,1,tokens[i][2]]) | |
| 88 | else: # if this was a subscript | |
| 89 | tokens[i][1] = int(tokens[i][1]) | |
| 90 | i = i + 1 | |
| 91 | ||
| 92 | return tokens | |
| 93 | ||
| 94 | def molecularize(tokens): | |
| 95 | mol = Molecule() | |
| 96 | mol.count = tokens[0][1] | |
| 97 | for i in range(1,len(tokens),2): | |
| 98 | mol.add(tokens[i][1], tokens[i+1][1]) | |
| 99 | return mol | |
| 100 | ||
| 101 | def pl(l): | |
| 102 | for n in l: | |
| 103 | print n | |
| 104 | ||
| 105 | def getmol(s): # returns a Molecule from a string | |
| 106 | - | return [left,right] |
| 106 | + | tok = tokenize(s) |
| 107 | standardize(tok) | |
| 108 | mol = molecularize(tok) | |
| 109 | - | # NaOH = "NaOH" |
| 109 | + | |
| 110 | - | # Na2O3H = "Na2O3HC" |
| 110 | + | |
| 111 | - | # |
| 111 | + | |
| 112 | - | # t_NaOH = tokenize(NaOH) |
| 112 | + | |
| 113 | - | # standardize(t_NaOH) |
| 113 | + | |
| 114 | - | # m_NaOH = molecularize(t_NaOH) |
| 114 | + | |
| 115 | - | # |
| 115 | + | |
| 116 | - | # print "Molecule: {}".format(m_NaOH)
|
| 116 | + | |
| 117 | - | # |
| 117 | + | |
| 118 | - | # |
| 118 | + | |
| 119 | - | # t_Na2O3H = tokenize(Na2O3H) |
| 119 | + | lmols = list() |
| 120 | - | # standardize(t_Na2O3H) |
| 120 | + | for m in left: |
| 121 | - | # m_Na2O3H = molecularize(t_Na2O3H) |
| 121 | + | lmols.append(getmol(m)) |
| 122 | - | # |
| 122 | + | |
| 123 | - | # print "Molecule: {}".format(m_Na2O3H)
|
| 123 | + | rmols = list() |
| 124 | - | # |
| 124 | + | for m in right: |
| 125 | - | # m_NaOH.fold(m_Na2O3H) |
| 125 | + | rmols.append(getmol(m)) |
| 126 | - | # |
| 126 | + | |
| 127 | - | # print "Molecule: {}".format(m_NaOH)
|
| 127 | + | return [lmols,rmols] |
| 128 | ||
| 129 | - | print fission("H2O+NaOH=C6H12O6")
|
| 129 | + | def fusion(lnr): # takes the output of fission and folds them for balancing |
| 130 | if len(lnr) != 2: | |
| 131 | - | # to do the function multiple times, map(balance, sequence_of_split_tokens) |
| 131 | + | |
| 132 | return Nothing | |
| 133 | ||
| 134 | for side in lnr: | |
| 135 | for i in range(1,len(side)): | |
| 136 | side[0].fold(side[i]) | |
| 137 | ||
| 138 | return [lnr[0][0], lnr[1][0]] | |
| 139 | ||
| 140 | def balance(s): | |
| 141 | print "fission" | |
| 142 | fis = fission(s) | |
| 143 | for side in fis: | |
| 144 | pl(side) | |
| 145 | print "fusion" | |
| 146 | fus = fusion(fis) | |
| 147 | pl(fus) | |
| 148 | ||
| 149 | l = fus[0].getElementTotals() | |
| 150 | r = fus[1].getElementTotals() | |
| 151 | ||
| 152 | return l == r | |
| 153 | ||
| 154 | print balance("H2O+H2O=2H2O")
| |
| 155 | # to do the function multiple times, map(balance, input.split()) |