-
Notifications
You must be signed in to change notification settings - Fork 0
/
calculator.go
113 lines (97 loc) · 2.01 KB
/
calculator.go
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package equation
import (
"fmt"
"strconv"
"github.com/amovah/equation/operators"
)
func commaHandler(str []string, operators map[string]operators.Operator) []float64 {
extracted := extractOperators(createReader(str))
result := make([]float64, 0)
lastIndex := 0
for _, v := range extracted {
if v.symbol == "," {
result = append(
result,
calculate(
str[lastIndex:v.startIndex],
operators,
),
)
lastIndex = v.startIndex + 1
}
}
result = append(
result,
calculate(
str[lastIndex:len(str)],
operators,
),
)
return result
}
func max(arr []sign, operators map[string]operators.Operator) sign {
max := arr[0]
maxPriority := operators[max.symbol].Priority
for _, v := range arr {
if operators[v.symbol].Priority > maxPriority {
max = v
maxPriority = operators[v.symbol].Priority
}
}
return max
}
func replaceWith(org []string, from, to int, with string) []string {
result := make([]string, 0)
for i, v := range org {
if i >= from && i < to {
continue
}
if i == to {
result = append(result, with)
continue
}
result = append(result, v)
}
return result
}
func calculate(str []string, operators map[string]operators.Operator) float64 {
extracted := extractOperators(createReader(str))
if len(extracted) == 0 {
num, err := strconv.ParseFloat(str[0], 64)
if err != nil {
return 0.0
}
return num
}
high := max(extracted, operators)
if high.innerExpression == "" {
return calculate(
replaceWith(
str,
high.startIndex-1,
high.startIndex+1,
fmt.Sprint(
operators[high.symbol].Operation(
calculate(str[high.startIndex-1:high.startIndex], operators),
calculate(str[high.startIndex+1:high.startIndex+2], operators),
),
),
),
operators,
)
} else {
return calculate(
replaceWith(
str,
high.startIndex,
high.endIndex,
fmt.Sprint(
operators[high.symbol].Operation(
commaHandler(splitter(high.innerExpression), operators)...,
),
),
),
operators,
)
}
}