How do I pass an array of C.double's to a Cgo function? - go

I'm just getting started with CGo and I'm trying to send data to a C library that performs statistical computations on arrays of floats/doubles. What I'm trying to figure out right now is how to send an array of floats, or C.double's, to a CGo function that has a signature like this:
double pop_mean(int numPoints, double a[])
I've figured out how to get in the C.int in there, but I'm having trouble figuring out how to send in an array of doubles.
I haven't yet seen any blog posts or SO Questions about this exact thing, so I thought I'd ask.
The following is my best effort so far.
// Get a basic function to work, while passing in an ARRAY arr := make([]C.double, 0)
arr = append(arr, C.double(10.0))
arr = append(arr, C.double(20.0))
arr = append(arr, C.double(30.0))
var fixedArray [3]C.double = arr[:]
// ptr := C.CBytes(arr)
// defer C.free(unsafe.Pointer(ptr))
coolMean := C.pop_mean(3, &fixedArray)
fmt.Println("pop_mean (10, 20, 30): ", coolMean)
And this is the error I'm getting:
./main.go:64:6: cannot use arr[:] (type []_Ctype_double) as type [3]_Ctype_double in assignment
./main.go:69:35: cannot use &fixedArray (type *[3]_Ctype_double) as type *_Ctype_double in argument to _Cfunc_pop_mean
How should I be passing an array of C.double to the code?

When an array name is passed to a function, what is passed is the
location of the initial element. Within the called function, this
argument is a local variable, and so an array name parameter is a
pointer, that is, a variable containing an address.
C Programming Language, 2nd Edition
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.
Like arrays, slices are indexable and have a length. The length of a
slice s can be discovered by the built-in function len; unlike with
arrays it may change during execution. The elements can be addressed
by integer indices 0 through len(s)-1. The slice index of a given
element may be less than the index of the same element in the
underlying array.
A slice, once initialized, is always associated with an underlying
array that holds its elements.
The Go Programming Language Specification
Reference: Go Command cgo
For a slice a, the arguments to the pop_mean(int numPoints, double a[]) C function are len(a), the length of the slice underlying array, and &a[0], the address of the first element of the slice underlying array.
In Go, we often hide details in a function. For example, a popMean function,
package main
import (
"fmt"
)
/*
double pop_mean(int numPoints, double a[]) {
if (a == NULL || numPoints == 0) {
return 0;
}
double mean = 0;
for (int i = 0; i < numPoints; i++) {
mean+=a[i];
}
return mean / numPoints;
}
*/
import "C"
func popMean(a []float64) float64 {
// This is the general case, which includes the special cases
// of zero-value (a == nil and len(a) == 0)
// and zero-length (len(a) == 0) slices.
if len(a) == 0 {
return 0
}
return float64(C.pop_mean(C.int(len(a)), (*C.double)(&a[0])))
}
func main() {
a := make([]float64, 10)
for i := range a {
a[i] = float64(i + 1)
}
// slice
fmt.Println(len(a), a)
pm := popMean(a)
fmt.Println(pm)
// subslice
b := a[1:4]
fmt.Println(len(b), b)
pm = popMean(b)
fmt.Println(pm)
// zero length
c := a[:0]
fmt.Println(len(c), c)
pm = popMean(c)
fmt.Println(pm)
// zero value (nil)
var z []float64
fmt.Println(len(z), z, z == nil)
pm = popMean(z)
fmt.Println(pm)
}
Output:
10 [1 2 3 4 5 6 7 8 9 10]
5.5
3 [2 3 4]
3
0 []
0
0 [] true
0

I figured out that you have to send a pointer to the first value in the array, rather than sending a pointer to the first element of the slice, or to the slice itself.
AND I also ran into the problem where I had created a new variable that was assigned the value of the first item in the slice and later created a pointer to that variable (which was no longer a part of the original array), instead of creating a pointer to the first item in the array (like I wanted).
Below is the working code, with comments to help avoid the problem in the paragraph above.
// Get a basic function to work, while passing in an ARRAY
// Create a dummy array of (10,20,30), the mean of which is 20.
arr := make([]C.double, 0)
arr = append(arr, C.double(10.0))
arr = append(arr, C.double(20.0))
arr = append(arr, C.double(30.0))
firstValue := &(arr[0]) // this notation seems to be pretty important... Re-use this!
// if you don't make it a pointer right away, then you make a whole new object in a different location, so the contiguous-ness of the array is jeopardized.
// Because we have IMMEDIATELY made a pointer to the original value,the first value in the array, we have preserved the contiguous-ness of the array.
fmt.Println("array length: ", len(arr))
var arrayLength C.int
arrayLength = C.int(len(arr))
// arrayLength = C.int(2)
fmt.Println("array length we are using: ", arrayLength)
arrayMean := C.pop_mean(arrayLength, firstValue)
fmt.Println("pop_mean (10, 20, 30): ", arrayMean)
This produces the following result:
array length: 3
array length we are using: 3
pop_mean (10, 20, 30): 20
Or if we uncomment the line that changes the arrayLength to be 2, we get this result:
array length: 3
array length we are using: 2
pop_mean (10, 20, 30): 15

Related

Whats happening with this method?

