Get all permutations of a slice - go

I was wondering if there was a way to find all the permutations of an slice filled with characters in Go?
In Python you can use itertools.product with a list or characters or integers, and you can get all the possible permutations.
I have looked to see if there is a package out there, and I cannot seem to find one. Any help would be welcomed.

Permutations of anything implementing sort.Interface: Permutation{First,Next}

Here is a implementation of a permutation function i've written...
https://github.com/itcraftsman/GoPermutation
func permutate(slice [][]int) (permutations [][][]int){
f := fac(len(slice))
for i := 0; i < len(slice); i++ {
elem, s := splice(slice, i)
pos := 0
for count := 0; count < (f / len(slice)); count++{
if pos == (len(s) -1) {
pos = 0
}
s = swap(s, pos, pos +1)
permutation := make([][]int, len(slice))
permutation = s
permutation = append(permutation, elem)
permutations = append(permutations, permutation)
pos++
}
}
return
}
it takes a 2D slice as input and returns a 3D slice, but you can easily change the code so that the function will take a simple slice as input and return a 2D slice with all permutations

Not really sure if this answers your question but this is a simple recursive implementation to find the output below.
package main
import "fmt"
func main() {
values := [][]int{}
// These are the first two rows.
row1 := []int{1, 2, 3}
row2 := []int{4, 5, 6}
row3 := []int{7, 8, 9}
// Append each row to the two-dimensional slice.
values = append(values, row1)
values = append(values, row2)
values = append(values, row3)
fmt.Println(getPermutation(values))
}
func getPermutation(vids [][]int) [][]int {
toRet := [][]int{}
if len(vids) == 0 {
return toRet
}
if len(vids) == 1 {
for _, vid := range vids[0] {
toRet = append(toRet, []int{vid})
}
return toRet
}
t := getPermutation(vids[1:])
for _, vid := range vids[0] {
for _, perm := range t {
toRetAdd := append([]int{vid}, perm...)
toRet = append(toRet, toRetAdd)
}
}
return toRet
}
https://play.golang.org/p/f8wktrxkU0
Output of above snippet:
[[1 4 7] [1 4 8] [1 4 9] [1 5 7] [1 5 8] [1 5 9] [1 6 7] [1 6 8] [1 6 9] [2 4 7] [2 4 8] [2 4 9] [2 5 7] [2 5 8] [2 5 9] [2 6 7] [2 6 8] [2 6 9] [3 4 7] [3 4 8] [3 4 9] [3 5 7] [3 5 8] [3 5 9] [3 6 7] [3 6 8] [3 6 9]]

Related

Can't modify a matrix in a function

I have an array of matrices and I try to mutate each matrix in case an if statement is true.
for example, if I have this matrix:
1 2 3
4 5 6
7 8 9
I want to change each odd number to 0.
This is what I have:
func main() {
matrices := createMatrix() <-- returns an array of matrices.
for _, matrix := range matrices {
removeOdds(matrix)
}
}
func removeOdds(mat [][]int) {
for i := 0; i < len(mat); i++ {
for j := 0; j < len(mat[i]); j++ {
if mat[i][j] % 2 != 0 {
mat[i][j] = 0
}
}
}
}
This is not working because the matrix is not being changed.
I read that Go pass array by value and not reference, so I tried using pointers. But still, when I print the matrix after the changes of removeOdds, I get the original one.
This is what I wrote:
func main() {
matrices := createMatrix() <-- returns an array of matrices.
for _, matrix := range matrices {
removeOdds(&matrix)
}
}
func removeOdds(mat *[][]int) {
for i := 0; i < len(*mat); i++ {
for j := 0; j < len((*mat)[i]); j++ {
if (*mat)[i][j] % 2 != 0 {
(*mat)[i][j] = 0
}
}
}
}
As far as I concerned, the code snippet looks completely ok.
To be clear, type []int is not an array, it's a slice. Array is a fix length block of data, and type signature of array should be like [3]int. Slice is a reference type, a variable length view onto the real data, means it does not own the data, it only record where to find the data in memory in its value.
When you pass a slice into function, that reference value is copied, even inside the function, you are still referencing the same data block, or you can say the underlaying array, as you are when out side function scope.
How ever, I've tried your code my self, and I wrote this:
type Mat = [][]int
func makeMat() Mat {
return [][]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
}
func main() {
mats := []Mat{}
for i := 0; i < 10; i++ {
mats = append(mats, makeMat())
}
for _, mat := range mats {
// no change was made to this function
removeOdds(mat)
}
for _, mat := range mats {
fmt.Println(mat)
}
}
output:
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
[[0 2 0] [4 0 6] [0 8 0]]
So I think there may be some mistake in your observation. Maybe provide more information about your createMatrix().
Your first approach is true except iterating over matrices.
You should use
for i := range matrices {
removeOdds(matrix[i])
}
instead of
for _, matrix := range matrices {
removeOdds(matrix)
}
https://go.dev/play/p/iE0uCE_6Z2v

