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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/fractify/calculator.rb', line 6
def evaluate(formula)
fraction_string = ''
current_rank = 0
incorrect_syntax, inside_of_a_fraction, minus_registered,
operator_awaiting_an_argument,
last_char_is_a_closed_bracket = false
at_least_one_fraction = false
fraction = nil
operators = Fractify::OperatorArray.new
index = 0
formula.each_char do |char|
if inside_of_a_fraction
if char == ')'
fraction_string = "(#{fraction_string})"
unless Fractify::Fraction.valid?(fraction_string)
incorrect_syntax = true
break
end
fraction = Fractify::Fraction.new(string: fraction_string)
operators.last.to_right = fraction if at_least_one_fraction
last_char_is_a_closed_bracket = true
fraction_string = ''
inside_of_a_fraction = false
operator_awaiting_an_argument = false
minus_registered = false
current_rank -= 3
at_least_one_fraction = true
else
fraction_string += char
end
elsif char == '('
if last_char_is_a_closed_bracket
incorrect_syntax = true
break
end
current_rank += 3
minus_registered = false if minus_registered
elsif char == ')'
last_char_is_a_closed_bracket = true
if current_rank.zero?
incorrect_syntax = true
break
end
current_rank -= 3
elsif Fractify::Fraction.numeric?(char) || char == '.'
if current_rank.zero?
incorrect_syntax = true
break
end
unless inside_of_a_fraction
inside_of_a_fraction = true
operator_awaiting_an_argument = false
if minus_registered
fraction_string += '-'
minus_registered = false
operators.pop
end
end
last_char_is_a_closed_bracket = false
fraction_string += char
elsif char == '-'
minus_registered = true
operator_awaiting_an_argument = true
operator = Fractify::Operator.new(char, calculate_rank(current_rank, char), fraction)
operators.push(operator)
last_char_is_a_closed_bracket = false
elsif char_is_an_operator(char)
if operator_awaiting_an_argument || inside_of_a_fraction
incorrect_syntax = true
break
end
last_char_is_a_closed_bracket = false
operator_awaiting_an_argument = true
operator = Fractify::Operator.new(char, calculate_rank(current_rank, char), fraction)
operators.push(operator)
elsif char != ' '
incorrect_syntax = true
break
end
index += 1
end
if operator_awaiting_an_argument || inside_of_a_fraction || incorrect_syntax
return nil
end
operators.sort_descending!
operators.each do |op|
case op.operator_character
when '+'
fraction = op.to_left + op.to_right
when '-'
fraction = op.to_left - op.to_right
when '*'
fraction = op.to_left * op.to_right
when '/'
fraction = op.to_left / op.to_right
when ':'
fraction = op.to_left / op.to_right
when '÷'
fraction = op.to_left / op.to_right
when '^'
fraction = op.to_left**op.to_right
end
left = op.to_left
operators.each do |o|
o.to_left = fraction if o.to_left == left
o.to_right = fraction if o.to_right == left
end
op.executed!
if op != operators.last
new_op_index = find_operator_with_left(operators, op.to_right)
operators[new_op_index].to_left = op.to_left unless new_op_index.negative?
end
end
fraction
end
|