| 1 | 1 | def answer(question: str) -> int: |
| 2 | | pass |
| 2 | # Edge Case: Empty or null input strings |
| 3 | if not question: |
| 4 | raise ValueError("syntax error") |
| 5 | |
| 6 | # Edge Case: Non-math questions |
| 7 | if not question.startswith("What is"): |
| 8 | raise ValueError("unknown operation") |
| 9 | |
| 10 | # Remove "What is" prefix and question mark |
| 11 | question = question[8:].rstrip('?') |
| 12 | |
| 13 | # Edge Case: Empty expression after removing prefix |
| 14 | if not question: |
| 15 | raise ValueError("syntax error") |
| 16 | |
| 17 | # Tokenize the question |
| 18 | tokens = question.split() |
| 19 | |
| 20 | # Edge Case: Single number without operations |
| 21 | if len(tokens) == 1: |
| 22 | try: |
| 23 | return int(tokens[0]) |
| 24 | except ValueError: |
| 25 | raise ValueError("syntax error") |
| 26 | |
| 27 | # Parse the expression |
| 28 | equation = [] |
| 29 | i = 0 |
| 30 | expect_number = True # Start by expecting a number |
| 31 | while i < len(tokens): |
| 32 | token = tokens[i] |
| 33 | |
| 34 | # First, determine what type of token this is |
| 35 | is_number = token.lstrip('-').isdigit() |
| 36 | is_plus = token == "plus" |
| 37 | is_minus = token == "minus" |
| 38 | is_multiplied = token == "multiplied" and i + 1 < len(tokens) and tokens[i + 1] == "by" |
| 39 | is_divided = token == "divided" and i + 1 < len(tokens) and tokens[i + 1] == "by" |
| 40 | |
| 41 | # Then, check if it's appropriate for the current context |
| 42 | if is_number: |
| 43 | if not expect_number: |
| 44 | raise ValueError("syntax error") # Expected operator, got number |
| 45 | equation.append(int(token)) |
| 46 | expect_number = False # Next should be operator |
| 47 | elif is_plus or is_minus or is_multiplied or is_divided: |
| 48 | if expect_number: |
| 49 | raise ValueError("syntax error") # Expected number, got operator |
| 50 | if is_plus: |
| 51 | equation.append('+') |
| 52 | expect_number = True # Next should be number |
| 53 | elif is_minus: |
| 54 | equation.append('-') |
| 55 | expect_number = True # Next should be number |
| 56 | elif is_multiplied: |
| 57 | equation.append('*') |
| 58 | expect_number = True # Next should be number |
| 59 | i += 1 # Skip "by" |
| 60 | elif is_divided: |
| 61 | equation.append('/') |
| 62 | expect_number = True # Next should be number |
| 63 | i += 1 # Skip "by" |
| 64 | else: |
| 65 | # Edge Case: Unsupported operations |
| 66 | # Any unrecognized token is an unknown operation |
| 67 | raise ValueError("unknown operation") |
| 68 | i += 1 |
| 69 | |
| 70 | # Should end expecting an operator (meaning we have a complete expression) |
| 71 | if expect_number and len(equation) > 0: |
| 72 | raise ValueError("syntax error") # Trailing number without operator |
| 73 | |
| 74 | # Edge Case: Invalid syntax (e.g., 'plus plus', missing numbers) |
| 75 | if len(equation) < 3 or len(equation) % 2 == 0: |
| 76 | raise ValueError("syntax error") |
| 77 | |
| 78 | # Check that elements at even indices are numbers and odd indices are operators |
| 79 | for j in range(len(equation)): |
| 80 | if j % 2 == 0: # Even index - should be a number |
| 81 | if not isinstance(equation[j], int): |
| 82 | raise ValueError("syntax error") |
| 83 | else: # Odd index - should be an operator |
| 84 | if equation[j] not in ['+', '-', '*', '/']: |
| 85 | raise ValueError("syntax error") |
| 86 | |
| 87 | # Evaluate the expression from left to right |
| 88 | result = equation[0] |
| 89 | i = 1 |
| 90 | while i < len(equation): |
| 91 | operator = equation[i] |
| 92 | # Edge Case: Division by zero |
| 93 | if i + 1 >= len(equation): |
| 94 | raise ValueError("syntax error") |
| 95 | operand = equation[i + 1] |
| 96 | |
| 97 | if operator == '+': |
| 98 | result += operand |
| 99 | elif operator == '-': |
| 100 | result -= operand |
| 101 | elif operator == '*': |
| 102 | result *= operand |
| 103 | elif operator == '/': |
| 104 | if operand == 0: |
| 105 | raise ValueError("syntax error") # Division by zero |
| 106 | result //= operand # Integer division as per examples |
| 107 | |
| 108 | i += 2 |
| 109 | |
| 110 | return result |
| 111 | # Handled Edge Cases: Empty or null input strings, Non-math questions, Single number without operations, Unsupported operations, Invalid syntax, Division by zero |