Error when using pointers to append into slice [][]int

While I was trying to solve a problem "Subset II" from LC, I came across a strange problem. The code generates a power set from a given set.
However, when I run the code it failed because one of the set wasn't correct.
The set [0,3,5,7] replaced by [0,3,5,9] (hence gets appended twice).
I have a print statement (highlighted in code) right before a set gets appended to res, and it prints the correct power set.
The only issue I could think is the use of pointers to append values into a slice, however since it's does not run concurrently I don't see why there would be a race condition.
Appreciate if someone can point out my mistake.
package main
import (
"fmt"
"sort"
)
func ValueCount( nums []int) map[int]int{
hm := make(map[int]int)
for _,v := range(nums){
if c, ok := hm[v]; ok {
hm[v] = c + 1
}else{
hm[v] = 1
}
}
return hm
}
func subsetsWithDup(nums []int) [][]int {
var res [][]int
res = append(res,[]int{})
sort.Ints(nums)
hashMap := ValueCount(nums)
var t []int
printTest(nums, t, &res, hashMap)
return res
}
func printTest(nums []int, t []int, res *[][]int, hm map[int]int) {
if len(nums) == 0 {
return
}
for i:= 0; i < len(nums); {
v := nums[i]
x := nums[i:]
for k:= 0; k< hm[v]; k++ {
var a,b []int
for z:= 0; z<k+1; z++ {
a = append(t,x[z])
}
fmt.Println(a) // <--------- Prints the values that gets appended to res
*res = append(*res, a)
b = a
printTest(nums[i+hm[v]:], b, res, hm)
}
i += hm[v]
}
}
func main(){
n := []int{9,0,3,5,7}
fmt.Println("Find the power set of:", n)
fmt.Println(subsetsWithDup(n))
}
// [0,3,5,7] changes to
// [0,3,5,9] in the output
The bug occurs on line 40:
a = append(t, x[z])
A quick fix would be to change this for loop:
for k := 0; k < hm[v]; k++ {
var a, b []int
for z := 0; z < k+1; z++ {
a = append(t, x[z])
}
fmt.Println(a) // <--------- Prints the values that gets appended to res
*res = append(*res, a)
b = a
printTest(nums[i+hm[v]:], b, res, hm)
}
To this:
for k := 0; k < hm[v]; k++ {
var a, b []int
a = make([]int, len(t))
copy(a, t)
for z := 0; z < k+1; z++ {
a = append(a, x[z])
}
fmt.Println(a) // <--------- Prints the values that gets appended to res
*res = append(*res, a)
b = a
printTest(nums[i+hm[v]:], b, res, hm)
}
It has to do with how Go uses slices as a data structure. When the first argument to the built-in append function was a slice argument, it copied some of the slice's internal data that wasn't intuitive to the programmer. It then modified the argument slice, t, and the newly created slice, a.
I'd recommend reading up on slice internals if you're interested in learning more.
Full program edited:
package main
import (
"fmt"
"sort"
)
func ValueCount(nums []int) map[int]int {
hm := make(map[int]int)
for _, v := range nums {
if c, ok := hm[v]; ok {
hm[v] = c + 1
} else {
hm[v] = 1
}
}
return hm
}
func subsetsWithDup(nums []int) [][]int {
var res [][]int
res = append(res, []int{})
sort.Ints(nums)
hashMap := ValueCount(nums)
var t []int
printTest(nums, t, &res, hashMap)
return res
}
func printTest(nums []int, t []int, res *[][]int, hm map[int]int) {
if len(nums) == 0 {
return
}
for i := 0; i < len(nums); {
v := nums[i]
x := nums[i:]
for k := 0; k < hm[v]; k++ {
var a, b []int
a = make([]int, len(t))
copy(a, t)
for z := 0; z < k+1; z++ {
a = append(a, x[z])
}
fmt.Println(a) // <--------- Prints the values that gets appended to res
*res = append(*res, a)
b = a
printTest(nums[i+hm[v]:], b, res, hm)
}
i += hm[v]
}
}
func main() {
n := []int{9, 0, 3, 5, 7}
fmt.Println("Find the power set of:", n)
fmt.Println(subsetsWithDup(n))
}
New output:
Find the power set of: [9 0 3 5 7]
[0]
[0 3]
[0 3 5]
[0 3 5 7]
[0 3 5 7 9]
[0 3 5 9]
[0 3 7]
[0 3 7 9]
[0 3 9]
[0 5]
[0 5 7]
[0 5 7 9]
[0 5 9]
[0 7]
[0 7 9]
[0 9]
[3]
[3 5]
[3 5 7]
[3 5 7 9]
[3 5 9]
[3 7]
[3 7 9]
[3 9]
[5]
[5 7]
[5 7 9]
[5 9]
[7]
[7 9]
[9]
[[] [0] [0 3] [0 3 5] [0 3 5 7] [0 3 5 7 9] [0 3 5 9] [0 3 7] [0 3 7 9] [0 3 9] [0 5] [0 5 7] [0 5 7 9] [0 5 9] [0 7] [0 7 9] [0 9] [3] [3 5] [3 5 7] [3 5 7 9] [3 5 9] [3 7] [3 7 9] [3 9] [5] [5 7] [5 7 9] [5 9] [7] [7 9] [9]]
Be very careful using (and reusing) slice results - especially when altering those slice values later. Since slices have backing arrays, the referenced data can change in very unexpected ways!
A quick fix to your problem is to copy slice results to a new slice. This ensures changes to the original slice do not introduce bugs (especially in a recursive algorithm).
To copy a slice:
func copyIntSlice(a []int) []int {
c := make([]int, len(a))
copy(c, a) // `a` can now grow/shrink/change without affecting `c`
return c
}
and just call this from your main code:
aCopy := copyIntSlice(a)
*res = append(*res, aCopy)
printTest(nums[i+hm[v]:], aCopy, res, hm)
https://play.golang.org/p/1p8Z4sV9foQ

