Related
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
This is a LeetCode problem: 189. Rotate Array:
Given an array, rotate the array to the right by k steps, where k is
non-negative.
Example 1:
Input: [1,2,3,4,5,6,7] and k = 3
Output: [5,6,7,1,2,3,4]
And here is my solution:
func rotate(nums []int, k int) {
k = k % len(nums)
nums = append(nums[k:],nums[0:k]...)
fmt.Println(nums)
}
It is a straight forward algorithm but it does not work.
I am new to Go. I suppose nums is passed by value and changes to nums won't affect the real nums.
How can I get this right?
In Go, all arguments are passed by value.
A Go slice is represented at runtime by a slice descriptor:
type slice struct {
array unsafe.Pointer
len int
cap int
}
If you change any of the slice descriptor values in a function then communicate the change, typically by returning the changed slice descriptor.
Your rotate function changes the values of the slice num pointer to the underlying array and the slice capacity, so return num.
For example, after I fixed the bugs in your rotate algorithm,
package main
import "fmt"
func rotate(nums []int, k int) []int {
if k < 0 || len(nums) == 0 {
return nums
}
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
r := len(nums) - k%len(nums)
nums = append(nums[r:], nums[:r]...)
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
return nums
}
func main() {
nums := []int{1, 2, 3, 4, 5, 6, 7}
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
nums = rotate(nums, 3)
fmt.Printf("nums %p array %p len %d cap %d slice %v\n", &nums, &nums[0], len(nums), cap(nums), nums)
}
Output:
nums 0xc00000a080 array 0xc00001a1c0 len 7 cap 7 slice [1 2 3 4 5 6 7]
nums 0xc00000a0c0 array 0xc00001a1c0 len 7 cap 7 slice [1 2 3 4 5 6 7]
nums 0xc00000a0c0 array 0xc00001a240 len 7 cap 8 slice [5 6 7 1 2 3 4]
nums 0xc00000a080 array 0xc00001a240 len 7 cap 8 slice [5 6 7 1 2 3 4]
Reference: The Go Blog: Go Slices: usage and internals
Here's a way do rotate a float 32 slice, you can change it for another type.
//RotateF32Slice positive n rotate to the left, negative to right
func RotateF32Slice(slice []float32, n int) (rotateSlice []float32) {
var begin []float32
var end []float32
size := len(slice)
rotateSlice = make([]float32, size)
nAbs := math.Abs(float64(n))
if int(nAbs) > size {
remainder, _ := QuotientAndRemainderF32(float32(n), float32(size))
n = int(remainder)
}
if n != 0 {
if n > 0 {
index := size - n
begin = slice[index:]
end = slice[0:index]
copy(rotateSlice, begin)
copy(rotateSlice[n:], end)
} else {
n = int(nAbs)
index := size - n
begin = slice[n:]
end = slice[0:n]
copy(rotateSlice, begin)
copy(rotateSlice[index:], end)
}
} else {
copy(rotateSlice, slice)
}
return rotateSlice
}
//QuotientAndRemainderF32 Computes the integer quotient and the remainder of the inputs. This function rounds floor(x/y) to the nearest integer towards -inf.
func QuotientAndRemainderF32(x, y float32) (Remainder, Quotient float32) {
Quotient = float32(math.Floor(float64(x / y)))
Remainder = x - y*Quotient
return Remainder, Quotient
}
Solutions
Solution 1 :
func rotate(ar []int,d,n int) []int{
var newArray []int
for i:=0;i<d;i++{
newArray = ar[1:n]
newArray = append(newArray,ar[0])
ar = newArray
}
return ar
}
Solution 2 :
func rotateR(ar []int,d,n int) []int{
ar = append(ar[d:n],ar[0:d]...)
return ar
}
func rotate(nums []int, k int) {
k = k % len(nums)
result := append(nums[len(nums)-k:], nums[:len(nums)-k]...)
for i := 0; i < len(nums); i++ {
nums[i] = result[i]
}
}
Answering this late as i came across this while reading the book "The Go Programming language". It presents a quite elegant algo to use the reverse function and apply it thrice to achieve the desired rotation by k elems. Something like this
// function to rotate array by k elems (3 reverse method)
func rotate(arr []int, k int) {
reverse(arr[:k])
reverse(arr[k:])
reverse(arr)
}
Please note, you will have to write a reverse function. Go does not provide one. This is an O(n) solution and takes O(1) space.
This is my solution to the same hackerrank problem
func rotateLeft(d int32, arr []int32) []int32 {
for ; d > 0 ; d-- {
left := arr[0]
arr = arr[1:]
arr = append(arr, left)
}
return arr
}
for me this worked for many of array rotating but not for hundreds nums[].
func rotate(nums []int, k int) {
for count:=k; count>0; count--{
if len(nums) >= 1 && len(nums) <= 10^5 {
for i:=len(nums)-1; i>0; i--{
nums[i], nums[i-1] = nums[i-1], nums[i]
}
}
}
}
Given an array, rotate the array to the right by k steps, where k is
non-negative.
Example 1:
Input: [1,2,3,4,5,6,7] and k = 3 Output: [5,6,7,1,2,3,4]
Blockquote
First, for k=3, shouldn't be the output [4,5,6,7,1,2,3] ?
For most array operations, it is always simplier to add elements to a newly created array rather than change the source array. If the array is not really large (takes Gigs of memory / billions of items, etc..), you can use a function that adds elements to the newly created array in the order you require and returns new one:
// GO 1.18
func rot[T any](slice []T, k int) (newSlice []T){
l := len(slice)
for i := range slice {
newSlice = append(newSlice, slice[(k+i) % l])
}
return
}
fmt.Printf("Slice %v after rotation %v\n", []int{1,2,3,4,5,6,7}, rot[int]([]int{1,2,3,4,5,6,7}, 3))
//Slice [1 2 3 4 5 6 7] after rotation [4 5 6 7 1 2 3]
If you insist on using "slicing", the code looks like this:
func rotationBySlicing[T any](slice []T, k int) (newSlice []T) {
if len(slice) == 0 {
return slice
}
return append(slice[(k%len(slice)):],slice[0:k%len(slice)]...)
}
fmt.Printf("Array %v after rotation %v\n", []string{}, rotationBySlicing[string]([]string{},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a"}, rotationBySlicing[string]([]string{"a"},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a","b"}, rotationBySlicing[string]([]string{"a","b"},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a","b","c"}, rotationBySlicing[string]([]string{"a","b","c"},1))
fmt.Printf("Array %v after rotation %v\n", []string{"a", "b", "c", "d"}, rotationBySlicing[string]([]string{"a", "b", "c", "d"},1))
fmt.Printf("Slice %v after rotation %v\n", []int{1,2,3,4,5,6,7}, rotationBySlicing[int]([]int{1,2,3,4,5,6,7}, 3))
Array [] after rotation []
Array [a] after rotation [a]
Array [a b] after rotation [b a]
Array [a b c] after rotation [b c a]
Array [a b c d] after rotation [b c d a]
Array [1 2 3 4 5 6 7] after rotation [4 5 6 7 1 2 3]
Also instruction says:
where k is non-negative
, for completeness the code should handle case when k is less than 0
In my case, I preferred this algorithm below because I wanted to keep slice capacity the same:
// Rotation by keeping the capacity same
func Rotate(nums []int, k int) {
k %= len(nums)
new_array := make([]int, len(nums))
copy(new_array[:k], nums[len(nums)-k:])
copy(new_array[k:], nums[:len(nums)-k])
copy(nums, new_array)
}
Also, I tested it in Leet code and it looks good :)
You can also add a condition at the top of your function to make it ready for negative shifts (rotates),
Whole code again:
func Rotate(nums []int, k int) {
k %= len(nums)
// Condition below is added.
if k < 0 {
k += len(nums)
}
new_array := make([]int, len(nums))
copy(new_array[:k], nums[len(nums)-k:])
copy(new_array[k:], nums[:len(nums)-k])
copy(nums, new_array)
}
This doesn't work because []byte is a slice which is sort of a "pointer to an array". Doing:
func f(v []T) {
v = ... //
}
won't have any observable effect for the caller. Assuming your append way is correct (didn't really check it) you could do something like this:
func rotate(nums []int, k int) {
k = k % len(nums)
temp := append(nums[k:], nums[0:k]...)
copy(nums, temp) // this actually writes to where nums points to
}
func main() {
nums := []int{1,2,3,4,5,6,7}
rotate(nums ,3)
fmt.Println(nums)
}
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!
I am looking for a way to generate all possible permutations of a list of elements. Something similar to python's itertools.permutations(arr)
permutations ([])
[]
permutations ([1])
[1]
permutations ([1,2])
[1, 2]
[2, 1]
permutations ([1,2,3])
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
With the difference that I do not care whether permutations would be generated on demand (like a generator in python) or all together. I also do not care whether they will be lexicographically sorted. All I need is to somehow get these n! permutations.
There are a lot of the algorithms that generate permutations. One of the easiest I found is Heap's algorithm:
It generates each permutation from the previous one by choosing a pair
of elements to interchange.
The idea and a pseudocode that prints the permutations one after another is outlined in the above link. Here is my implementation of the algorithm which returns all permutations
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
}
and here is an example of how to use it (Go playground):
arr := []int{1, 2, 3}
fmt.Println(permutations(arr))
[[1 2 3] [2 1 3] [3 2 1] [2 3 1] [3 1 2] [1 3 2]]
One thing to notice that the permutations are not sorted lexicographically (as you have seen in itertools.permutations). If for some reason you need it to be sorted, one way I have found it is to generate them from a factorial number system (it is described in permutation section and allows to quickly find n-th lexicographical permutation).
P.S. you can also take a look at others people code here and here
Here's code that iterates over all permutations without generating them all first. The slice p keeps the intermediate state as offsets in a Fisher-Yates shuffle algorithm. This has the nice property that the zero value for p describes the identity permutation.
package main
import "fmt"
func nextPerm(p []int) {
for i := len(p) - 1; i >= 0; i-- {
if i == 0 || p[i] < len(p)-i-1 {
p[i]++
return
}
p[i] = 0
}
}
func getPerm(orig, p []int) []int {
result := append([]int{}, orig...)
for i, v := range p {
result[i], result[i+v] = result[i+v], result[i]
}
return result
}
func main() {
orig := []int{11, 22, 33}
for p := make([]int, len(orig)); p[0] < len(p); nextPerm(p) {
fmt.Println(getPerm(orig, p))
}
}
var res [][]int
func permute(nums []int) [][]int {
res=make([][]int,0)
n:=len(nums)
var backTrack func(int)
backTrack=func(first int){
if first == n{
temp:=make([]int, n)
copy(temp,nums)
res = append(res, temp)
}
for i:=first;i<n;i++{
nums[first],nums[i] = nums[i],nums[first]
backTrack(first+1)
nums[first],nums[i] = nums[i],nums[first]
}
}
backTrack(0)
return res
}
In my case I had a reference to an array, then I've did a few changes in your example:
func generateIntPermutations(array []int, n int, result *[][]int) {
if n == 1 {
dst := make([]int, len(array))
copy(dst, array[:])
*result = append(*result, dst)
} else {
for i := 0; i < n; i++ {
generateIntPermutations(array, n-1, result)
if n%2 == 0 {
// Golang allow us to do multiple assignments
array[0], array[n-1] = array[n-1], array[0]
} else {
array[i], array[n-1] = array[n-1], array[i]
}
}
}
}
numbers := []int{0, 1, 2}
var result [][]int
generateIntPermutations(numbers, len(numbers), &result)
// result -> [[0 1 2] [1 0 2] [2 1 0] [1 2 0] [2 0 1] [0 2 1]]
Another Working code
package permutations
import "fmt"
func AllPermutation(a []int) {
var res [][]int
calPermutation(a, &res, 0)
fmt.Println(res)
}
func calPermutation(arr []int, res *[][]int, k int) {
for i := k; i < len(arr); i++ {
swap(arr, i, k)
calPermutation(arr, res, k+1)
swap(arr, k, i)
}
if k == len(arr)-1 {
r := make([]int, len(arr))
copy(r, arr)
*res = append(*res, r)
return
}
}
func swap(arr []int, i, k int) {
arr[i], arr[k] = arr[k], arr[i]
}
//result [[1 2 3] [1 3 2] [2 1 3] [2 3 1] [3 2 1] [3 1 2]]
Here is another variation:
// heap algorithm
func permutations(arr []int, l int, p [][]int) [][]int {
if l == 1 { p = append(p, append([]int{}, arr...)) }
for i := 0 ; i < l ; i++ {
p = permutations(arr, l-1, p)
if l % 2 == 1 {
arr[0], arr[l-1] = arr[l-1], arr[0]
} else {
arr[i], arr[l-1] = arr[l-1], arr[i]
}
}
return p
}
I'm trying to append bytes to an array in the following way:
Go
func readBytes() {
b := make([]byte, 1)
a := [][]byte{}
for i := 0, i < 4, i++ {
conn.Read(b)
a = append(a, b)
fmt.Println(b)
}
fmt.Println(a)
}
Result from fmt.Println(b):
[2]
[5]
[5]
[3]
Result from fmt.Println(a):
[[3], [3], [3], [3]]
Why does it only print out the last byte sent?? Am I missing something?
b is a slice - and you're therefore updating the same underlying array each time you pass it to conn.Read. You can look at this Golang blog post to understand how this works.
Once you call fmt.Println(a) .. each slice is looking at the same underlying array.
You could fix this by instantiating the buffer b in the loop, or using an array instead of a slice.
Here's a working example that re-allocates the b slice inside the loop: http://play.golang.org/p/cN1BE8WSFE
It is essentially (with an int slice):
for i := 0; i < 5; i++ {
b = []int{i, i + 1, i + 2, i + 3, i + 4}
a = append(a, b)
}