# Extending an array to a specified length, alternating directions

I am working on golang and trying to understand to write good code not translated from another language, so I have written this program just for learning.

I want to perform operation on this array [1,2,3,4] with limit of 10, so that i get this output [1,2,3,4, 4,3,2,1, 1,2].

This function working correctly but I want to see suggestions for optimizations and improvements.

package main

import "fmt"

func arrayExm(array []int, limit int) []int {
var res []int

length := len(array)

for i:=0; i < limit; i++ {

if(i/length)%2 == 0{
res = append(res,array[i%length])

} else {
res = append(res, array[length -i % length - 1])
}
}

return res

}
func main() {
fmt.Println(" Array with limit", arrayExm([]int{1,2,3,4},10))
}


This function working correctly but I want to see suggestions for optimizations and improvements.

Your source code is undocumented. See Godoc: documenting Go code.

By design, Go has a short, readable specification: The Go Programming Language Specification. As you write code, read useful parts of it in detail, for exanple, make (to make precise allocations), append (which may require multiple reallocations), copy (which has minimal bounds checking and may do block copies), and Index Expressions (which often require a bounds check), and so on.

Browse the Go standard library for useful packages. For example, the testing package provides testing and benchmark facilities.

Your algorithm takes an array element view of the problem. Consider other algorihms. For example, a repeating, alternating pattern of input and reverse input.

I want to see other way.

That's an excellent idea. I usually try to come up with three different ways to do things, although I often settle for two. I use code reviews to ask other people for ideas.

Here's one other way. It's a little different and much more efficient than your way. It uses the Go standard library and code review conventions, and Go's test and benchmark facilities.

alternate.go:

package main

import "fmt"

// alternate returns a list of length n
// with alternating a and reverse a.
func alternate(a []int, n int) []int {
b := make([]int, n)
// copy a
copy(b, a)
// copy reverse a
for i, j := len(a)-1, len(a); i >= 0 && j < len(b); i, j = i-1, j+1 {
b[j] = a[i]
}
// copy repeating pattern
for i := 2 * len(a); i < n; i *= 2 {
copy(b[i:], b[:i])
}
return b
}

func main() {
a := []int{1, 2, 3, 4}
for i := 0; i < 4*len(a)+2; i++ {
fmt.Println(alternate(a, i), i)
}
}


Output:

$go run alternate.go [] 0 [1] 1 [1 2] 2 [1 2 3] 3 [1 2 3 4] 4 [1 2 3 4 4] 5 [1 2 3 4 4 3] 6 [1 2 3 4 4 3 2] 7 [1 2 3 4 4 3 2 1] 8 [1 2 3 4 4 3 2 1 1] 9 [1 2 3 4 4 3 2 1 1 2] 10 [1 2 3 4 4 3 2 1 1 2 3] 11 [1 2 3 4 4 3 2 1 1 2 3 4] 12 [1 2 3 4 4 3 2 1 1 2 3 4 4] 13 [1 2 3 4 4 3 2 1 1 2 3 4 4 3] 14 [1 2 3 4 4 3 2 1 1 2 3 4 4 3 2] 15 [1 2 3 4 4 3 2 1 1 2 3 4 4 3 2 1] 16 [1 2 3 4 4 3 2 1 1 2 3 4 4 3 2 1 1] 17$


alternate_test.go:

package main

import (
"fmt"
"testing"
)

func TestAlternate(t *testing.T) {
a := []int{1, 2, 3, 4}
n := 10
got := fmt.Sprint(alternate(a, n))
want := fmt.Sprint([]int{1, 2, 3, 4, 4, 3, 2, 1, 1, 2})
if want != got {
t.Errorf("want: %v got: %v", want, got)
}
}

func BenchmarkAlternate(b *testing.B) {
a := make([]int, 42)
for i := range a {
a[i] = i
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
alternate(a, 1024)
}
}

func arrayExm(array []int, limit int) []int {
var res []int
length := len(array)
for i := 0; i < limit; i++ {
if (i/length)%2 == 0 {
res = append(res, array[i%length])
} else {
res = append(res, array[length-i%length-1])
}
}
return res
}

func BenchmarkArrayExm(b *testing.B) {
a := make([]int, 42)
for i := range a {
a[i] = i
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
arrayExm(a, 1024)
}
}


Output:

$go test -v -bench=. alternate.go alternate_test.go === RUN TestAlternate --- PASS: TestAlternate (0.00s) goos: linux goarch: amd64 BenchmarkAlternate-4 500000 2576 ns/op 8192 B/op 1 allocs/op BenchmarkArrayExm-4 50000 25783 ns/op 16376 B/op 11 allocs/op PASS ok command-line-arguments 4.388s$

• Thank you So much Peter for this i am also figure out other possible ways – Manjeet Thakur Nov 22 '17 at 7:27