This commit is contained in:
parent
c33a997dc5
commit
57507756ec
14 changed files with 864 additions and 97 deletions
82
ia-calc.go
Normal file
82
ia-calc.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Enhanced math expression parser
|
||||
func parseMathExpression(query string) (string, bool) {
|
||||
// Clean and normalize the expression
|
||||
query = strings.ReplaceAll(query, " ", "")
|
||||
query = strings.ReplaceAll(query, ",", "")
|
||||
|
||||
// Regex to match valid math expressions
|
||||
mathRegex := regexp.MustCompile(`^\d+(\.\d+)?([\+\-\*/\^]\d+(\.\d+)?)+$`)
|
||||
if !mathRegex.MatchString(query) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Operator precedence handling
|
||||
operators := []struct {
|
||||
symbol string
|
||||
apply func(float64, float64) float64
|
||||
}{
|
||||
{"^", func(a, b float64) float64 {
|
||||
result := 1.0
|
||||
for i := 0; i < int(b); i++ {
|
||||
result *= a
|
||||
}
|
||||
return result
|
||||
}},
|
||||
{"*", func(a, b float64) float64 { return a * b }},
|
||||
{"/", func(a, b float64) float64 { return a / b }},
|
||||
{"+", func(a, b float64) float64 { return a + b }},
|
||||
{"-", func(a, b float64) float64 { return a - b }},
|
||||
}
|
||||
|
||||
// Parse numbers and operators
|
||||
var tokens []interface{}
|
||||
current := ""
|
||||
for _, char := range query {
|
||||
if char >= '0' && char <= '9' || char == '.' {
|
||||
current += string(char)
|
||||
} else {
|
||||
if current != "" {
|
||||
num, _ := strconv.ParseFloat(current, 64)
|
||||
tokens = append(tokens, num)
|
||||
current = ""
|
||||
}
|
||||
tokens = append(tokens, string(char))
|
||||
}
|
||||
}
|
||||
if current != "" {
|
||||
num, _ := strconv.ParseFloat(current, 64)
|
||||
tokens = append(tokens, num)
|
||||
}
|
||||
|
||||
// Evaluate expression with operator precedence
|
||||
for _, op := range operators {
|
||||
for i := 1; i < len(tokens)-1; i += 2 {
|
||||
if operator, ok := tokens[i].(string); ok && operator == op.symbol {
|
||||
left := tokens[i-1].(float64)
|
||||
right := tokens[i+1].(float64)
|
||||
result := op.apply(left, right)
|
||||
|
||||
// Update tokens
|
||||
tokens = append(tokens[:i-1], tokens[i+2:]...)
|
||||
tokens = append(tokens[:i-1], append([]interface{}{result}, tokens[i-1:]...)...)
|
||||
i -= 2 // Adjust index after modification
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format result
|
||||
result := tokens[0].(float64)
|
||||
if result == float64(int(result)) {
|
||||
return fmt.Sprintf("%d", int(result)), true
|
||||
}
|
||||
return fmt.Sprintf("%.2f", result), true
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue