Similar Go functions appending strings and arrays do not behave as expected - algorithm

I have two Go functions:
func permutation(prefix, str []int) {
n := len(str)
if n == 0 {
fmt.Println(prefix)
} else {
for i := 0; i < n; i++ {
permutation(
append(prefix, str[i]),
append(str[0:i], str[i+1:]...),
)
}
}
}
func perms(prefix, str string) {
n := len(str)
if n == 0 {
fmt.Println(prefix)
} else {
for i := 0; i < n; i++ {
perms(
prefix+string(str[i]),
string(str[0:i])+string(str[i+1:]),
)
}
}
}
The first takes an array of ints, the second takes a string. They both then calculate all permutations of the array, or the string.
I can run them like so:
permutation([]int{}, []int{1, 2, 3})
perms("", "123")
Their output is not the same:
$ go run main.go
[1 2 3]
[1 3 3]
[3 3 3]
[3 3 3]
[3 3 3]
[3 3 3]
123
132
213
231
312
321
I guess there is some nuance to appending arrays that I am missing. I can't seem to figure it out. Any idea what's going on?

While str1+str2 does return new (unrelated in terms of memory) string, append doesn't behave this way. For example append(str[0:i], str[i+1:]...) will destroy original content of str, overwriting str[i:] with str[i+1:]. This is because str[0:i] will have capacity to append str[i+1:] without allocating new buffer.
The solution would be to create a completely new array in every iteration. At least for str, as append(prefix, str[i]) is immune to this problem. For example:
for i := 0; i < n; i++ {
var s []int
s = append(s, str[0:i]...)
s = append(s, str[i+1:]...)
permutation(append(prefix, str[i]), s)
}
https://play.golang.org/p/lXwu39AA0V
More about slices and mechanism of append:
http://blog.golang.org/go-slices-usage-and-internals
https://blog.golang.org/slices

Related

Rotate Array in Go

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)
}

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!

How to return the sorted indices for Counting Sort?

I want to return the sorted indices for x array from the Counting Sort algorithm below, it must be simple but I can not figure out how to do that! Can someone please guide me on how to do that in Matlab or Golang or any idomatic c-style demonstration for the algorithm below? thanks a lot in advance.
x=[6 2 5 3 2 2 ];
MAX=10;
n = length(x);
C = zeros(MAX,1); // intialize counting array
for j = 1:n
C(x(j)) = C(x(j)) + 1;
end
z=1;
sorted_x = zeros(n,1); // empty array -container for sorted elements
for j = 1:n;
while ( C(j) >0)
sorted_x(z) = j;
z=z+1;
C(j) = C(j) - 1;
end
end
the code above returns the sorted_x=[2 2 2 3 5 6]
But I want to modify it to also return the sorted_indices=[2 5 6 4 3 1]
Thanks
You can use a map to store the indices -
package main
import "fmt"
func main(){
nums := [6]int{6, 2, 5, 3, 2, 2}
count := make(map[int][]int)
for i, v := range nums {
count[v] = append(count[v], i+1)
}
output := []int{}
for i := 0; i < 10; i++ {
output = append(output, count[i]...)
}
for i := 0; i < len(output); i++ {
fmt.Printf("%d ", nums[output[i]-1])
}
fmt.Println()
fmt.Println("The indices are:")
fmt.Println(output)
}
Output -
2 2 2 3 5 6
The indices are:
[2 5 6 4 3 1]
In matlab the second output value of sort function is the indices. Simply try this:
[sorted, s_ind] = sort(x);
For example, using the Go sort package,
package main
import (
"fmt"
"sort"
)
type AX struct{ A, X []int }
func (ax AX) Len() int {
return len(ax.A)
}
func (ax AX) Swap(i, j int) {
ax.A[i], ax.A[j] = ax.A[j], ax.A[i]
ax.X[i], ax.X[j] = ax.X[j], ax.X[i]
}
func (ax AX) Less(i, j int) bool {
return ax.A[i] < ax.A[j]
}
func sortAX(a []int) (x []int) {
x = make([]int, len(a))
for i := range x {
x[i] = i
}
sort.Stable(AX{A: a, X: x})
return x
}
func main() {
a := []int{6, 2, 5, 3, 2, 2}
fmt.Println("a:", a)
x := sortAX(a)
fmt.Println("a:", a)
fmt.Println("x:", x)
}
Output (Go indices start at 0):
a: [6 2 5 3 2 2]
a: [2 2 2 3 5 6]
x: [1 4 5 3 2 0]
References:
Go: Package sort

Generate all permutations in go

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
}

What is wrong with the following merge sort algorithm?

As the question states, I'm having trouble finding where is the issue within the following algorithm. It is the aux function for mergesort, i.e. the one used for combining sorted arrays.
func Merge(toSort *[]int, p, q, r int) {
arr := *toSort
L := arr[p:q]
R := arr[q:r+1]
fmt.Println(L)
fmt.Println(R)
i := 0
j := 0
for index := p; index <= r; index++ {
if i >= len(L) {
arr[index] = R[j]
j += 1
continue
} else if j >= len(R) {
arr[index] = L[i]
i += 1
continue
}
if L[i] > R[j] {
fmt.Println("right smaller")
arr[index] = R[j]
j += 1
continue
}
if L[i] <= R[j] {
fmt.Println("left smaller")
arr[index] = L[i]
i += 1
continue
}
}
}
For arr := []int{1,7,14,15,44,65,79,2,3,6,55,70} it gives as output [1 2 2 2 2 2 2 2 3 6 55 70].
Golang Play link
The JavaScript equivalent for this function works as expected, but I don't know why it isn't working in Go
Thank you
Golang slices are passed by reference. So you don't need to pass a pointer into the function in the first place, but you do need to take explicit copies of L and R or else merge into a different slice entirely. You are currently writing into the same underlying memory from which you are getting your values.
Code like L := arr[p:q] does not create a copy. I suppose you are overwriting your L and R parts during the assignments to arr. Have a look at http://blog.golang.org/slices to understand how slices work. (E.g. you'll basically never write stuff like toSort *[]int as []int is almost kinda pointer)
This seems to work: http://play.golang.org/p/vPo2ZKXtI9
You don't need all the indexes: slices are already views into an array. Here's a complete example using purely slice manipulation:
package main
import "fmt"
// Merge takes two sorted, increasing slices of ints and
// returns a slice combining them into a single sorted, increasing
// slice.
func Merge(a, b []int) []int {
res := make([]int, 0, len(a)+len(b))
for len(a) > 0 || len(b) > 0 {
if len(b) == 0 || len(a) > 0 && a[0] <= b[0] {
res = append(res, a[0])
a = a[1:]
} else {
res = append(res, b[0])
b = b[1:]
}
}
return res
}
func main() {
a := []int{1, 2, 5, 6, 3, 4, 7, 9}
fmt.Println(Merge(a[:4], a[4:]))
}

Resources