Merge branch 'add-array-sum' into 'master'

add array-sum solution

See merge request dananglin/go-laboratory!1
This commit is contained in:
Dan Anglin 2020-03-20 22:38:58 +00:00
commit dac61bc6c7
6 changed files with 165 additions and 0 deletions

5
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,5 @@
---
image: golang:1.14.1-alpine
include:
- local: '/experiments/array-sum/.gitlab-ci.yml'

View file

@ -0,0 +1,10 @@
---
test:arraysum:
only:
refs:
- merge_requests
changes:
- "experiments/array-sum/*.go"
- "experiments/array-sum/.gitlab-ci.yml"
script:
- go test -v ./experiments/array-sum

View file

@ -0,0 +1,9 @@
# Array Sum
This package contains functions to return the sum of all elements of a slice.
There are three main functions which all return the same result but uses different methods.
These are:
- `SumWithForLoop` - Uses a for loop to calculate the sum.
- `SumWithRecursion` - Uses recursion to calculate the sum.
- `SumWithTailRecursion` - Uses tail recursion to to calculate the sum.

View file

@ -0,0 +1,45 @@
package arraysum
// SumWithForLoop uses a for loop to
// calculate the sum of the slice argument.
func SumWithForLoop(numbers []int) int {
output := 0
for _, v := range numbers {
output += v
}
return output
}
// SumWithRecursion uses recursion to
// calculate the sum of the slice argument.
func SumWithRecursion(numbers []int) int {
if len(numbers) == 0 {
return 0
}
return numbers[0] + SumWithRecursion(numbers[1:])
}
// SumWithRecursion uses tail recursion to
// calculate the sum of the slice argument.
func SumWithTailRecursion(numbers []int) int {
return SumWithSubTailCall(numbers, 0)
}
// SumWithSubTailCall is a sub function of
// SumWithTailRecursion. This function takes the
// first element of the array and adds it to the
// running total. It then removes said element and
// calls itself with the updated slice and the current
// running total.
// Recursion ends when there are no more elements in the
// slice. It returns the total sum back to the SubWithTailRecursion
// function.
func SumWithSubTailCall(numbers []int, runningTotal int) int {
if len(numbers) == 0 {
return runningTotal
}
runningTotal += numbers[0]
return SumWithSubTailCall(numbers[1:], runningTotal)
}

View file

@ -0,0 +1,93 @@
package arraysum
import "testing"
var testCases = []struct {
input []int
expected int
}{
{
input: []int{1, 2, 3},
expected: 6,
},
{
input: []int{0, 0, 0, 0},
expected: 0,
},
{
input: []int{64, 1, -294, 5, 79, 9, 103, 15, 10, 41, 1, 0, -2},
expected: 32,
},
{
input: []int{-10238, 89, 73204, -13983, -78338, 5, 1897},
expected: -27364,
},
}
var gout int
// TestSumWithForLoop tests the correctness of SumWithForLoop
func TestSumWithForLoop(t *testing.T) {
for _, tc := range testCases {
actual := SumWithForLoop(tc.input)
if actual != tc.expected {
t.Errorf("Unexpected output received: actual: %d, expected: %d", actual, tc.expected)
}
}
}
// TestSumWithRecursion tests the correctness of SumWithRecursion
func TestSumWithRecursion(t *testing.T) {
for _, tc := range testCases {
actual := SumWithRecursion(tc.input)
if actual != tc.expected {
t.Errorf("Unexpected output received: actual: %d, expected: %d", actual, tc.expected)
}
}
}
// TestSumWithRecursion tests the correctness of SumWithTailRecursion
func TestSumWithTailRecursion(t *testing.T) {
for _, tc := range testCases {
actual := SumWithTailRecursion(tc.input)
if actual != tc.expected {
t.Errorf("Unexpected output received: actual: %d, expected: %d", actual, tc.expected)
}
}
}
// BenchmarkSumWithForLoop tests the performance of the SumWithForLoop function.
func BenchmarkSumWithForLoop(b *testing.B) {
var out int
var benchmarkCase = []int{-485, 327, -865, 858, -58, 893, 74, 345, -467, 632, -557, -728, 749, 634, 451, -670, 799, 300, 115, 755}
for i := 0; i < b.N; i++ {
out = SumWithForLoop(benchmarkCase)
}
gout = out
}
// BenchmarkSumWithRecursion tests the performance of the SumWithRecursion function.
func BenchmarkSumWithRecursion(b *testing.B) {
var out int
var benchmarkCase = []int{-485, 327, -865, 858, -58, 893, 74, 345, -467, 632, -557, -728, 749, 634, 451, -670, 799, 300, 115, 755}
for i := 0; i < b.N; i++ {
out = SumWithRecursion(benchmarkCase)
}
gout = out
}
// BenchmarkSumWithTailRecursion tests the performance of the SumWithTailRecursion function.
func BenchmarkSumWithTailRecursion(b *testing.B) {
var out int
var benchmarkCase = []int{-485, 327, -865, 858, -58, 893, 74, 345, -467, 632, -557, -728, 749, 634, 451, -670, 799, 300, 115, 755}
for i := 0; i < b.N; i++ {
out = SumWithTailRecursion(benchmarkCase)
}
gout = out
}

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module gitlab.com/dananglin/go-laboratory
go 1.13