CMU Coding Bootcamp
at main 3.6 kB view raw
1from typing import List 2 3 4def getMostImportantOpIndex(parts: List[str]) -> int: 5 """Returns the index of the most important operator in the given list of parts.""" 6 index = len(parts) + 1 7 higher_order_operator = 0 8 9 if "^" in parts: 10 higher_order_operator = 2 11 index = parts.index("^") 12 if "*" in parts and higher_order_operator < 2 and parts.index("*") < index: 13 higher_order_operator = 1 14 index = parts.index("*") 15 if "/" in parts and higher_order_operator < 2 and parts.index("/") < index: 16 higher_order_operator = 1 17 index = parts.index("/") 18 if "%" in parts and higher_order_operator < 2 and parts.index("%") < index: 19 higher_order_operator = 1 20 index = parts.index("%") 21 if "+" in parts and higher_order_operator < 1 and parts.index("+") < index: 22 index = parts.index("+") 23 if "-" in parts and higher_order_operator < 1 and parts.index("-") < index: 24 index = parts.index("-") 25 return index 26 27 28def runStep(a: str, sign: str, b: str) -> str: 29 """Runs a single step of the evaluation process.""" 30 if sign == "+": 31 return str(int(a) + int(b)) 32 elif sign == "-": 33 return str(int(a) - int(b)) 34 elif sign == "*": 35 return str(int(a) * int(b)) 36 elif sign == "/": 37 return str(int(a) // int(b)) 38 elif sign == "%": 39 return str(int(a) % int(b)) 40 elif sign == "^": 41 return str(int(a) ** int(b)) 42 else: 43 raise ValueError("Invalid operator") 44 45 46def getEvalSteps(expr: str) -> str: 47 """Returns a string containing the evaluation steps of the given expression.""" 48 padding = " " * (len(expr) + 1) + "= " 49 50 expr = expr.strip() 51 expr = expr.replace(" ", "") 52 expr = expr.replace("**", "^") 53 expr = expr.replace("//", "/") 54 steps = [expr] 55 56 expr_parts = [] 57 cur_piece = "" 58 for c in expr: 59 if c.isdigit(): 60 cur_piece += c 61 else: 62 expr_parts.append(cur_piece) 63 expr_parts.append(c) 64 cur_piece = "" 65 expr_parts.append(cur_piece) 66 while len(expr_parts) > 1: 67 next_op = getMostImportantOpIndex(expr_parts) 68 left = expr_parts.pop(next_op - 1) 69 op = expr_parts.pop(next_op - 1) 70 right = expr_parts.pop(next_op - 1) 71 val = runStep(left, op, right) 72 expr_parts.insert(next_op - 1, val) 73 steps.append("".join(expr_parts)) 74 steps[0] = steps[0] + " = " + steps.pop(1) 75 steps = [step.replace("^", "**") for step in steps] 76 steps = [step.replace("/", "//") for step in steps] 77 steps = [padding + step if not i == 0 else step for i, step in enumerate(steps)] 78 final = "\n".join(steps) + "\n" 79 return final 80 81 82def testGetEvalSteps(): 83 print("Testing getEvalSteps()...", end="") 84 assert ( 85 getEvalSteps("2+3*4-8**3%3") 86 == """\ 872+3*4-8**3%3 = 2+3*4-512%3 88 = 2+12-512%3 89 = 2+12-2 90 = 14-2 91 = 12 92""" 93 ) 94 assert ( 95 getEvalSteps("2**2**3+4-2//3") 96 == """\ 972**2**3+4-2//3 = 4**3+4-2//3 98 = 64+4-2//3 99 = 64+4-0 100 = 68-0 101 = 68 102""" 103 ) 104 assert ( 105 getEvalSteps("4//2**2*8-3+2") 106 == """\ 1074//2**2*8-3+2 = 4//4*8-3+2 108 = 1*8-3+2 109 = 8-3+2 110 = 5+2 111 = 7 112""" 113 ) 114 assert ( 115 getEvalSteps("2**4//2-3+1") 116 == """\ 1172**4//2-3+1 = 16//2-3+1 118 = 8-3+1 119 = 5+1 120 = 6 121""" 122 ) 123 print("Passed!") 124 125 126testGetEvalSteps()