type IntSet struct {
words []uint64
}
func (s *IntSet) Has(x int) bool {
word, bit := x/64, uint(x%64)
return word < len(s.words) && s.words[word]&(1<<bit) != 0
}
Lets go through what I think is going on:
A new type is declared called IntSet. Underneath its new type declaration it is unint64 slice.
A method is created called Has(). It can only receive IntSet types, after playing around with ints she returns a bool
Before she can play she needs two ints. She stores these babies on the stack.
Lost for words
This methods purpose is to report whether the set contains the non-negative value x. Here is a the go test:
func TestExample1(t *testing.T) {
//!+main
var x, y IntSet
fmt.Println(x.Has(9), x.Has(123)) // "true false"
//!-main
// Output:
// true false
}
Looking for some guidance understanding what this method is doing inside. And why the programmer did it in such complicated means (I feel like I am missing something).
The return statement:
return word < len(s.words) && s.words[word]&(1<<bit) != 0
Are the order of operations this?
return ( word < len(s.words) && ( s.words[word]&(1<<bit)!= 0 )
And what is the [words] and & doing within:
s.words[word]&(1<<bit)!= 0
edit: Am beginning to see slightly seeing that:
s.words[word]&(1<<bit)!= 0
Is just a slice but don't understand the &
As I read the code, I scribbled some notes:
package main
import "fmt"
// A set of bits
type IntSet struct {
// bits are grouped into 64 bit words
words []uint64
}
// x is the index for a bit
func (s *IntSet) Has(x int) bool {
// The word index for the bit
word := x / 64
// The bit index within a word for the bit
bit := uint(x % 64)
if word < 0 || word >= len(s.words) {
// error: word index out of range
return false
}
// the bit set within the word
mask := uint64(1 << bit)
// true if the bit in the word set
return s.words[word]&mask != 0
}
func main() {
nBits := 2*64 + 42
// round up to whole word
nWords := (nBits + (64 - 1)) / 64
bits := IntSet{words: make([]uint64, nWords)}
// bit 127 = 1 * 64 + 63
bits.words[1] = 1 << 63
fmt.Printf("%b\n", bits.words)
for i := 0; i < nWords*64; i++ {
has := bits.Has(i)
if has {
fmt.Println(i, has)
}
}
has := bits.Has(127)
fmt.Println(has)
}
Playground: https://play.golang.org/p/rxquNZ_23w1
Output:
[0 1000000000000000000000000000000000000000000000000000000000000000 0]
127 true
true
The Go Programming Language Specification
Arithmetic operators
& bitwise AND integers
peterSO's answer is spot on - read it. But I figured this might also help you understand.
Imagine I want to store some random numbers in the range 1 - 8. After I store these numbers I will be asked if the number n (also in the range of 1 - 8) appears in the numbers I recorded earlier. How would we store the numbers?
One, probably obvious, way would be to store them in a slice or maybe a map. Maybe we would choose a map since lookups will be constant time. So we create our map
seen := map[uint8]struct{}{}
Our code might look something like this
type IntSet struct {
seen: map[uint8]struct{}
}
func (i *IntSet) AddValue(v uint8) {
i.seen[v] = struct{}{}
}
func (i *IntSet) Has(v uint8) bool {
_, ok := i.seen[v]
return ok
}
For each number we store we take up (at least) 1 byte (8 bits) of memory. If we were to store all 8 numbers we would be using 64 bits / 8 bytes.
However, as the name implies, this is an int Set. We don't care about duplicates, we only care about membership (which Has provides for us).
But there is another way we could store these numbers, and we could do it all within a single byte. Since a byte provides 8 bits, we can use these 8 bits as markers for values we have seen. The initial value (in binary notation) would be
00000000 == uint8(0)
If we did an AddValue(3) we could change the 3rd bit and end up with
00000100 == uint8(3)
^
|______ 3rd bit
If we then called AddValue(8) we would have
10000100 == uint8(132)
^ ^
| |______ 3rd bit
|___________ 8th bit
So after adding 3 and 8 to our IntSet we have the internally stored integer value of 132. But how do we take 132 and figure out whether a particular bit is set? Easy, we use bitwise operators.
The & operator is a logical AND. It will return the value of the bits common between the numbers on each side of the operator. For example
10001100 01110111 11111111
& 01110100 & 01110000 & 00000001
-------- -------- --------
00000100 01110000 00000001
So to find out if n is in our set we simply do
our_set_value & (1 << (value_we_are_looking_for - 1))
which if we were searching for 4 would yield
10000100
& 00001000
----------
0 <-- so 4 is not present
or if we were searching for 8
10000100
& 10000000
----------
10000000 <-- so 8 is present
You may have noticed I subtracted 1 from our value_we_are_looking for. This is because I am fitting 1-8 into our 8bit number. If we only wanted to store seven numbers then we could just skip using the very first bit and assume our counting starts at bit #2 then we wouldn't have to subtract 1, like the code you posted does.
Assuming you understand all of that, here's where things get interesting. So far we have been storing our values in a uint8 (so we could only have 8 values, or 7 if you omit the first bit). But there are larger numbers that have more bits, like uint64. Instead of 8 values, we can store 64 values! But what happens if the range of values we want to track exceed 1-64? What if we want to store 65? This is where the slice of words comes from in the original code.
Since the code posted skips the first bit, from now on I will do so as well.
We can use the first uint64 to store the numbers 1 - 63. When we want to store the numbers 64-127 we need a new uint64. So our slice would be something like
[ uint64_of_1-63, uint64_of_64-127, uint64_of_128-192, etc]
Now, to answer the question about whether a number is in our set we need to first find the uint64 whose range would contain our number. If we were searching for 110 we would want to use the uint64 located at index 1 (uint64_of_64-128) because 110 would fall in that range.
To find the index of the word we need to look at, we take the whole number value of n / 64. In the case of 110 we would get 1, which is exactly what we want.
Now we need to examine the specific bit of that number. The bit that needs to be checked would be the remainder when dividing 110 by 64, or 46. So if the 46th bit of the word at index 1 is set, then we have seen 110 before.
This is how it might look in code
type IntSet struct {
words []uint64
}
func (s *IntSet) Has(x int) bool {
word, bit := x/64, uint(x%64)
return word < len(s.words) && s.words[word]&(1<<bit) != 0
}
func (s *IntSet) AddValue(x int) {
word := x / 64
bit := x % 64
if word < len(s.words) {
s.words[word] |= (1 << uint64(bit))
}
}
And here is some code to test it
func main() {
rangeUpper := 1000
bits := IntSet{words: make([]uint64, (rangeUpper/64)+1)}
bits.AddValue(127)
bits.AddValue(8)
bits.AddValue(63)
bits.AddValue(64)
bits.AddValue(998)
fmt.Printf("%b\n", bits.words)
for i := 0; i < rangeUpper; i++ {
if ok := bits.Has(i); ok {
fmt.Printf("Found %d\n", i)
}
}
}
OUTPUT
Found 8
Found 63
Found 64
Found 127
Found 998
Playground of above
Note
The |= is another bitwise operator OR. It means combine the two values keeping anywhere there is a 1 in either value
10000000 00000001 00000001
& 01000000 & 10000000 & 00000001
-------- -------- --------
11000000 10000001 00000001 <-- important that we
can set the value
multiple times
Using this method we can reduce the cost of storage for 65535 numbers from 131KB to just 1KB. This type of bit manipulation for set membership is very common in implementations of Bloom Filters
An IntSet represents a Set of integers. The presence in the set of any of a contiguous range of integers can be established by writing a single bit in the IntSet. Likewise, checking whether a specific integer is in the IntSet can be done by checking whether the particular integer corresponding to that bit is set.
So the code is finding the specific uint64 in the Intset corresponding to the integer:
word := x/64
and then the specific bit in that uint64:
bit := uint(x%64)
and then checking first that the integer being tested is in the range supported by the IntSet:
word < len(s.words)
and then whether the specific bit corresponding to the specific integer is set:
&& s.words[word]&(1<<bit) != 0
This part:
s.words[word]
pulls out the specific uint64 of the IntSet that tracks whether the integer in question is in the set.
&
is a bitwise AND.
(1<<bit)
means take a 1, shift it to the bit position representing the specific integer being tested.
Performing the bitwise AND between the integer in question, and the bit-shifted 1 will return a 0 if the bit corresponding to the integer is not set, and a 1 if the bit is set (meaning, the integer in question is a member of the IntSet).

One-liner to generate Powerball picks in Swift?

With the U.S.'s large $1.5 Billion lottery this week, I wrote a function in Ruby to make Powerball picks. In Powerball, you choose 5 numbers from the range 1..69 (with no duplicates) and 1 number from the range 1..26.
This is what I came up with:
def pball
Array(1..69).shuffle[0..4].sort + [rand(1..26)]
end
It works by creating an array of integers from 1 to 69, shuffling that array, choosing the first 5 numbers, sorting those, and finally adding on a number from 1 to 26.
To do this in Swift takes a bit more work since Swift doesn't have the built-in shuffle method on Array.
This was my attempt:
func pball() -> [Int] {
let arr = Array(1...69).map{($0, drand48())}.sort{$0.1 < $1.1}.map{$0.0}[0...4].sort()
return arr + [Int(arc4random_uniform(26) + 1)]
}
Since there is no shuffle method, it works by creating an [Int] with values in the range 1...69. It then uses map to create [(Int, Double)], an array of tuple pairs that contain the numbers and a random Double in the range 0.0 ..< 1.0. It then sorts this array using the Double values and uses a second map to return to [Int] and then uses the slice [0...4] to extract the first 5 numbers and sort() to sort them.
In the second line, it appends a number in the range 1...26. I tried adding this to the first line, but Swift gave the error:
Expression was too complex to be solved in reasonable time; consider
breaking up the expression into distinct sub-expressions.
Can anyone suggest how to turn this into a 1-line function? Perhaps there is a better way to choose the 5 numbers from 1...69.
Xcode 8.3 • Swift 3.1
import GameKit
var powerballNumbers: [Int] {
return (GKRandomSource.sharedRandom().arrayByShufflingObjects(in: Array(1...69)) as! [Int])[0..<5].sorted() + [Int(arc4random_uniform(26) + 1)]
}
powerballNumbers // [5, 9, 62, 65, 69, 2]
Swift 2.x
import GameKit
var powerballNumbers: [Int] {
return (GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(Array(1...69)) as! [Int])[0...4].sort() + [Int(arc4random_uniform(26).successor())]
}
powerballNumbers // [21, 37, 39, 42, 65, 23]
I don't find the "one-liner" concept very compelling. Some languages lend themselves to it; others don't. I would suggest giving Swift a shuffle method to start with:
extension Array {
mutating func shuffle () {
for var i = self.count - 1; i != 0; i-- {
let ix1 = i
let ix2 = Int(arc4random_uniform(UInt32(i+1)))
(self[ix1], self[ix2]) = (self[ix2], self[ix1])
}
}
}
But since I made this mutating, we still need more than one line to express the entire operation because we have to have a var reference to our starting array:
var arr = Array(1...69)
(1...4).forEach {_ in arr.shuffle()}
let result = Array(arr[0..<5]) + [Int(arc4random_uniform(26)) + 1]
If you really insist on the one-liner, and you don't count the code needed to implement shuffle, then you can do it, though less efficiently, by defining shuffle more like this:
extension Array {
func shuffle () -> [Element] {
var arr = self
for var i = arr.count - 1; i != 0; i-- {
let ix1 = i
let ix2 = Int(arc4random_uniform(UInt32(i+1)))
(arr[ix1], arr[ix2]) = (arr[ix2], arr[ix1])
}
return arr
}
}
And here's your one-liner:
let result = Array(1...69).shuffle().shuffle().shuffle().shuffle()[0..<5] + [Int(arc4random_uniform(26)) + 1]
But oops, I omitted your sort. I don't see how to do that without getting the "too complex" error; to work around that, I had to split it into two lines:
var result = Array(1...69).shuffle().shuffle().shuffle().shuffle()[0..<5].sort(<)
result.append(Int(arc4random_uniform(26)) + 1)
How about this:
let winningDraw = (1...69).sort{ _ in arc4random_uniform(2) > 0}[0...4].sort() + [Int(arc4random_uniform(26)+1)]
[edit] above formula wasn't random. but this one will be
(1...69).map({Int(rand()%1000*70+$0)}).sort().map({$0%70})[0...4].sort() + [Int(rand()%26+1)]
For the fun of it, a non-GameplayKit (long) one-liner for Swift 3, using the global sequence(state:next:) function to generate random elements from the mutable state array rather than shuffling the array (although mutating the value array 5 times, so some extra copy operations here...)
let powerballNumbers = Array(sequence(state: Array(1...69), next: {
(s: inout [Int]) -> Int? in s.remove(at: Int(arc4random_uniform(UInt32(s.count))))})
.prefix(5).sorted()) + [Int(arc4random_uniform(26) + 1)]
... broken down for readability.
(Possible in future Swift version)
If the type inference weren't broken inout closure parameters (as arguments to closures), we could reduce the above to:
let powerballNumbers = Array(sequence(state: Array(1...69), next: {
$0.remove(at: Int(arc4random_uniform(UInt32($0.count)))) })
.prefix(5).sorted()) + [Int(arc4random_uniform(26) + 1)]
If we'd also allow the following extension
extension Int {
var rand: Int { return Int(arc4random_uniform(UInt32(exactly: self) ?? 0)) }
}
Then, we could go on to reduce the one-line to:
let powerballNumbers = Array(sequence(state: Array(1...69), next: { $0.remove(at: $0.count.rand) }).prefix(5).sorted()) + [26.rand + 1]
Xcode 10 • Swift 4.2
Swift now has added shuffled() to ClosedRange and random(in:) to Int which now makes this easily accomplished in one line:
func pball() -> [Int] {
return (1...69).shuffled().prefix(5).sorted() + [Int.random(in: 1...26)]
}
Further trimmings:
Because of the return type of pball(), the Int can be inferred in the random method call. Also, .prefix(5) can be replaced with [...4]. Finally, return can be omitted from the one-line function:
func pball() -> [Int] {
(1...69).shuffled()[...4].sorted() + [.random(in: 1...26)]
}

How to iterate and extract values out of a for loop in Rust

I'm new to Rust and looking to understand concepts like borrowing. I'm trying to create a simple two dimensional array using standard input. The code:
use std::io;
fn main() {
let mut values = [["0"; 6]; 6]; // 6 * 6 array
// iterate 6 times for user input
for i in 0..6 {
let mut outputs = String::new();
io::stdin().read_line(&mut outputs).expect(
"failed to read line",
);
// read space separated list 6 numbers. Eg: 5 7 8 4 3 9
let values_itr = outputs.trim().split(' ');
let mut j = 0;
for (_, value) in values_itr.enumerate() {
values[i][j] = value;
j += 1;
}
}
}
This won't compile because the outputs variable lifetime is not long enough:
error[E0597]: `outputs` does not live long enough
--> src/main.rs:20:5
|
14 | let values_itr = outputs.trim().split(' ');
| ------- borrow occurs here
...
20 | }
| ^ `outputs` dropped here while still borrowed
21 | }
| - borrowed value needs to live until here
How can I get the iterated values out of the block into values array?
split() gives you substrings (string slices) borrowed from the original string, and the original string is outputs from line 6.
The string slices can't outlive the scope of outputs: when a loop iteration ends, outputs is deallocated.
Since values is longer lived, the slices can't be stored there.
We can't borrow slices of outputs across a modification of outputs. So even if the String outputs itself was defined before values, we couldn't easily put the string slices from .split() into values; modifying the string (reading into it) invalidates the slices.
A solution needs to either
Use a nested array of String, and when you assign an element from the split iterator, make a String from the &str using .to_string(). I would recommend this solution. (However an array of String is not at as easy to work with, maybe already this requires using Vec instead.) 1
Read all input before constructing a nested array of &str that borrows from the input String. This is good if the nested array is something that you only need temporarily.
1: You can use something like vec![vec![String::new(); 6]; 6] instead
This answer was moved from the question, where it solved the OPs needs.
use std::io;
fn main() {
let mut values = vec![vec![String::new(); 6]; 6];
for i in 0..6 {
let mut outputs = String::new();
io::stdin().read_line(&mut outputs)
.expect("failed to read line");
let values_itr = outputs.trim().split(' ');
let mut j = 0;
for (_, value) in values_itr.enumerate() {
values[i][j] = value.to_string();
j += 1;
}
}
}

