Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 274
Good morning! Here's your coding interview problem for today.

This problem was asked by Facebook.

Given a string consisting of parentheses, single digits, and positive and negative signs, convert the string into a mathematical expression to obtain the answer.

Don't use `eval` or a similar built-in parser.

For example, given `'-1 + (2 + 3)'`, you should return `4`.

Pull request:
Day274
Resolves #559.

Patch:
diff --git a/README.md b/README.md
index 96b06b4..cf06cc0 100644
--- a/README.md
+++ b/README.md
@@ -284,6 +284,7 @@ problems from
 * [Day 271](https://github.com/vaskoz/dailycodingproblem-go/issues/553)
 * [Day 272](https://github.com/vaskoz/dailycodingproblem-go/issues/555)
 * [Day 273](https://github.com/vaskoz/dailycodingproblem-go/issues/556)
+* [Day 274](https://github.com/vaskoz/dailycodingproblem-go/issues/559)
 * [Day 275](https://github.com/vaskoz/dailycodingproblem-go/issues/560)
 * [Day 277](https://github.com/vaskoz/dailycodingproblem-go/issues/563)
 * [Day 278](https://github.com/vaskoz/dailycodingproblem-go/issues/565)
diff --git a/day274/problem.go b/day274/problem.go
new file mode 100644
index 0000000..4f9db34
--- /dev/null
+++ b/day274/problem.go
@@ -0,0 +1,56 @@
+package day274
+
+import (
+	"strings"
+)
+
+// EvalSimpleMathExpression parses very simple math expressions.
+// Expr consisting of parentheses, single digits, and positive and negative signs.
+func EvalSimpleMathExpression(expr string) int {
+	ex := trimAllSpaces(expr)
+	return simpleMath([]rune(ex))
+}
+
+func simpleMath(expr []rune) int {
+	var result int
+	for i := 0; i < len(expr); i++ {
+		switch r := expr[i]; r {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			if i > 0 && expr[i-1] == '-' {
+				result -= int(r - '0')
+			} else {
+				result += int(r - '0')
+			}
+		case '(':
+			count := 1
+			j := i + 1
+			for count != 0 {
+				r = expr[j]
+				switch r {
+				case '(':
+					count++
+				case ')':
+					count--
+				}
+				j++
+			}
+			if i > 0 && expr[i-1] == '-' {
+				result -= simpleMath(expr[i+1 : j-1])
+			} else {
+				result += simpleMath(expr[i+1 : j-1])
+			}
+			i = j
+		}
+	}
+	return result
+}
+
+func trimAllSpaces(expr string) string {
+	var sb strings.Builder
+	for _, r := range expr {
+		if r != ' ' {
+			sb.WriteRune(r)
+		}
+	}
+	return sb.String()
+}


Test patch:
diff --git a/day274/problem_test.go b/day274/problem_test.go
new file mode 100644
index 0000000..00ed0cd
--- /dev/null
+++ b/day274/problem_test.go
@@ -0,0 +1,32 @@
+package day274
+
+import "testing"
+
+// nolint
+var testcases = []struct {
+	expr     string
+	expected int
+}{
+	{"-1 + (2 + 3)", 4},
+	{"-2 + (2 + (3 + 5 + 8))", 16},
+	{"-2 + (-2 + (-3 + 5 + 8))", 6},
+	{"2 - (2 - (3 - 5 - 8))", -10},
+	{"(((3 - 5 - 8) - 2) - (2 - 3))", -11},
+}
+
+func TestEvalSimpleMathExpression(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := EvalSimpleMathExpression(tc.expr); result != tc.expected {
+			t.Errorf("Expected %v, got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkEvalSimpleMathExpression(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			EvalSimpleMathExpression(tc.expr)
+		}
+	}
+}