Last active
December 21, 2020 16:12
-
-
Save segasai/81e48162825cbd8c94f616130d15c939 to your computer and use it in GitHub Desktop.
day18
This file contains 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
from enum import Enum | |
import sys | |
class State(Enum): | |
DEFAULT = -1 | |
NUMBER = 1 | |
PARENTHESIS = 2 | |
OPERATOR = 3 | |
class Operator(Enum): | |
MULT = 1 | |
ADD = 2 | |
class Number: | |
def __init__(self, val): | |
self.value = val | |
def __str__(self): | |
return 'NUM: %d' % (self.value) | |
class PAREN(Enum): | |
OPEN = 1 | |
CLOSE = 2 | |
def tokenize(S): | |
R = [] | |
state = State.DEFAULT | |
par_state = 0 | |
numbuf = [''] | |
for i, k in enumerate(S): | |
if k in '0123456789': | |
if state != State.NUMBER: | |
numbuf = [k] | |
state = State.NUMBER | |
else: | |
numbuf.append(k) | |
continue | |
else: | |
# closure of number | |
if state == State.NUMBER: | |
val = int(''.join(numbuf)) | |
R.append(Number(val)) | |
numbuf = [''] | |
if k in '()': | |
state = State.PARENTHESIS | |
if k == '(': | |
R.append(PAREN.OPEN) | |
par_state += 1 | |
if k == ')': | |
R.append(PAREN.CLOSE) | |
par_state -= 1 | |
assert (par_state >= 0) | |
continue | |
if k == '+': | |
R.append(Operator.ADD) | |
continue | |
if k == '*': | |
R.append(Operator.MULT) | |
continue | |
if k == ' ': | |
state = State.DEFAULT | |
continue | |
raise Exception('oops', k) | |
if state == State.NUMBER: | |
val = int(''.join(numbuf)) | |
R.append(Number(val)) | |
return R | |
def proc(listTokens): | |
#print("PROCESSING") | |
#for ll in listTokens: | |
# print(ll) | |
#print('END') | |
R = [] | |
i = 0 | |
# process parenthesis blocks replacing them | |
while True: | |
if i == len(listTokens): | |
break | |
if listTokens[i] == PAREN.OPEN: | |
# print('opening') | |
state = 1 | |
for i1 in range(i + 1, len(listTokens)): | |
if listTokens[i1] == PAREN.OPEN: | |
state += 1 | |
if listTokens[i1] == PAREN.CLOSE: | |
state -= 1 | |
if state == 0: | |
R.append(Number(proc(listTokens[i + 1:i1]))) | |
break | |
i = i1 + 1 | |
continue | |
if listTokens[i] == PAREN.CLOSE: | |
# print(listTokens, i) | |
raise Exception('oops2') | |
R.append(listTokens[i]) | |
i += 1 | |
val = R[0].value | |
lastop = None | |
for v in R[1:]: | |
if lastop is None and isinstance(v, Operator): | |
lastop = v | |
continue | |
if lastop is not None and isinstance(v, Number): | |
if lastop == Operator.MULT: | |
val = val * v.value | |
if lastop == Operator.ADD: | |
val = val + v.value | |
lastop = None | |
return val | |
def doall(fname): | |
for ll in open(fname, 'r').read().split('\n'): | |
print(proc(tokenize(ll))) | |
if __name__ == '__main__': | |
S = sys.argv[1] # '1 + 2 * 3 + 4 * 5 + 6' | |
T = tokenize(S) | |
print(S) | |
print('TOKENS') | |
for a in T: | |
print(a) | |
print('----') | |
print(T) | |
R = proc(T) | |
print('RESULT') | |
print(R) |
This file contains 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
from enum import Enum | |
import copy | |
import sys | |
class State(Enum): | |
DEFAULT = -1 | |
NUMBER = 1 | |
PARENTHESIS = 2 | |
OPERATOR = 3 | |
class Operator(Enum): | |
MULT = 1 | |
ADD = 2 | |
class Number: | |
def __init__(self, val): | |
self.value = val | |
def __str__(self): | |
return 'NUM: %d' % (self.value) | |
class PAREN(Enum): | |
OPEN = 1 | |
CLOSE = 2 | |
def tokenize(S): | |
R = [] | |
state = State.DEFAULT | |
par_state = 0 | |
numbuf = [''] | |
for i, k in enumerate(S): | |
if k in '0123456789': | |
if state != State.NUMBER: | |
numbuf = [k] | |
state = State.NUMBER | |
else: | |
numbuf.append(k) | |
continue | |
else: | |
# closure of number | |
if state == State.NUMBER: | |
val = int(''.join(numbuf)) | |
R.append(Number(val)) | |
numbuf = [''] | |
if k in '()': | |
state = State.PARENTHESIS | |
if k == '(': | |
R.append(PAREN.OPEN) | |
par_state += 1 | |
if k == ')': | |
R.append(PAREN.CLOSE) | |
par_state -= 1 | |
assert (par_state >= 0) | |
continue | |
if k == '+': | |
R.append(Operator.ADD) | |
continue | |
if k == '*': | |
R.append(Operator.MULT) | |
continue | |
if k == ' ': | |
state = State.DEFAULT | |
continue | |
raise Exception('oops', k) | |
if state == State.NUMBER: | |
val = int(''.join(numbuf)) | |
R.append(Number(val)) | |
return R | |
def proc(listTokens): | |
R = [] | |
i = 0 | |
# process parenthesis blocks replacing them | |
while True: | |
if i == len(listTokens): | |
break | |
if listTokens[i] == PAREN.OPEN: | |
# print('opening') | |
state = 1 | |
for i1 in range(i + 1, len(listTokens)): | |
if listTokens[i1] == PAREN.OPEN: | |
state += 1 | |
if listTokens[i1] == PAREN.CLOSE: | |
state -= 1 | |
if state == 0: | |
R.append(Number(proc(listTokens[i + 1:i1]))) | |
break | |
i = i1 + 1 | |
continue | |
if listTokens[i] == PAREN.CLOSE: | |
# print(listTokens, i) | |
raise Exception('oops2') | |
R.append(listTokens[i]) | |
i += 1 | |
R1 = copy.copy(R) | |
for curop in [Operator.ADD, Operator.MULT]: | |
lastval = R1[0] | |
accum = False | |
R2 = [] | |
#print(" PROCESSING") | |
#for ll in R1: | |
# print(ll) | |
#print('END') | |
for v in R1[1:]: | |
if isinstance(v, Operator): | |
if v == curop: | |
accum = True | |
else: | |
accum = False | |
R2.append(lastval) | |
R2.append(v) | |
if isinstance(v, Number): | |
if accum: | |
if curop == Operator.MULT: | |
val = lastval.value * v.value | |
if curop == Operator.ADD: | |
val = lastval.value + v.value | |
lastval = Number(val) | |
else: | |
lastval = v | |
R2.append(lastval) | |
R1 = R2 | |
ret = R2[0].value | |
#print('RESULT', ret) | |
return ret | |
def doall(fname): | |
for ll in open(fname, 'r').read().split('\n'): | |
print(proc(tokenize(ll))) | |
if __name__ == '__main__': | |
S = sys.argv[1] # '1 + 2 * 3 + 4 * 5 + 6' | |
T = tokenize(S) | |
print(S) | |
print('TOKENS') | |
for a in T: | |
print(a) | |
print('----') | |
print(T) | |
R = proc(T) | |
print('RESULT') | |
print(R) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment