Interesting Little Error With Append

The goal of my program is to create the permutations (aka all combinations where order matters and there is no repitition) of items in a given array. The error occurs when using append in the following code:

package main

import (
	"fmt"
)

func buildNewPool(arr []int, i int) (s []int) {
	s1 := arr[:i]
	s2 := arr[i+1:]
	s = append(s, s1...)
	s = append(s, s2...)
	return s
}
func Permutations(value []int, pool []int, n int, chOut chan<- []int) {
	if n == 0 {
		chOut <- value
	}
	for i := 0; i < len(pool); i++ {
		newValue := append(value,pool[i])
		newPool := buildNewPool(pool,i)
		newN := n - 1
		go Permutations(newValue, newPool, newN, chOut)
	}

	return
}
func main() {
	ch := make(chan []int)
	var Nums = []int{1, 2, 3, 4, 5, 6}
	var V []int
	Permutations(V, Nums, 6, ch)
	for i := range ch {
		fmt.Println(i)
	}
}

It works normally with a small list, but once I go over 5 items in the array, I was getting repeats in my outputted array. To fix this I made my own append function for it and the code is:

package main

import (
	"fmt"
)

func buildNewPool(arr []int, i int) (s []int) {
	s1 := arr[:i]
	s2 := arr[i+1:]
	s = append(s, s1...)
	s = append(s, s2...)
	return s
}
func appendValue(v []int, n int) (value []int) {
	s := make([]int, len(v)+1)
	copy(s, v)
	s[len(s)-1] = n
	value = s
	return
}
func Permutations(value []int, pool []int, n int, chOut chan<- []int) {
	if n == 0 {
		chOut <- value
	}
	for i := 0; i < len(pool); i++ {
		newValue := appendValue(value,pool[i])
		newPool := buildNewPool(pool,i)
		newN := n - 1
		go Permutations(newValue, newPool, newN, chOut)
	}

	return
}
func main() {
	ch := make(chan []int)
	var Nums = []int{1, 2, 3, 4, 5, 6}
	var V []int
	Permutations(V, Nums, 6, ch)
	for i := range ch {
		fmt.Println(i)
	}
}

This fixed the issue, but I’m curious about why it occurred in the first place.

A friend also helped me clean up the code and make it use append, and made it use append, but still had to do part of my append function to make it work. Code:

package main

import (
    "fmt"
)

func NewPool(arr []int, i int) (s []int) {
    s1 := arr[:i]
    s2 := arr[i+1:]
    s = append(s, s1...)
    s = append(s, s2...)
    return s
}
func Permutations(value []int, pool []int, n int, chOut chan<- []int) {
    if n == 0 {
        chOut <- value
    }
    for i := 0; i < len(pool); i++ {
        t := make([]int, len(value))
        copy(t, value)
        go Permutations(append(t, pool[i]), NewPool(pool, i), n-1, chOut)
    }

    return
}
func main() {
    ch := make(chan []int)
    var Nums = []int{1, 2, 3, 4, 5}
    var V []int
    Permutations(V, Nums, 2, ch)
    for i := range ch {
        fmt.Println(i)
    }
}

Thanks for reading :slight_smile:

Main Question: Why did the Append error occur?

Thanks for your question and supplying a runnable.code sample, but you omitted one thing,the output.

What did you see when you ran your faulty program? What did you expect to see?

It was supposed to give the permutations of the numbers given. The error was that there were repeating numbers in the output. Permutations are combinations where order matters and there is no repetition. The problem is that sometimes there was repetition in the output.

