Problem creating superset from list of integers [duplicate] - algorithm

This question already has answers here:
Slice within a loop seems to retain the previous/last reference (depending on the length of slice)
(2 answers)
unexpected slice append behaviour
(3 answers)
Bug in HouseRobber Programming Task in GoLang
(1 answer)
How to append to a 2d slice
(3 answers)
Closed 11 days ago.
I was defining a function that returns all the subsets (power set) of a list of integers.
Example: [1,2,3] -> [[], [1], [2], [3], [1,2], [2,3], [1,3], [1,2,3]]
The code I wrote is as follows :-
func subsets(nums []int) [][]int {
out := make([][]int, 0)
out = append(out, []int{})
for _, num := range nums {
n := len(out)
for i:=0; i<n; i++ {
out = append(out, append(out[i], num))
}
}
return out
}
Which adds the next number in the list to all the previous subsets.
Output when input = [9,0,3,5,7]
Upto input length <= 4, the function runs fine. But when it is more than that, some weird behaviour occurs, like the out should be appended [9,0,3,5] but it appends [9,0,3,7] (input list [9,0,3,5,7])
What could be the reason behind this peculiar behaviour?

Related

My Go recursive function not working as expected due to slices

I have written a function and I can't seem to find where the bug is:
The function change works like this:
An input of 15 (target value) with possible values of [1, 5, 10, 25, 100] should return [5, 10]. That's because to reach a target value of 15, the least amount of numbers to make up that target number is to have a 10 and 5
I use a caching mechanism, as it is a recursive function and remembers the values that have already been calculated.
func Change(coins []int, target int, resultsCache map[int][]int) ([]int, error) {
if val, ok := resultsCache[target]; ok {
return val, nil
}
if target == 0 {
return make([]int, 0), nil
}
if target < 0 {
return nil, errors.New("Target can't be less than zero")
}
var leastNumOfCoinChangeCombinations []int
for _, coin := range coins {
remainder := target - coin
remainderCombination, _ := Change(coins, remainder, resultsCache)
if remainderCombination != nil {
combination := append(remainderCombination, coin)
if leastNumOfCoinChangeCombinations == nil || len(combination) < len(leastNumOfCoinChangeCombinations) {
leastNumOfCoinChangeCombinations = combination
}
}
}
if leastNumOfCoinChangeCombinations == nil {
return nil, errors.New("Can't find changes from coin combinations")
}
sort.Ints(leastNumOfCoinChangeCombinations)
resultsCache[target] = leastNumOfCoinChangeCombinations
return leastNumOfCoinChangeCombinations, nil
}
The cache however have some abnormal behaviour, for example if I want to use the value of 12 in the cache later, instead of getting [2,5,5], I get [1 2 5] instead. Not sure where I went wrong. (but initially it was calculated and stored correctly, not sure how it got changed).
Here is a playground I used for troubleshooting:
https://play.golang.org/p/Rt8Sh_Ul-ge
You are encountering a fairly common, but sometimes difficult to spot, issue caused by the way slices work. Before reading further it's probably worth scanning the blog post Go Slices: usage and internals. The issue stems from the way append can reuse the slices underlying array as per this quote from the spec:
If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.
The below code provides a simple demonstration of what is occurring:
package main
import (
"fmt"
"sort"
)
func main() {
x := []int{2, 3}
x2 := append(x, 4)
x3 := append(x2, 1)
fmt.Println("x2 before sort", x2)
sort.Ints(x3)
fmt.Println("x2 after sort", x2)
fmt.Println("x3", x3)
fmt.Println("x2 cap", cap(x2))
}
The results are (playground):
x2 before sort [2 3 4]
x2 after sort [1 2 3]
x3 [1 2 3 4]
x2 cap 4
The result is probably not what you expected - why did x2 change when we sorted x3? The reason this happens is that the backing array for x2 has a capacity of 4 (length is 3) and when we append 1 the new slice x3 uses the same backing array (capacity 4, length 4). This only becomes an issue when we make a change to the portion of the backing array used by x2 and this happens when we call sort on x3.
So in your code you are adding a slice to the map but it's backing array is then being altered after that instance of Change returns (the append/sort ends up happening pretty much as in the example above).
There are a few ways you can fix this; removing the sort will do the trick but is probably not what you want. A better alternative is to take a copy of the slice; you can do this by replacing combination := append(remainderCombination, coin) with:
combination := make([]int, len(remainderCombination)+1)
copy(combination , remainderCombination)
combination[len(remainderCombination)] = coin
or the simpler (but perhaps not as easy to grasp - playground):
combination := append([]int{coin}, remainderCombination...)