Why does my range show non-existent value in the slice?

I was trying to solve a Leetcode problem in Go. The problem is subsets.
This is the whole code I'm writing with some debug log:
package main
import (
"fmt"
)
func main() {
v := []int{9, 0, 3, 5, 7}
fmt.Println(subsets(v))
}
func subsets(nums []int) [][]int {
result := [][]int{
[]int{}, // empty
}
for _, num := range nums {
fmt.Println("==========")
fmt.Println(num)
fmt.Printf("result = %v\n", result)
temp := [][]int{}
for _, r := range result {
fmt.Printf("r = %v\n", r)
temp = append(temp, append(r, num))
}
for _, t := range temp {
result = append(result, t)
}
fmt.Println("==========")
}
return result
}
(I also prepared Go play ground URL)
Here is the output of above code:
==========
9
result = [[]]
r = []
==========
==========
0
result = [[] [9]]
r = []
r = [9]
==========
==========
3
result = [[] [9] [0] [9 0]]
r = []
r = [9]
r = [0]
r = [9 0]
==========
==========
5
result = [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3]]
r = []
r = [9]
r = [0]
r = [9 0]
r = [3]
r = [9 3]
r = [0 3]
r = [9 0 3]
==========
==========
7
result = [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5]] // (a)
r = []
r = [9]
r = [0]
r = [9 0]
r = [3]
r = [9 3]
r = [0 3]
r = [9 0 3]
r = [5]
r = [9 5]
r = [0 5]
r = [9 0 5]
r = [3 5]
r = [9 3 5]
r = [0 3 5]
r = [9 0 3 7] // (b)
==========
[[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 7] [7] [9 7] [0 7] [9 0 7] [3 7] [9 3 7] [0 3 7] [9 0 3 7] [5 7] [9 5 7] [0 5 7] [9 0 5 7] [3 5 7] [9 3 5 7] [0 3 5 7] [9 0 3 7 7]]
Let's see 5th result. (I pointed out there as (a) ) As of there, the last element of result is [9, 0, 3, 5], and this is expected behavior.
However, after that, when I'm trying to write a debug log of the element in result, it changes to [9, 0, 3, 7] ( (b) ).
Do you know why?
The append changes the r when needed:
Instead of:
temp = append(temp, append(r, num))
You may use:
rr := make([]int, len(r))
copy(rr, r)
rr = append(rr, num)
temp = append(temp, rr)
and you are good to go:
package main
import (
"fmt"
)
func main() {
v := []int{9, 0, 3, 5, 7}
fmt.Println(subsets(v))
}
func subsets(nums []int) [][]int {
result := [][]int{
[]int{}, // empty
}
for _, num := range nums {
fmt.Println("==========")
fmt.Println(num)
fmt.Printf("result = %v\n", result)
temp := [][]int{}
for _, r := range result {
fmt.Printf("r = %v\n", r)
// append(r, num)
rr := make([]int, len(r))
copy(rr, r)
rr = append(rr, num)
temp = append(temp, rr)
}
for _, t := range temp {
result = append(result, t)
}
fmt.Println("==========")
}
return result
}
Just debug your code and you'll see, it happens here:
temp := [][]int{}
for _, r := range result {
fmt.Println("result =", result, len(result), cap(result))
fmt.Println("r ==", r, len(r), cap(r))
fmt.Println("num =", num)
rr := append(r, num)
fmt.Println("r ==", r, len(r), cap(r))
fmt.Println("rr ==", rr, len(rr), cap(rr))
fmt.Println("result =", result, len(result), cap(result))
fmt.Println("temp =", temp)
temp = append(temp, rr)
fmt.Println("temp =", temp)
}
When
result = [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 5]] 16 16
r == [9 0 3] 3 4
num = 7
r == [9 0 3] 3 4
rr == [9 0 3 7] 4 4
result = [[] [9] [0] [9 0] [3] [9 3] [0 3] [9 0 3] [5] [9 5] [0 5] [9 0 5] [3 5] [9 3 5] [0 3 5] [9 0 3 7]] 16 16
Because of:
append(r, num)

Unexpected behavior when passing a pointer to a slice in go

The following go program is supposed to generate all permutations of a slice of integers:
package main
import "fmt"
func permute(nums []int) [][]int {
var res [][]int
var s []int
permuteHlp(&res, nums, 0, s)
return res
}
func permuteHlp(res *[][]int, nums []int, i int, s []int) {
if i == len(nums) {
*res = append(*res, s)
return
}
for j := i; j < len(nums); j++ {
s = append(s, nums[j])
nums[i], nums[j] = nums[j], nums[i]
permuteHlp(res, nums, i+1, s)
s = s[:len(s)-1]
nums[i], nums[j] = nums[j], nums[i]
}
}
func main() {
x := []int{1,2,3,4}
y := permute(x)
fmt.Println(y)
}
The output is unexpected
[[1 2 4 3] [1 2 4 3] [1 3 4 2] [1 3 4 2] [1 4 2 3] [1 4 2 3] [2 1 4 3] [2 1 4 3] [2 3 4 1] [2 3 4 1] [2 4 1 3] [2 4 1 3] [3 2 4 1] [3 2 4 1] [3 1 4 2] [3 1 4 2] [3 4 2 1] [3 4 2 1] [4 2 1 3] [4 2 1 3] [4 3 1 2] [4 3 1 2] [4 1 2 3] [4 1 2 3]]
I don't understand what is wrong here. I would appreciate any help.
Thank you!
You're passing around a pointer to the the same slice. In the end you wind up with a bunch of pointers to the same slice in your results, so of course all the values will be identical - it's the same slice printed over and over.
It's also worth noting that a pointer to a slice is rarely what you want, as slices already contain a pointer to the underlying array.
There's no need for a pointer to the slice since slices are pointers themselves. "a slice is a reference to a contiguous segment of an array.", reference.
The strange behavior you're seeing is because you're using append, when a slice grows beyond its capacity it's required to create a new slice with increased capacity and copy all the contents of the original one (this is what append does behind the scenes), hence new slice is no longer pointing to the original underlying array.
Instead of modifying the incoming parameter, I suggest returning the slice as a return value for the function.
func permute(nums []int) [][]int {
res := permuteHlp(nums, 0, new([]int))
return res
}
I recommend you read the blog post in golang.org about slices internals, here
Edit:
I add a refactor, taking the algorithm from this answer.
package main
import (
"fmt"
)
func permutations(arr []int)[][]int{
var helper func([]int, int)
res := [][]int{}
helper = func(arr []int, n int){
if n == 1{
tmp := make([]int, len(arr))
copy(tmp, arr)
res = append(res, tmp)
} else {
for i := 0; i < n; i++{
helper(arr, n - 1)
if n % 2 == 1{
tmp := arr[i]
arr[i] = arr[n - 1]
arr[n - 1] = tmp
} else {
tmp := arr[0]
arr[0] = arr[n - 1]
arr[n - 1] = tmp
}
}
}
}
helper(arr, len(arr))
return res
}
func main() {
x := []int{1,2,3,4}
d := permutations(x)
fmt.Print(d)
}
Generally you won't want to have a pointer to a slice, instead, return a new one from the function, another thing to comment on, try not to use recursion if possible as golang doesn't have tail call optimization, and its loops perform amazingly. Hope it helps!