[5 4 3 2 1]
[5 1 4 3 2]
[1 5 4 3 2]
[5 4 2 3 1]
[5 1 4 3 3]
[1 2 5 4 3]
[5 2 4 3 1]
[5 4 3 2 2]
[1 3 5 4 2]
[5 2 1 4 3]
[1 4 5 3 2]
[1 5 2 4 3]
[1 5 3 4 2]
[1 5 4 3 3]
[1 2 3 5 4]
[1 2 4 5 3]
[1 2 5 4 4]
[1 3 2 5 4]
[1 3 4 5 2]
[1 3 5 4 4]
[1 4 2 5 3]
[1 4 3 5 2]
[1 4 5 3 3]
[1 5 2 4 4]
[1 5 3 4 4]
[1 2 3 5 5]
[1 2 4 5 5]
[1 3 2 5 5]
[1 3 4 5 5]
[1 4 2 5 5]
[1 4 3 5 5]
[5 1 2 4 3]
[3 5 4 2 1]
[4 5 3 2 1]
[5 1 2 4 4]
[3 1 5 4 2]
[3 2 5 4 1]
[3 4 5 2 1]
[3 5 1 4 2]
[3 5 2 4 1]
[3 5 4 2 2]
[4 1 5 3 2]
[4 2 5 3 1]
[4 3 5 2 1]
[4 5 1 3 2]
[4 5 2 3 1]
[4 5 3 2 2]
[3 1 2 5 4]
[3 1 4 5 2]
[3 1 5 4 4]
[3 2 1 5 4]
[3 2 4 5 1]
[3 2 5 4 4]
[3 4 1 5 2]
[3 4 2 5 1]
[3 4 5 2 2]
[3 5 1 4 4]
[3 5 2 4 4]
[4 1 2 5 3]
[4 1 3 5 2]
[4 1 5 3 3]
[4 2 1 5 3]
[4 2 3 5 1]
[4 2 5 3 3]
[4 3 1 5 2]
[4 3 2 5 1]
[4 3 5 2 2]
[4 5 1 3 3]
[4 5 2 3 3]
[3 1 2 5 5]
[3 1 4 5 5]
[3 2 1 5 5]
[3 2 4 5 5]
[3 4 1 5 5]
[3 4 2 5 5]
[4 1 2 5 5]
[4 1 3 5 5]
[4 2 1 5 5]
[4 2 3 5 5]
[4 3 1 5 5]
[4 3 2 5 5]
[5 2 4 3 3]
[5 2 1 4 4]
[5 3 4 2 1]
[5 4 1 3 2]
[5 4 2 3 3]
[5 3 1 4 2]
[5 3 2 4 1]
[5 3 4 2 2]
[5 4 1 3 3]
[5 3 1 4 4]
[5 3 2 4 4]
[5 1 3 4 2]
[5 1 3 4 4]
[2 1 5 4 3]
[2 1 3 5 4]
[2 1 4 5 3]
[2 1 5 4 4]
[2 1 3 5 5]
[2 1 4 5 5]
[5 2 3 4 1]
[5 2 3 4 4]
[2 5 4 3 1]
[2 3 5 4 1]
[2 4 5 3 1]
[2 5 1 4 3]
[2 5 3 4 1]
[2 5 4 3 3]
[2 3 1 5 4]
[2 3 4 5 1]
[2 3 5 4 4]
[2 4 1 5 3]
[2 4 3 5 1]
[2 4 5 3 3]
[2 5 1 4 4]
[2 5 3 4 4]
[2 3 1 5 5]
[2 3 4 5 5]
[2 4 1 5 5]
[2 4 3 5 5]

Here’s the output of using the builtin append function.

Have you tried running you program with the race detector?

https://blog.golang.org/race-detector

My friend kind of explained what was happening. Slices are still part of the underlying arrary, so appending a slice affects the underlying array which was shared between multiple slices. I was just hoping for a more specific explanation/verbose explanation pointing out where and what was happening to cause the error. I kind of understand what he was getting at, but a visual or more detailed explanation is what I’m looking for.

Docs relevant: https://blog.golang.org/slices

Have you read this link ? https://blog.golang.org/go-slices-usage-and-internals

deadwood(~/src) % go run main.go
[5 4]
[1 5]
[2 5]
[3 5]
[4 5]
[5 1]
[5 2]
[5 3]
[4 1]
[4 2]
[4 3]
[3 4]
[2 1]
[2 3]
[1 4]
[2 4]
[3 1]
[1 2]
[1 3]
[3 2]
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        /home/dfc/src/main.go:31 +0x111
exit status 2

This is what I get when I run your program. I think you may have some issues to work on.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.