Unexpected behaviour when populating a map using recursion [duplicate]

This question already has answers here:
Slice getting updated magically
(1 answer)
Problem accumulating/appending values in an array using recursion with Go
(2 answers)
Pass slice as function argument, and modify the original slice
(4 answers)
Recursively append to slice not working
(2 answers)
appending to slice of slices recursively
(2 answers)
Closed 1 year ago.
The goal is to compute all possible slices of length k that can be formed from a set of n strings.
I tried to do it using a simple recursion. Just printing the result works fine. Putting the results in a map yields some unexpected results for odd k's greater than 2.
What causes differences between the map's keys and their corresponding values?
https://play.golang.org/p/_SGrPRFjJ5g
package main
import (
"fmt"
"strings"
)
func main() {
QQM := make(map[string][]string)
states := []string{
"a",
"b",
}
var perm func(Q []string, k int)
perm = func(Q []string, k int) {
if k == 0 {
QQM[strings.Join(Q, "")] = Q
fmt.Println(QQM)
return
}
for i := 0; i < len(states); i++ {
perm(append(Q, states[i]), k-1)
}
}
perm([]string{}, 4)
}
map[aaaa:[a a a a]]
map[aaaa:[a a a b] aaab:[a a a b]]
map[aaaa:[a a a b] aaab:[a a a b] aaba:[a a b a]]
...
A slice is a view of an underlying array. When you pass slices around, you are not passing the values they contain, but references to those values. So when you put a slice to a map then add elements to that slice, if the slice has the capacity, you would be adding elements to the slice in the map as well.
Copy the slice before putting into the map:
newQ:=make([]string,len(Q))
copy(newQ,Q)
QQM[strings.Join(Q, "")] = newQ

Trying to initialize 2D slice, but the element reference changes all the rows in the slice [duplicate]

This question already has answers here:
What is a concise way to create a 2D slice in Go?
(4 answers)
Closed 2 years ago.
I created a 2D slice using the below code. Say I created [3]3] slice -- [[1 2 3],[4 5 6][7 8 9]]
But if I update the slice say s[1][1]=99 all changes --> [1 99 3], [4 99 6], [7 99 9]]
However, the second slice I have initialized below with variable cost does behave correctly. Not sure what is wrong:
func CreateSparseM() *SparseM{
var m,n,nz int
fmt.Println("Enter the row count of matrix ")
fmt.Scan(&m)
fmt.Println("Enter the column count of matrix ")
fmt.Scan(&n)
fmt.Println("Enter the count of Non Zero elements in the matrix ")
fmt.Scan(&nz)
r:=make([][]int,m)
c:=make([]int,n)
for i:=0;i<m;i++{
r[i] = c
}
fmt.Println(" r ", r)
r[1][1] = 99
fmt.Println(r[1][1])
fmt.Println(r[0][1])
//enter the non-zero elements
var row,col,elem int
for i:=0;i<nz;i++{
fmt.Println("Enter row ")
fmt.Scan(&row)
fmt.Println("Enter col ")
fmt.Scan(&col)
fmt.Println("Enter element ")
fmt.Scan(&elem)
r[row][col] = elem
}
fmt.Println(r)
cost:= [][]int{ {1,1,2,2,3,4,4,5,5},
{2,6,3,7,4,5,7,6,7},
{25,5,12,10,8,16,14,20,18}}
fmt.Println(cost)
cost[1][2]= 777
fmt.Println(cost)
sparseM := &SparseM{m,n,nz,r}
return sparseM
}
A slice contains a reference to an array, the capacity, and the length of the slice. So the following code:
r:=make([][]int,m)
c:=make([]int,n)
for i:=0;i<m;i++{
r[i] = c
}
sets all of r[i] to the same slice c. That is, all r[i] share the same backing array. So if you set r[i][j]=x, you set j'th element of all slices r[i] to x.
The slice you initialized using a literal has three distinct slices, so it does not behave like this.
If you do:
for i:=0;i<m;i++{
r[i] = make([]int,n)
}
then you'll have distinct slices for the first case as well.

