I want to generate a sequence of numbers in Go but I can't find any built-in functions for this.
Basically I want the equivalent of PHP's range function in Golang:
array range ( mixed $start , mixed $end [, number $step = 1 ] )
It would be useful when creating a slice/array of numeric types and you want to populate/initialize it with a numeric sequence.
There is no equivalent to PHP's range in the Go standard library. You have to create one yourself. The simplest is to use a for loop:
func makeRange(min, max int) []int {
a := make([]int, max-min+1)
for i := range a {
a[i] = min + i
}
return a
}
Using it:
a := makeRange(10, 20)
fmt.Println(a)
Output (try it on the Go Playground):
[10 11 12 13 14 15 16 17 18 19 20]
Also note that if the range is small, you can use a composite literal:
a := []int{1, 2, 3}
fmt.Println(a) // Output is [1 2 3]
1- You may use:
//Create a slice containing a range of elements.
//
// start: First value of the sequence.
// end: The sequence is ended upon reaching the end value.
// step: step will be used as the increment between elements in the sequence.
// step should be given as a positive number.
//
//Return Values: Returns a slice of elements from start to end, inclusive.
func NewSlice(start, end, step int) []int {
if step <= 0 || end < start {
return []int{}
}
s := make([]int, 0, 1+(end-start)/step)
for start <= end {
s = append(s, start)
start += step
}
return s
}
Try it on The Go Playground:
package main
import "fmt"
//Create a slice containing a range of elements.
//
// start: First value of the sequence.
// end: The sequence is ended upon reaching the end value.
// step: step will be used as the increment between elements in the sequence.
// step should be given as a positive number.
//
//Return Values: Returns a slice of elements from start to end, inclusive.
func NewSlice(start, end, step int) []int {
if step <= 0 || end < start {
return []int{}
}
s := make([]int, 0, 1+(end-start)/step)
for start <= end {
s = append(s, start)
start += step
}
return s
}
func main() {
s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(s) // [0 1 2 3 4 5 6 7 8 9]
fmt.Println(NewSlice(10, 19, 1)) // [10 11 12 13 14 15 16 17 18 19]
fmt.Println(NewSlice(10, 28, 2)) // [10 12 14 16 18 20 22 24 26 28]
fmt.Println(NewSlice(-10, -1, 1)) // [-10 -9 -8 -7 -6 -5 -4 -3 -2 -1]
}
2- You may use:
// Returns a slice of elements with exact count.
// step will be used as the increment between elements in the sequence.
// step should be given as a positive, negative or zero number.
func NewSlice(start, count, step int) []int {
s := make([]int, count)
for i := range s {
s[i] = start
start += step
}
return s
}
Try it on The Go Playground:
package main
import "fmt"
func NewSlice(start, count, step int) []int {
s := make([]int, count)
for i := range s {
s[i] = start
start += step
}
return s
}
func main() {
s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(s) // [0 1 2 3 4 5 6 7 8 9]
fmt.Println(NewSlice(10, 10, 1)) // [10 11 12 13 14 15 16 17 18 19]
fmt.Println(NewSlice(10, 10, 2)) // [10 12 14 16 18 20 22 24 26 28]
fmt.Println(NewSlice(-1, 10, -1)) // [-1 -2 -3 -4 -5 -6 -7 -8 -9 -10]
fmt.Println(NewSlice(20, 10, 0)) // [20 20 20 20 20 20 20 20 20 20]
}
package main
import "fmt"
func main() {
var a [11]int
for i := 1; i < len(a); i++ {
a[i] = i
}
fmt.Print(a)
}
You will get:
[0 1 2 3 4 5 6 7 8 9 10]
You can try this code GenerateSequenceInt, it's like Python's range:
package main
import (
"fmt"
"errors"
)
func GenerateSequenceInt(begin, end, step int) (sequence []int){
if step == 0 {
panic(errors.New("step must not be zero"))
}
count := 0
if (end > begin && step > 0) || (end < begin && step < 0) {
count = (end-step-begin)/step + 1
}
sequence = make([]int, count)
for i := 0; i < count; i, begin = i+1, begin+step {
sequence[i] = begin
}
return
}
func main() {
seq1 := GenerateSequenceInt(-1,11,-3)
fmt.Println(seq1)
seq2 := GenerateSequenceInt(1,-1,3)
fmt.Println(seq2)
seq3 := GenerateSequenceInt(1,1,1)
fmt.Println(seq3)
seq4 := GenerateSequenceInt(1, 11, 2)
fmt.Println(seq4)
seq5 := GenerateSequenceInt(1, -11, -2)
fmt.Println(seq5)
}
When you create an array/slice of number in golang, it is automatically populated with 0s. You could use the index instead of the value if you need a 0 based range that increases by 1.
nums := make([]int, 10)
for i := range nums {
//do something with index
fmt.Println(i)
}
If you needed a different starting point (not zero) and step (not 1) of the range, you could calculate it in a loop. For example, for a range of 10 numbers starting at 100, increasing by 5
nums := make([]int, 10)
for i := range nums {
nums[i] = 100 + i*5
}
Wrapping it as a function that returns a slice of numbers
func Range(start int, max int, step int) []int {
count := (max - start) / step
nums := make([]int, count)
for i := range nums {
nums[i] = start + i*step
}
return nums
}
Call it as
nums = Range(-50, 150, 10)
fmt.Println(nums)
Related
64 symbols have 64! permutations. How to get one of these permutations from its index/rank and how to get index/rank of one of these permutations in the fastest way in Java or Python or C#?
These permutations have no repetitions, and the length of each of the permutations is equal to the number of symbols given to the function.
N-th permutation
The iea is that whichever digit you select for the first position, what remains is a permutation of (n-1) elements, so the digit selected to the first position is floor(idx / (n-1)!). Apply this recursively and you have the permutation you want.
from functools import lru_cache
#lru_cache
def factorial(n):
if n <= 1: return 1
else: return n * factorial(n-1);
def nth_permutation(idx, length, alphabet=None, prefix=()):
if alphabet is None:
alphabet = [i for i in range(length)]
if length == 0:
return prefix
else:
branch_count = factorial(length-1)
for d in alphabet:
if d not in prefix:
if branch_count <= idx:
idx -= branch_count;
else:
return nth_permutation(idx,
length-1, alphabet, prefix + (d,))
This will return a tuple representing the requested permutation, if you want you can pass a custom alphabet.
Examples
nth_permutation(1, 10)
# (0, 1, 2, 3, 4, 5, 6, 7, 9, 8)
nth_permutation(1000, 10)
# (0, 1, 2, 4, 6, 5, 8, 9, 3, 7)
1000
nth_permutation(3628799, 10)
# (9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
nth_permutation(10**89, 64)
# [[50 27 40 11 60 12 10 49]
# [63 29 41 0 2 48 43 47]
# [57 6 59 56 17 58 52 39]
# [13 51 25 23 45 24 26 7]
# [46 20 36 62 14 55 31 3]
# [ 4 5 53 15 8 28 16 21]
# [32 30 35 18 19 37 61 44]
# [38 42 54 9 33 34 1 22]]
Permutation index
The index of a given permutation is the index of the first element multiplied by (n-1)! added to the rank of the permutation of the remaining terms.
def permutation_index(item, alphabet=None):
if alphabet is None:
alphabet = sorted(item)
n = len(item)
r = 0
for i, v in enumerate(item):
# for every (item[j] > item[i]) we have to increase (n - i)!
# the factorials are computed recursively
# grouped in r
r = sum(1 for u in item[i+1:]
if alphabet.index(u) < alphabet.index(v)) + r * (n - i)
return r;
Consistency check
permutation_index(nth_permutation(1234567890, 16))
The function below separates each value into chunks separated by indexes index with the values in L_list. So it outputs the minimum value between indexes 3-5 which is -5 and the index of the value. Both the numpy_argmin_reduceat(a, b) and the Drawdown function do as planned however the index output of the numpy_argmin_reduceat(a, b) is faulty it The minimum values of Drawdown do not match with the indexes of the outputs of numpy_argmin_reduceat(a, b).How would I be able to solve this?
Arrays:
import numpy as np
# indexes 0, 1, 2,3,4, 5, 6,7, 8, 9,10, 11, 12
L_list = np.array([10,20,30,0,0,-5,11,2,33, 4, 5, 68, 7])
index = np.array([3,5,7,11])
Functions:
#getting the minimum values
Drawdown = np.minimum.reduceat(L_list,index+1)
#Getting the min Index
def numpy_argmin_reduceat(a, b):
n = a.max() + 1 # limit-offset
id_arr = np.zeros(a.size,dtype=int)
id_arr[b] = 1
shift = n*id_arr.cumsum()
sortidx = (a+shift).argsort()
grp_shifted_argmin = b
idx =sortidx[grp_shifted_argmin] - b
min_idx = idx +index
return min_idx
min_idx =numpy_argmin_reduceat(L_list,index+1)
#printing function
DR_val_index = np.array([np.around(Drawdown,1), min_idx])
DR_result = np.apply_along_axis(lambda x: print(f'Min Values: {x[0]} at index: {x[1]}'), 0, DR_val_index)
Output
Min Values: -5 at index: 4
Min Values: 2 at index: 6
Min Values: 4 at index: 8
Min Values: 7 at index: 11
Expected Output:
Min Values: -5 at index: 5
Min Values: 2 at index: 7
Min Values: 4 at index: 9
Min Values: 7 at index: 12
If you change the line
id_arr[b[1:]] = 1
to
id_arr[b] = 1
I think the function will behave as you hope.
Return the sum of the numbers in the array, returning 0 for an empty array. Except the number 13 is very unlucky, so it does not count and numbers that come immediately after a 13 also do not count.
my code:
def sum13(nums):
sum1 = 0
for i in nums:
sum1 += i
if 13 in nums:
ind = nums.index(13)
if ind == len(nums)-1:
sum13 = sum1 - 13
else:
sum13 = sum1 - 13 -nums[ind+1]
return sum13
else:
return sum1
it fails when
nums= [1, 2, 13, 2, 1, 13]
For your list, if you want to find the sum of all numbers other than 13, try:
sum( i for i in nums if i!=13)
Now if you want to stop the summation when you reach your first 13 in the list, try:
sum( i for i in nums[:nums.index(13)] if i!=13)
Now to exclude 13 and the number after that from summation, try:
def sum13(nums):
if nums[-1] == 13:
return sum([nums[0]] + [nums[i] for i in range(len(nums)) if (nums[i] != 13 and nums[i-1] !=13)])
else:
return sum([nums[i] for i in range(len(nums)) if (nums[i] != 13 and nums[i-1] !=13)])
def sum13(nums):
sum=0
for i in range(len(nums)):
if nums[i]!=13:
sum+=nums[i]
elif i<len(nums)-1:
if nums[i+1]!=13:
sum-=nums[i+1]
return sum
I'm trying and failing to accomplish the simple task of batching over input, at most 10 at a time. The follow code almost works:
func batchMe(input []int) {
fmt.Println("Length", len(input), len(input)/10)
for i := 0; i <= len(input)/10; i++ {
from := i * 10
to := (i + 1) * 10
if len(input) < to {
to = len(input)
}
fmt.Println("Batch", i, input[from:to])
}
But you can see from https://play.golang.org/p/_UgFD1iDyse that it prints:
Length 10 1
Batch 0 [1 2 3 4 5 6 7 8 9 10]
Batch 1 []
I don't want it to print Batch 1 in the case of 10 elements!
Perhaps there is a code simplification here?
Elegant solution from Tv on #go-nuts looks like:
for len(input) > 0 {
n := 10
if n > len(input) {
n = len(input)
}
chunk := input[:n]
input = input[n:]
fmt.Println("Batch", chunk)
}
https://play.golang.org/p/Y3U8dUD7Zrr
I am interested to calculate correlations in parallel in Go. The main problem I have is that all the Go processes seems to execute exactly the same calculation. I reproduced here the problem with a very simple example.
I obtain :
4 + 50 = 54
4 + 50 = 54
4 + 50 = 54
instead of :
1 + 20 = 21
2 + 30 = 32
3 + 40 = 43
If I move up "wg.Wait()" I obtain the good result but no parallelism :(
Thank's in advance for your comments !
package main
import (
"fmt"
"runtime"
"sync"
)
func process_array(x, y int) int {
r := x + y
return r
}
func main() {
a1 := []int{0, 1, 2, 3, 4}
a2 := []int{10, 20, 30, 40, 50}
runtime.GOMAXPROCS(8)
var wg sync.WaitGroup
for i := 1; i < 4 ; i++ {
wg.Add(1)
go func() {
defer wg.Done()
x :=process_array(a1[i],a2[i])
fmt.Println(a1[i],"+", a2[i],"=", x)
}()
//wg.Wait() give the good result
//but it is not parallel processing
// 1 + 20 = 21
// 2 + 30 = 32
// 3 + 40 = 43
}
wg.Wait() // give a repetition of the same result :
// 4 + 50 = 54
// 4 + 50 = 54
// 4 + 50 = 54
}
You're accessing the same copy of i in all goroutines. The output you see is because the loop happens to finish before any of the goroutines start executing.
This means that i has the same value in all goroutines, i.e. the last value it had in the loop.
Passing i as an argument to each of your goroutines, thereby operating on a copy per goroutine instead, solves this problem.
The reason you saw the result you expected when you added wg.Wait() in the loop is because you then introduced synchronization, waiting for the goroutine to finish before starting the next one. That means the execution was in fact serial, not parallell.
Here's the updated code, which works as you'd expect:
package main
import (
"fmt"
"runtime"
"sync"
)
func process_array(x, y int) int {
r := x + y
return r
}
func main() {
a1 := []int{0, 1, 2, 3, 4}
a2 := []int{10, 20, 30, 40, 50}
runtime.GOMAXPROCS(8)
var wg sync.WaitGroup
for i := 1; i < 4; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
x := process_array(a1[i], a2[i])
fmt.Println(a1[i], "+", a2[i], "=", x)
}(i)
//wg.Wait() give the good result
//but it is not parallel processing
// 1 + 20 = 21
// 2 + 30 = 32
// 3 + 40 = 43
}
wg.Wait() // give a repetition of the same result :
// 4 + 50 = 54
// 4 + 50 = 54
// 4 + 50 = 54
}