Sum of numbers with approximation and no repetition

For an app I'm working on, I need to process an array of numbers and return a new array such that the sum of the elements are as close as possible to a target sum. This is similar to the coin-counting problem, with two differences:
Each element of the new array has to come from the input array (i.e. no repetition/duplication)
The algorithm should stop when it finds an array whose sum falls within X of the target number (e.g., given [10, 12, 15, 23, 26], a target of 35, and a sigma of 5, a result of [10, 12, 15] (sum 37) is OK but a result of [15, 26] (sum 41) is not.
I was considering the following algorithm (in pseudocode) but I doubt that this is the best way to do it.
function (array, goal, sigma)
var A = []
for each element E in array
if (E + (sum of rest of A) < goal +/- sigma)
A.push(E)
return A
For what it's worth, the language I'm using is Javascript. Any advice is much appreciated!
This is not intended as the best answer possible, just maybe something that will work well enough. All remarks/input is welcome.
Also, this is taking into mind the answers from the comments, that the input is length of songs (usually 100 - 600), the length of the input array is between 5 to 50 and the goal is anywhere between 100 to 7200.
The idea:
Start with finding the average value of the input, and then work out a guess on the number of input values you're going to need. Lets say that comes out x.
Order your input.
Take the first x-1 values and substitute the smallest one with the any other to get to your goal (somewhere in the range). If none exist, find a number so you're still lower than the goal.
Repeat step #3 using backtracking or something like that. Maybe limit the number of trials you're gonna spend there.
x++ and go back to step #3.
I would use some kind of divide and conquer and a recursive implementation. Here is a prototype in Smalltalk
SequenceableCollection>>subsetOfSum: s plusOrMinus: d
"check if a singleton matches"
self do: [:v | (v between: s - d and: s + d) ifTrue: [^{v}]].
"nope, engage recursion with a smaller collection"
self keysAndValuesDo: [:i :v |
| sub |
sub := (self copyWithoutIndex: i) subsetOfSum: s-v plusOrMinus: d.
sub isNil ifFalse: [^sub copyWith: v]].
"none found"
^nil
Using like this:
#(10 12 15 23 26) subsetOfSum: 62 plusOrMinus: 3.
gives:
#(23 15 12 10)
With limited input this problem is good candidate for dynamic programming with time complexity O((Sum + Sigma) * ArrayLength)
Delphi code:
function FindCombination(const A: array of Integer; Sum, Sigma: Integer): string;
var
Sums: array of Integer;
Value, idx: Integer;
begin
Result := '';
SetLength(Sums, Sum + Sigma + 1); //zero-initialized array
Sums[0] := 1; //just non-zero
for Value in A do begin
idx := Sum + Sigma;
while idx >= Value do begin
if Sums[idx - Value] <> 0 then begin //(idx-Value) sum can be formed from array]
Sums[idx] := Value; //value is included in this sum
if idx >= Sum - Sigma then begin //bingo!
while idx > 0 do begin //unwind and extract all values for this sum
Result := Result + IntToStr(Sums[idx]) + ' ';
idx := idx - Sums[idx];
end;
Exit;
end;
end;
Dec(idx); //idx--
end;
end;
end;
Here's one commented algorithm in JavaScript:
var arr = [9, 12, 20, 23, 26];
var target = 35;
var sigma = 5;
var n = arr.length;
// sort the numbers in ascending order
arr.sort(function(a,b){return a-b;});
// initialize the recursion
var stack = [[0,0,[]]];
while (stack[0] !== undefined){
var params = stack.pop();
var i = params[0]; // index
var s = params[1]; // sum so far
var r = params[2]; // accumulating list of numbers
// if the sum is within range, output sum
if (s >= target - sigma && s <= target + sigma){
console.log(r);
break;
// since the numbers are sorted, if the current
// number makes the sum too large, abandon this thread
} else if (s + arr[i] > target + sigma){
continue;
}
// there are still enough numbers left to skip this one
if (i < n - 1){
stack.push([i + 1,s,r]);
}
// there are still enough numbers left to add this one
if (i < n){
_r = r.slice();
_r.push(arr[i]);
stack.push([i + 1,s + arr[i],_r]);
}
}
/* [9,23] */

For a struct vertex, what's the difference between map[int]vertex and map[int]*vertex?

To define a map from int to struct vertex, should I define map[int]vertex or map[int]*vertex? Which one is preferred?
I extended Chickencha's code:
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
b := make(map[int]*vertex)
v := &vertex{0, 0}
a[0] = *v
b[0] = v
v.x, v.y = 4, 4
println(a[0].x, a[0].y, b[0].x, b[0].y)
//a[0].x = 3 // cannot assign to (a[0]).x
//a[0].y = 3 // cannot assign to (a[0]).y
b[0].x = 3
b[0].y = 3
println(a[0].x, a[0].y, b[0].x, b[0].y)
u1 := a[0]
u1.x = 2
u1.y = 2
u2 := b[0]
u2.x = 2
u2.y = 2
println(a[0].x, a[0].y, b[0].x, b[0].y)
}
The output:
0 0 4 4
0 0 3 3
0 0 2 2
From the output, my understanding is, if I want to change the struct member in place, I must use pointer to the struct.
But I'm still not sure the underlying reasons. Especially, why I cannot assign to a[0].x?
The main difference is that map[int]vertex stores vertex values and map[int]*vertex stores vertex references (pointers). The output of the following program should help illustrate:
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
b := make(map[int]*vertex)
v := &vertex{0, 0}
a[0] = *v
b[0] = v
v.x, v.y = 4, 4
println(a[0].x, a[0].y, b[0].x, b[0].y)
}
Output:
0 0 4 4
The vertex stored in b is modified by the v.x, v.y = 4, 4 line, while the vertex stored in a is not.
The answer to this question is likely to be dependent on how Go maps are implemented. For the current implementation, I would take a look the Go map runtime header, hashmap.h, and code, hashmap.c, files. It's also going to depend on how you use the map e.g. what type and volume of activities against the map, key and element data structures, etc.
To update a vector element value in place, read the vector element value from the map, update the element value, write the updated element value to the map. For example
package main
type vertex struct {
x, y int
}
func main() {
a := make(map[int]vertex)
a[0] = vertex{0, 0}
println(a[0].x, a[0].y)
v0 := a[0]
v0.x = 1
a[0] = v0
println(a[0].x, a[0].y)
}
Output:
0 0
1 0

Resources