Skip to content

Instantly share code, notes, and snippets.

@skylar
Created November 20, 2025 21:23
Show Gist options
  • Select an option

  • Save skylar/2bcaa553e48ac466d10e84b903e42615 to your computer and use it in GitHub Desktop.

Select an option

Save skylar/2bcaa553e48ac466d10e84b903e42615 to your computer and use it in GitHub Desktop.
FIRST_OPERATORS = Set.new(['+', "-"])
SECOND_OPERATORS = Set.new(['*', '/'])
def is_digit?(char)
char[0].between?('0', '9')
end
def is_operator?(char)
op_order(char) > 0
end
def op_order(char)
if FIRST_OPERATORS.member?(char)
1
elsif SECOND_OPERATORS.member?(char)
2
else
0
end
end
def calculate(s)
Calculator.new.calculate(s)
end
class Calculator
def initialize
@number = 0
@op_stack = ['+']
@stack = [0]
end
def calculate(str)
str.chars.each do |char|
parse(char)
end
@stack << @number
resolve_operations('=')
@stack.last
end
def parse(char)
if is_digit?(char)
@number *= 10
@number += char.to_i
elsif is_operator?(char)
@stack << @number
@number = 0
resolve_operations(char)
end
end
def resolve_operations(next_operation)
while !@op_stack.empty? && op_order(next_operation) <= op_order(@op_stack.last)
right = @stack.pop
result = operate(@stack.pop, right, @op_stack.pop)
@stack << result
end
@op_stack << next_operation
end
def operate(left, right, operator)
case operator
when '+'
left + right
when '-'
left - right
when '*'
left * right
when '/'
left / right
else
raise "invalid operator"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment