Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 127
Good morning! Here's your coding interview problem for today.

This problem was asked by Microsoft.

Let's represent an integer in a linked list format by having each node represent a digit in the number. The nodes make up the number in reversed order.

For example, the following linked list:

1 -> 2 -> 3 -> 4 -> 5
is the number 54321.

Given two linked lists in this format, return their sum in the same linked list format.

For example, given

9 -> 9
5 -> 2
return 124 (99 + 25) as:

4 -> 2 -> 1

Pull request:
Day127
Resolves #259.

Patch:
diff --git a/README.md b/README.md
index 480dcba..c554b7c 100644
--- a/README.md
+++ b/README.md
@@ -131,3 +131,4 @@ problems from
 * [Day 123](https://github.com/vaskoz/dailycodingproblem-go/issues/253)
 * [Day 124](https://github.com/vaskoz/dailycodingproblem-go/issues/255)
 * [Day 125](https://github.com/vaskoz/dailycodingproblem-go/issues/257)
+* [Day 127](https://github.com/vaskoz/dailycodingproblem-go/issues/259)
diff --git a/day127/problem.go b/day127/problem.go
new file mode 100644
index 0000000..9fd3347
--- /dev/null
+++ b/day127/problem.go
@@ -0,0 +1,39 @@
+package day127
+
+// RevLLNum represents a reversed linked list of digits.
+type RevLLNum struct {
+	Digit int
+	Next  *RevLLNum
+}
+
+// SumRevLLNum returns the sum of two RevLLNum as a new RevLLNum.
+func SumRevLLNum(first, second *RevLLNum) *RevLLNum {
+	var carryOne bool
+	result := &RevLLNum{}
+	current := result
+	for first != nil || second != nil {
+		current.Next = &RevLLNum{}
+		current = current.Next
+		var sum int
+		if first == nil {
+			sum = second.Digit
+			second = second.Next
+		} else if second == nil {
+			sum = first.Digit
+			first = first.Next
+		} else {
+			sum = first.Digit + second.Digit
+			first = first.Next
+			second = second.Next
+		}
+		if carryOne {
+			sum++
+		}
+		carryOne = sum > 9
+		current.Digit = sum % 10
+	}
+	if carryOne {
+		current.Next = &RevLLNum{1, nil}
+	}
+	return result.Next
+}


Test patch:
diff --git a/day127/problem_test.go b/day127/problem_test.go
new file mode 100644
index 0000000..4055610
--- /dev/null
+++ b/day127/problem_test.go
@@ -0,0 +1,69 @@
+package day127
+
+import (
+	"strconv"
+	"strings"
+	"testing"
+)
+
+var testcases = []struct {
+	first, second, sum *RevLLNum
+}{
+	{&RevLLNum{9, &RevLLNum{9, nil}},
+		&RevLLNum{5, &RevLLNum{2, nil}},
+		&RevLLNum{4, &RevLLNum{2, &RevLLNum{1, nil}}}},
+	{&RevLLNum{9, &RevLLNum{9, nil}},
+		nil,
+		&RevLLNum{9, &RevLLNum{9, nil}}},
+	{nil,
+		&RevLLNum{9, &RevLLNum{9, nil}},
+		&RevLLNum{9, &RevLLNum{9, nil}}},
+	{&RevLLNum{9, &RevLLNum{9, &RevLLNum{9, &RevLLNum{9, nil}}}},
+		&RevLLNum{1, nil},
+		&RevLLNum{0, &RevLLNum{0, &RevLLNum{0, &RevLLNum{0, &RevLLNum{1, nil}}}}}},
+}
+
+func TestSumRevLLNum(t *testing.T) {
+	t.Parallel()
+	for tcid, tc := range testcases {
+		if result := SumRevLLNum(tc.first, tc.second); !equal(result, tc.sum) {
+			t.Errorf("TCID%d does not match expected. Got %v expected %v",
+				tcid, String(result), String(tc.sum))
+		}
+	}
+}
+
+func BenchmarkSumRevLLNum(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			SumRevLLNum(tc.first, tc.second)
+		}
+	}
+}
+
+func equal(a, b *RevLLNum) bool {
+	if a == nil && b == nil {
+		return true
+	} else if a == nil && b != nil {
+		return false
+	} else if a != nil && b == nil {
+		return false
+	}
+	for a != nil && b != nil {
+		if a.Digit != b.Digit {
+			return false
+		}
+		a = a.Next
+		b = b.Next
+	}
+	return a == b
+}
+
+func String(a *RevLLNum) string {
+	var sb strings.Builder
+	for a != nil {
+		sb.WriteString(strconv.Itoa(a.Digit))
+		a = a.Next
+	}
+	return sb.String()
+}