maybe it's not just a Go-Problem but i have this problem:
I want to multiply two (or more) arrays, so for example:
a := [3]int{2, 3, 5}
b := [2]bool{true, false}
// desired output of "c" =>
// [[2 true] [2 false] [3 true] [3 false] [5 true] [5 false]]
I already found this library here: https://godoc.org/github.com/gonum/matrix/mat64 but i'm not seeing how to use something else than float64
The fallback-solution would be to use multiple for-range-loops but it'd be amazing if there is a "smoother" way to do this
Short answer: go is not intended for this kind of problem. What you want is an equivalent of the zip function, which is present natively in some languages (e.g. Haskell, Python, ...)
However, in Golang you'll have one big problem: you can't have dynamic types. That is: an array can contain only one type (int OR bool), not several. The workaround is to make an array of interface, but that means you'd have to make ugly type assertions to get the proper type back.
Also, you do have a general way to do that, but the type you'll get at the end will be [][]interface{} and no way of knowing what's inside.
For your example: here is the simplest way to do what you want (not general):
func main() {
a := [3]int{2, 3, 5}
b := [2]bool{true, false}
var c [6][2]interface{}
i := 0
for _, val1 := range a {
for _, val2 := range b {
c[i] = [2]interface{}{val1, val2}
i += 1
}
}
var a1 int = c[0][0].(int)
var b1 bool = c[0][1].(bool)
fmt.Printf("c[0] is %v, a1 is %d and b1 is %v\n", c[0], a1, b1)
fmt.Println(c)
}
As you can see, that's ugly and useless in practice (and very error-prone)
So, if you want to make this kind of transformations, you should use another language, Go was not (and won't) designed for this type of purposes.
This isn't a matrix multiplication, as pointed out above. The two for loops work if there are only two things, but if there are multiple ones it can clearly get tedious.
The way I would do it is to think of a multidimensional array. The total "number" of elements is the product of the sizes, and then use a function like SubFor https://godoc.org/github.com/btracey/meshgrid#SubFor
dims := []int{3,2}
sz := 1
for _,v := range dims {
sz *= v
}
sub := make([]int, len(dims))
for i := 0: i < sz; i++{
meshgrid.SubFor(sub, i, dims)
fmt.Println(a[sub[0]], b[sub[1]])
}
There are some things with types to figure out (appending to a slice, etc.), but that should give you the general gist.
Related
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...)
I'm trying to learn recursion and going through the Stanford online video lectures and textbook. In the programming exercises a question is posed to generate all permutations for a string given an index. For example "ABCD" and index 2. This should generate "ABCD" and "ABDC".
I understand how to generate the permutations by using func permute(prefix, suffix) but this question is confusing me. Here is want I have so far:
func permute(s string) {
permuteHelper(s, 2)
}
func permuteHelper(s string, idx int) {
if idx == 0 {
fmt.Println(s)
return
}
for i := idx; i < len(s); i++ {
newS := s[:idx]
suffix := s[idx : idx+1]
newS += suffix
permuteHelper(newS, idx-1)
}
}
Output:
AB
AB
AB
AB
I don't want the answer, but perhaps some guidance in my thought process. I know I should create a static "AB" and then select "C" on one iteration and then select "D", then my base case should be triggered and print the string. Control will then return to "AB" and "i" should be 3 and I choose "D", but how do I then chose "C"?
You're on the right track and the overall form looks fine, but the details are still blurry.
Firstly,
newS := s[:idx]
suffix := s[idx : idx+1]
newS += suffix
is equivalent to
newS := s[:idx+1]
No real permuting is going on here; this is chopping off the back of the string and ignoring the loop variable i entirely. Try to swap two characters in the string for each recursive call and use both i and idx to do so; think of idx as a fixed pivot for swapping every i...len(s) element with per call frame. Good job ensuring you're not reassigning to the string in the current scope, though, because that'd mess up state for later iterations of the loop.
Second suggestion: To establish the base case, count recursively up to len(s) instead of down to zero. You can pretty much pretend the entire first chunk of the array doesn't exist. Think of it just like a regular permutation algorithm except you've skipped the first idx indices.
Also, this is more of a design point than an algorithmic issue, but I would expose the idx parameter to the caller instead of hiding it behind a wrapper. This makes the function reusable and more obvious as to what it does--as a user of a library, I'd be perplexed if a function named permute refused to permute the first 2 chars.
It's better to return a result than produce a side effect like printing, but I'll set that aside for pedagogy's sake.
Here's one solution (spoiler alert!):
package main
import "fmt"
func permute(s string, idx int) {
if idx == len(s) {
fmt.Println(s)
}
for i := idx; i < len(s); i++ {
a := []rune(s)
a[i], a[idx] = a[idx], a[i]
permute(string(a), idx + 1)
}
}
func main() {
permute("abcde", 2)
}
permute("abcde", 2) produces
abcde
abced
abdce
abdec
abedc
abecd
I'm trying to make a very simple program that modifies arrays, but ran across some interesting behavior if I converted them to types. https://play.golang.org/p/KC7mqmHuLw It appears that if I have an array go passes by reference, but if I have a type then go passes by value. Is this correct?
I have two variables b and c, both are arrays of 3 integers, but c is of type cT, in every other respect they should be identical. I can assign values as b[0]=-1 and c[0]=-1, but if I pass those arrays as parameters to a function they act very differently.
The output of the program is:
before b: [1 2 3]
before c: [1 2 3]
*after b: [-1 2 0]
*after c: [-1 2 3]
*what? c: [-1 2 0]
My initial assumption is that the lines "after b" and "after c" should have been the same. Am I doing something incorrectly or am I correct about types passing to functions by value (ie. creating copy of the variable before passing to the function)?
package main
import "fmt"
type cT [3]int
func main() {
b := []int{1, 2, 3}
c := cT{1, 2, 3}
fmt.Println("before b:", b)
fmt.Println("before c:", c)
b[0] = -1
c[0] = -1
mangleB(b) // ignore return value
mangleC(c) // ignore return value
fmt.Println("*after b:", b)
fmt.Println("*after c:", c)
c = mangleC(c)
fmt.Println("*what? c:", c)
}
func mangleB(row []int) []int {
row[2] = 0
return row
}
func mangleC(row cT) cT{
row[2] = 0
return row
}
The Go Programming Language Specification
Array types
An array is a numbered sequence of elements of a single type, called
the element type.
Slice types
A slice is a descriptor for a contiguous segment of an underlying
array and provides access to a numbered sequence of elements from that
array.
Calls
In a function call, the function value and arguments are evaluated in
the usual order. After they are evaluated, the parameters of the call
are passed by value to the function and the called function begins
execution. The return parameters of the function are passed by value
back to the calling function when the function returns.
type cT [3]int
b := []int{1, 2, 3}
c := cT{1, 2, 3}
I have two variables, b and c, both are arrays of 3 integers
No, you don't!
b is a slice of int with length (len(b)) 3 and capacity (cap(b)) 3, c is an array of (len(c)) 3 int.
In Go, all parameters are passed by value. b is passed as a slice descriptor, c is passed as an array. A slice descriptor is a struct with a slice length and capacity, and a pointer to the underlying array.
See comments:
func main() {
b := []int{1, 2, 3} // slice
c := cT{1, 2, 3} // array
fmt.Println("before b:", b)
fmt.Println("before c:", c)
b[0] = -1
c[0] = -1
// passing in a slice which you can think of as ref to array
// pass by value, and it is copy of ref to array
mangleB(b) // ignore return value
// passing in copy of array (pass by value)
// yes full shallow copy of array
mangleC(c) // ignore return value
// if you ignore return modifications are lost
fmt.Println("*after b:", b)
fmt.Println("*after c:", c)
// return value is modified array
c = mangleC(c)
// c now copy of array from line 24
fmt.Println("*what? c:", c)
}
when I'm calling slice a ref I'm simplifying details here https://blog.golang.org/go-slices-usage-and-internals
https://play.golang.org/p/OAaCMhc-Ug
How do I create an array of int arrays in Golang using slice literals?
I've tried
test := [][]int{[1,2,3],[1,2,3]}
and
type Test struct {
foo [][]int
}
bar := Test{foo: [[1,2,3], [1,2,3]]}
You almost have the right thing however your syntax for the inner arrays is slightly off, needing curly braces like; test := [][]int{[]int{1,2,3},[]int{1,2,3}} or a slightly more concise version; test := [][]int{{1,2,3},{1,2,3}}
The expression is called a 'composite literal' and you can read more about them here; https://golang.org/ref/spec#Composite_literals
But as a basic rule of thumb, if you have nested structures, you have to use the syntax recursively. It's very verbose.
In some other langauges (Perl, Python, JavaScript), [1,2,3] might be an array literal, but in Go, composite literals use braces, and here, you have to specify the type of the outer slice:
package main
import "fmt"
type T struct{ foo [][]int }
func main() {
a := [][]int{{1, 2, 3}, {4, 5, 6}}
b := T{foo: [][]int{{1, 2, 3}, {4, 5, 6}}}
fmt.Println(a, b)
}
You can run or play with that on the Playground.
The Go compiler is just tricky enough to figure out that the elements of an [][]int are []int without you saying so on each element. You do have to write out the outer type's name, though.
Just replace the square brackets with curly braces. In Go, array literals are identified with curly braces.
test := [][]int{{1,2,3},{1,2,3}}
A slice literal is written as []type{<value 1>, <value 2>, ... }. A slice of ints would be []int{1,2,3} and a slice of int slices would be [][]int{[]int{1,2,3},[]int{4,5,6}}.
groups := [][]int{[]int{1,2,3},[]int{4,5,6}}
for _, group := range groups {
sum := 0
for _, num := range group {
sum += num
}
fmt.Printf("The array %+v has a sum of %d\n", sub, sum)
}
How can I check if two slices are equal, given that the operators == and != are not an option?
package main
import "fmt"
func main() {
s1 := []int{1, 2}
s2 := []int{1, 2}
fmt.Println(s1 == s2)
}
This does not compile with:
invalid operation: s1 == s2 (slice can only be compared to nil)
You should use reflect.DeepEqual()
DeepEqual is a recursive relaxation of Go's == operator.
DeepEqual reports whether x and y are “deeply equal,” defined as
follows. Two values of identical type are deeply equal if one of the
following cases applies. Values of distinct types are never deeply
equal.
Array values are deeply equal when their corresponding elements are
deeply equal.
Struct values are deeply equal if their corresponding fields, both
exported and unexported, are deeply equal.
Func values are deeply equal if both are nil; otherwise they are not
deeply equal.
Interface values are deeply equal if they hold deeply equal concrete
values.
Map values are deeply equal if they are the same map object or if they
have the same length and their corresponding keys (matched using Go
equality) map to deeply equal values.
Pointer values are deeply equal if they are equal using Go's ==
operator or if they point to deeply equal values.
Slice values are deeply equal when all of the following are true: they
are both nil or both non-nil, they have the same length, and either
they point to the same initial entry of the same underlying array
(that is, &x[0] == &y[0]) or their corresponding elements (up to
length) are deeply equal. Note that a non-nil empty slice and a nil
slice (for example, []byte{} and []byte(nil)) are not deeply equal.
Other values - numbers, bools, strings, and channels - are deeply
equal if they are equal using Go's == operator.
You need to loop over each of the elements in the slice and test. Equality for slices is not defined. However, there is a bytes.Equal function if you are comparing values of type []byte.
func testEq(a, b []Type) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
This is just example using reflect.DeepEqual() that is given in #VictorDeryagin's answer.
package main
import (
"fmt"
"reflect"
)
func main() {
a := []int {4,5,6}
b := []int {4,5,6}
c := []int {4,5,6,7}
fmt.Println(reflect.DeepEqual(a, b))
fmt.Println(reflect.DeepEqual(a, c))
}
Result:
true
false
Try it in Go Playground
If you have two []byte, compare them using bytes.Equal. The Golang documentation says:
Equal returns a boolean reporting whether a and b are the same length and contain the same bytes. A nil argument is equivalent to an empty slice.
Usage:
package main
import (
"fmt"
"bytes"
)
func main() {
a := []byte {1,2,3}
b := []byte {1,2,3}
c := []byte {1,2,2}
fmt.Println(bytes.Equal(a, b))
fmt.Println(bytes.Equal(a, c))
}
This will print
true
false
And for now, here is https://github.com/google/go-cmp which
is intended to be a more powerful and safer alternative to reflect.DeepEqual for comparing whether two values are semantically equal.
package main
import (
"fmt"
"github.com/google/go-cmp/cmp"
)
func main() {
a := []byte{1, 2, 3}
b := []byte{1, 2, 3}
fmt.Println(cmp.Equal(a, b)) // true
}
You cannot use == or != with slices but if you can use them with the elements then Go 1.18 has a new function to easily compare two slices, slices.Equal:
Equal reports whether two slices are equal: the same length and all elements equal. If the lengths are different, Equal returns false. Otherwise, the elements are compared in increasing index order, and the comparison stops at the first unequal pair. Floating point NaNs are not considered equal.
The slices package import path is golang.org/x/exp/slices. Code inside exp package is experimental, not yet stable. It will be moved into the standard library in Go 1.19 eventually.
Nevertheless you can use it as soon as Go 1.18 (playground)
sliceA := []int{1, 2}
sliceB := []int{1, 2}
equal := slices.Equal(sliceA, sliceB)
fmt.Println(equal) // true
type data struct {
num float64
label string
}
sliceC := []data{{10.99, "toy"}, {500.49, "phone"}}
sliceD := []data{{10.99, "toy"}, {200.0, "phone"}}
equal = slices.Equal(sliceC, sliceD)
fmt.Println(equal) // true
If the elements of the slice don't allow == and !=, you can use slices.EqualFunc and define whatever comparator function makes sense for the element type.
In case that you are interested in writing a test, then github.com/stretchr/testify/assert is your friend.
Import the library at the very beginning of the file:
import (
"github.com/stretchr/testify/assert"
)
Then inside the test you do:
func TestEquality_SomeSlice (t * testing.T) {
a := []int{1, 2}
b := []int{2, 1}
assert.Equal(t, a, b)
}
The error prompted will be:
Diff:
--- Expected
+++ Actual
## -1,4 +1,4 ##
([]int) (len=2) {
+ (int) 1,
(int) 2,
- (int) 2,
(int) 1,
Test: TestEquality_SomeSlice
Thought of a neat trick and figured I'd share.
If what you are interested in knowing is whether two slices are identical (i.e. they alias the same region of data) instead of merely equal (the value at each index of one slice equals the value in the same index of the other) then you can efficiently compare them in the following way:
foo := []int{1,3,5,7,9,11,13,15,17,19}
// these two slices are exactly identical
subslice1 := foo[3:][:4]
subslice2 := foo[:7][3:]
slicesEqual := &subslice1[0] == &subslice2[0] &&
len(subslice1) == len(subslice2)
There are some caveats to this sort of comparison, in particular that you cannot compare empty slices in this way, and that the capacity of the slices isn't compared, so this "identicality" property is only really useful when reading from a slice or reslicing a strictly narrower subslice, as any attempt to grow the slice will be affected by the slices' capacity. Still, it's very useful to be able to efficiently declare, "these two huge blocks of memory are in fact the same block, yes or no."
To have a complete set of answers: here is a solution with generics.
func IsEqual[A comparable](a, b []A) bool {
// Can't be equal if length differs
if len(a) != len(b) {
return false
}
// Empty arrays trivially equal
if len(a) == 0 {
return true
}
// Two pointers going towards each other at every iteration
left := 0
right := len(a) - 1
for left < right {
if a[left] != b[left] || a[right] != b[right] {
return false
}
left++
right--
}
return true
}
Code uses strategy of "two pointers" which brings runtime complexity of n / 2, which is still O(n), however, twice as less steps than a linear check one-by-one.