Go variables being overwritten (bug?)

So bit of a weird one here. My question is, do people get the same results from running my code as I do? And if you do, is it a fault of my code (I'm a python programmer usually), or a bug in golang?
System info: Go version (1.1.2) linux x64 (fedora 19)
Background info on the code: What I'm doing is finding the highest cost route from the top of a triangle to the bottom, this is from project_euler 18 and 67
The bug: I set a variable called pathA, this is an integer list, plus a new int for the new value found from the triangle
e.g. 3, 7, 2 append 8 should equal 3, 2, 7, 8
and, it does! ... until I set pathB. pathB gets set correctly however suddenly pathA is the same value as pathB.
tl;dr one variable is being overwritten when I set another
My code is as follows:
package main
import (
"fmt"
)
func extendPaths(triangle, prePaths [][]int) [][]int {
nextLine := triangle[len(prePaths)]
fmt.Println("#####PrePaths: ", prePaths)
fmt.Println("#####nextLine: ", nextLine)
postPaths := [][]int{{}}
for i := 0; i < len(prePaths); i++ {
route := prePaths[i]
nextA := nextLine[i]
nextB := nextLine[i+1]
fmt.Println("Next A:", nextA, "Next B:", nextB, "\n")
pathA := append(route, nextA)
fmt.Println("pathA check#1:", pathA)
pathB := append(route, nextB)
fmt.Println("pathA check#2:", pathA, "\n")
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}
postPaths = postPaths[1:]
prePaths = [][]int{postPaths[0]}
for i := 1; i < len(postPaths)-1; i += 2 {
if getSum(postPaths[i]) > getSum(postPaths[i+1]) {
prePaths = append(prePaths, postPaths[i])
} else {
prePaths = append(prePaths, postPaths[i+1])
}
}
prePaths = append(prePaths, postPaths[len(postPaths)-1])
return prePaths
}
func getSum(sumList []int) int {
total := 0
for i := 0; i < len(sumList); i++ {
total += sumList[i]
}
return total
}
func getPaths(triangle [][]int) {
prePaths := [][]int{{triangle[0][0]}}
for i := 0; i < len(triangle)-1; i++ {
prePaths = extendPaths(triangle, prePaths)
}
}
func main() {
triangle := [][]int{{3}, {7, 4}, {2, 4, 6}, {8, 5, 9, 3}}
getPaths(triangle)
}
This gives the output in my terminal shown below:
#####PrePaths: [[3]]
#####nextLine: [7 4]
Next A: 7 Next B: 4
pathA check#1: [3 7]
pathA check#2: [3 7]
#####PrePaths: [[3 7] [3 4]]
#####nextLine: [2 4 6]
Next A: 2 Next B: 4
pathA check#1: [3 7 2]
pathA check#2: [3 7 2]
Next A: 4 Next B: 6
pathA check#1: [3 4 4]
pathA check#2: [3 4 4]
#####PrePaths: [[3 7 2] [3 7 4] [3 4 6]]
#####nextLine: [8 5 9 3]
Next A: 8 Next B: 5
pathA check#1: [3 7 2 8]
pathA check#2: [3 7 2 5]
Next A: 5 Next B: 9
pathA check#1: [3 7 4 5]
pathA check#2: [3 7 4 9]
Next A: 9 Next B: 3
pathA check#1: [3 4 6 9]
pathA check#2: [3 4 6 3]
Here you can see that for the last 4 times that I set pathA, it is initially set correctly, but then gets overwritten by pathB.
Does anyone have any thoughts on this?
EDIT:
As pointed out by the comments below, what was needed was to make new slices and copy data from the originals. This was done using code from http://blog.golang.org/go-slices-usage-and-internals modified slightly:
func AppendInt(slice []int, data ...int) []int {
m := len(slice)
n := m + len(data)
if n > cap(slice) {
newSlice := make([]int, (n+1)*2)
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:n]
copy(slice[m:n], data)
return slice
}
I also changed the code on the other side, where I created the slices pathA and pathB. This changed to:
for i := 0; i < len(prePaths); i++ {
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := AppendInt(prePaths[i], nextA)
pathB := AppendInt(prePaths[i], nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}
EDIT2:
It's quite early in the morning here, and I flat out made a mistake in my first edit, I did not fully understand your solution, after a bit of hacking I got there in the end:
This code does not work (pathA gets overwritten):
for i := 0; i < len(prePaths); i++ {
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := append(prePaths[i], nextA)
pathB := append(prePaths[i], nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}
This code also does not work (pathA gets overwritten):
for i := 0; i < len(prePaths); i++ {
newRoute := make([]int, len(prePaths[i]), (cap(prePaths[i])+1)*2)
copy(newRoute, prePaths[i])
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := append(newRoute, nextA)
pathB := append(newRoute, nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}
However, if I mix the 2 scenarios above into the code below, it works fine (pathA does not get overwritten):
for i := 0; i < len(prePaths); i++ {
newRoute := make([]int, len(prePaths[i]), (cap(prePaths[i])+1)*2)
copy(newRoute, prePaths[i])
nextA := nextLine[i]
nextB := nextLine[i+1]
pathA := append(newRoute, nextA)
pathB := append(prePaths[i], nextB)
postPaths = append(postPaths, pathA)
postPaths = append(postPaths, pathB)
}
So, my solution was to make a copy of the array, and have them both use different ones.
A slice is basically a structure consisting of 3 things:
A pointer to an array of the elements in the slice
The length of that array (the "capacity")
The number of elements actually stored in the array (the "length")
When you run the following code:
append(x, element)
It does the following:
Check if extending the slice will exceed the capacity of the underlying array. If so, allocate a larger one and copy the existing elements to the new array, and update the capacity.
Write the new element (or elements) to the end of the array and update the length.
Return the new slice.
In your code, you have the following:
pathA := append(route, nextA)
pathB := append(route, nextB)
Now there are two possibilities here:
len(route) == cap(route), and a new backing array will be allocated, with pathA and pathB having independent values.
len(route) < cap(route), so pathA and pathB end up sharing the same backing array. The last element in the array will be nextB, since that operation was run second.
It seems that the first case is true for the first few iterations of your loop, after which you hit the second case. You could avoid this by manually making a copy for one of your paths (allocate a slice with make(), and then use copy() to copy the old data).

Resources