golang combination generation made an error

I'm dealing with a programming problem
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
and with input n = 5, k = 4, the output should be [[1,2,3,4],[1,2,3,5],[1,2,4,5],[1,3,4,5],[2,3,4,5]], the following is my golang solution
func combine(n int, k int) [][]int {
result := [][]int{}
comb := []int{}
subcom(0, k, n, &comb, &result)
return result
}
func subcom(s, k, n int, comb *[]int, result *[][]int) {
if k > 0 {
for i := s + 1; i <= n-k+1; i++ {
c := append(*comb, i)
subcom(i, k-1, n, &c, result)
}
} else {
*result = append(*result, *comb)
}
}
I think my solution is right, but it return [[1 2 3 5] [1 2 3 5] [1 2 4 5] [1 3 4 5] [2 3 4 5]].
After debugging, I found [1 2 3 4] was added to the result slice at the beginning, but later changed to [1 2 3 5], resulting in the repetition of two [1 2 3 5]s. But I can't figure out what's wrong here.
This is a common mistake when using append.
When your code runs c:=append(*comb,i), it tries to first use the allocated memory in the underlying array to add a new item and only create a new slice when it failed to do so. This is what changes the [1 2 3 4] to [1 2 3 5] - because they share the same underlying memory.
To fix this, copy when you want to append into result:
now := make([]int,len(*comb))
copy(now,*comb)
*result = append(*result,now)
Or use a shortcut of copying:
*result = append(*result, append([]int{},*comb...))
Update:
To understand what I mean by underlying memory, one should understandd the internal model of Go's slice.
In Go, a slice has a data structure called SliceHeader which is accessible through reflect package and is what being referred to when you use unsafe.Sizeof and taking address.
The SliceHeader taking cares of three elements: Len,Cap and a Ptr. The fisrt two is trivail: they are what len() and cap() is for. The last one is a uintptr that points to the memory of the data the slice is containing.
When you shallow-copy a slice, a new SliceHeader is created but with the same content, including Ptr. So the underlying memory is not copied, but shared.

Subdivide a list into list of lists [duplicate]

This question already has answers here:
Split list into multiple lists with fixed number of elements
(5 answers)
Closed 8 years ago.
I would like to subdivide a list into lists of list with a max size for each sublist. For example, given List(1,2,5,3,90,3,4,1,0,3) and max size of sublists defined as 4, I would like to get List(List(1,2,5,3), List(90,3,4,1), List(0,3)) back.
This is what has already been done:
val l: List[Int] = ???
val subSize: Int = 4
val rest: Int = if(l.size % subSize == 0) 1 else 0
val subdivided: List[List[Int]] = for{
j <- List.range(0, l.size/subSize - rest, 1)
}yield{
for{
i <- List.range(subSize*j,subSize*j+3,1)
if(i < l.size)
}yield{
l(i)
}
}
Is there a better, more functional way of doing this?
Yes there is, using grouped.
scala> List(1,2,5,3,90,3,4,1,0,3).grouped(4).toList
res1: List[List[Int]] = List(List(1, 2, 5, 3), List(90, 3, 4, 1), List(0, 3))
Note that grouped actually returns an Iterator, so that you can lazily traverse the collection without doing all the computation at once.

Resources