language: Ruby (ruby-1.9.3)
date: 235 days 0 hours ago
link:
visibility: private
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
class Prog024
        OPERATORS = {'~' => 1, '+' => 0, '-' => 0, '*' => 0}
 
        def initialize(input_str)
                @input = '(' + input_str + ')'
                @operand_stack = []
                @operator_stack = []
        end
 
        def evaluate_simple_expr
                operator = @operator_stack.delete_at(-1)
                opnd1 = @operand_stack.delete_at(-1)
                if operator == '~'
                        @operand_stack << -opnd1
                else
                        opnd2 = @operand_stack.delete_at(-1)
                        if operator == '+'
                                val = opnd2 + opnd1
                        elsif operator == '-'
                                val = opnd2 - opnd1
                        elsif operator == '*'
                                val = opnd2 * opnd1
                        else
                                raise "Unexpected operator #{operator}" if operator != '/'
                                val = opnd2 / opnd1
                        end
                        @operand_stack << val
                end
        end
 
        def evaluate_nested_expr
                while @operator_stack.last != '('
                        evaluate_simple_expr
                end
                @operator_stack.delete_at(-1)
        end
 
        def evaluate_expr
                i = 0
                while i < @input.length
                        prev_ch = (i > 0) ? @input[i - 1] : nil
                        curr_ch = @input[i]
                        # puts "ch = #{curr_ch}, opr = " + @operator_stack.inspect + ", opnd = " + @operand_stack.inspect
                        if curr_ch =~ /[0-9]/
                                j = (i + 1)
                                while j < @input.length
                                        if @input[j] !~ /[0-9]/
                                                break
                                        end
                                        j += 1
                                end
                                val = @input[i...j].to_i
                                @operand_stack << val
                                i = j
                                next
                        end
 
                        if curr_ch == '-' && /[0-9)]/ !~ prev_ch
                                @operator_stack << '~'
                        elsif curr_ch == ')'
                                evaluate_nested_expr
                        elsif curr_ch == '('
                                @operator_stack << curr_ch
                        elsif curr_ch == '+' || curr_ch == '*' || curr_ch == '-' || curr_ch == '/'
                                while @operator_stack.last != '('
                                        evaluate_simple_expr
                                end
                                @operator_stack << curr_ch
                        else
                                raise "Unsupported operator" unless curr_ch.nil?
                                # @operator_stack << curr_ch
                        end
                        i += 1
                end
 
                # raise "Unexpected operand stack size" if @operand_stack.length != 1
                return @operand_stack[0].to_i
        end
 
        def self.main
                input = gets.strip.gsub(/\s/, '')
                prog = Prog024.new(input)
                res = prog.evaluate_expr
                puts res.to_s
        end
end
 
if $0 == __FILE__
        Prog024.main
        exit(0)
end