I've just started learning Golang, so I set myself a challenge to order a slice of integers in highest to lowest and/or lowest to highest. I've got most of it right, but it seems to miss out the last item?
Expected: [5, 4, 1]
Got: [5, 4]
Now, this line is the issue,
for len(rebuiltNumbers) < len(numbers)
If I change it to this, it works fine:
for len(rebuiltNumbers) < len(numbers) + 2
but I don't understand why? Does while or for form of while work differently in go?
Here is the full code
package main
import "fmt"
func main() {
var numbers = []int { 1, 4, 5 }
fmt.Println(orderArrayOfNumbers(numbers, true))
}
func orderArrayOfNumbers(numbers []int, descending bool) []int {
var rebuiltNumbers []int
for len(rebuiltNumbers) < len(numbers) + 1 {
var next = 0
if descending {
next = getHighestItemInArray(numbers);
} else {
next = getLowestItemInArray(numbers);
}
rebuiltNumbers = append(rebuiltNumbers, next)
numbers = remove(numbers, next)
}
return rebuiltNumbers
}
func getHighestItemInArray(numbers []int) int {
var highest = 0
var hasSet = 0
for i := 0; i < len(numbers); i++ {
if numbers[i] > highest || hasSet == 0 {
highest = numbers[i]
hasSet = 1
}
}
return highest
}
func getLowestItemInArray(numbers []int) int {
var lowest = 0
var hasSet = 0
for i := 0; i < len(numbers); i++ {
if numbers[i] < lowest || hasSet == 0 {
lowest = numbers[i]
hasSet = 1
}
}
return lowest
}
func remove(slice []int, remove int) []int {
var rebuiltSlice = []int {}
for i := 0; i < len(slice); i++ {
if slice[i] != remove {
rebuiltSlice = append(rebuiltSlice, slice[i])
}
}
return rebuiltSlice
}
These two lines are important
rebuiltNumbers = append(rebuiltNumbers, next)
numbers = remove(numbers, next)
When you append to one array and remove from the other, the sizes will meet eventually in the middle. So you should rather save the size upfront, and then compare to that, e.g.
var nOrig = len(numbers)
for len(rebuiltNumbers) < nOrig {
// ...
}
Related
Clue :
An arcade game player wants to climb to the top of the leaderboard and track their ranking. The game uses Dense Ranking, so its leaderboard works like this:
The player with the highest score is ranked number 1 on the leaderboard.
Players who have equal scores receive the same ranking number, and the next player(s) receive the immediately following ranking number.
This is my code solution for climbing the leaderboard, 8/12 test case is passed. but 4 case is timeout. any solution for boosting the performance of my code?
func contains(s []int32, e int32) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
func remove(slice []int32, s int) []int32 {
return append(slice[:s], slice[s+1:]...)
}
func climbingLeaderboard(ranked []int32, player []int32) []int32 {
// Write your code here
for i := 0; i < len(ranked); i++ {
if contains(ranked[i+1:], ranked[i]) {
ranked = remove(ranked, i)
i--
}
}
sort.Slice(ranked, func(i, j int) bool { return ranked[i] < ranked[j] })
var result = make([]int32, len(player))
if len(ranked) == 1 {
for i := 0; i < len(player); i++ {
if player[i] > ranked[0] {
result[i] = 1
} else if player[0] == ranked[0] {
result[i] = 1
} else if player[0] < ranked[0] {
result[i] = 2
}
}
} else {
for i := 0; i < len(player); i++ {
l := len(ranked)
l32 := int32(l)
p := player[i]
var temp int32
for j := 1; j < l; j++ {
if p > ranked[j] {
temp = 1
} else if p > ranked[j-1] && p < ranked[j] {
temp = l32 - int32(j) + 1
break
} else if p == ranked[j-1] {
temp = l32 - int32(j) + 1
break
} else if p < ranked[j-1] {
temp = l32 + 1
break
}
}
result[i] = temp
temp = 0
}
}
return result
}
Your code to dedupe ranked is very inefficient.
func contains(s []int32, e int32) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
func remove(slice []int32, s int) []int32 {
return append(slice[:s], slice[s+1:]...)
}
for i := 0; i < len(ranked); i++ {
if contains(ranked[i+1:], ranked[i]) {
ranked = remove(ranked, i)
i--
}
}
sort.Slice(ranked, func(i, j int) bool { return ranked[i] < ranked[j] })
Your code to search for player game ranks is not efficient.
Efficiency is not just what you do, it's also how many times you do it.
Your code is too complicated.
Here is some simple code that solves the challenge without triggering a timeout.
import (
"sort"
)
func climbingLeaderboard(ranked []int32, player []int32) []int32 {
ranks := ranked[:1]
last := ranks[0]
for _, score := range ranked[1:] {
if score != last {
ranks = append(ranks, score)
}
last = score
}
climb := make([]int32, 0, len(player))
for _, score := range player {
rank := sort.Search(
len(ranks),
func(i int) bool { return ranks[i] <= score },
)
climb = append(climb, int32(rank+1))
}
return climb
}
I'm trying to get the max value from a diff, n[i] - n[i-1], timeseries. The first value is always zero from the slice, here is the code:
func MaxBelowZero(n ...float64) float64 {
var maxValue float64
if len(n) == 1 {
return n[0]
} else if len(n) == 0 {
return 0.
}
for i := range n {
if i == 0 {
maxValue = math.SmallestNonzeroFloat64
continue
}
if maxValue < n[i] && n[i] < 0 {
maxValue = n[i]
}
}
return maxValue
}
var sliceTest = []float64{0, 1, 2, -1, -2, -10, 10, 20}
MaxBelowZero(sliceTest...)
Output: 5e-324
It supossed to be -1. What am I doing wrong? I would appreciate some help.
The code in playground: link
math.SmallestNonzeroFloat64 is the number closest to 0 that is not 0, not the number furthest from zero. Try this:
go playground
func MaxBelowZero(values ...float64) float64 {
if len(values) == 0 {
return 0
} else if len(values) == 1 {
return values[0]
}
max := -math.MaxFloat64
for _, n := range values {
if n >= 0 {
continue
}
if n > max {
max = n
}
}
return max
}
func MaxBelowZero(n ...float64) float64 {
maxValue := -math.MaxFloat64 // Initial value must be negative
if len(n) == 1 {
return n[0]
} else if len(n) == 0 {
return 0.
}
for i := 1; i < len(n); i++ {
diff := n[i] - n[i-1] // Correct logic here
if diff > maxValue && diff < 0 {
maxValue = diff
}
}
return maxValue
}
You could reverse sort the slice, then find first negative number:
package main
import "sort"
func main() {
a := []float64{0, 1, 2, -1, -2, -10, 10, 20}
sort.Slice(a, func(d, e int) bool {
return a[e] < a[d]
})
n := sort.Search(len(a), func(n int) bool {
return a[n] < 0
})
println(a[n] == -1)
}
Or sort by sign, then by absolute value:
package main
import "math"
type sFunc func(a, b float64) bool
var sFuncs = []sFunc{
func(a, b float64) bool {
return math.Copysign(1, a) < math.Copysign(1, b)
},
func(a, b float64) bool {
return math.Abs(a) < math.Abs(b)
},
}
Result:
package main
import (
"fmt"
"sort"
)
func main() {
floats := []float64{0, 1, 2, -1, -2, -10, 10, 20}
sort.Slice(floats, func(a, b int) bool {
fa, fb := floats[a], floats[b]
for _, sf := range sFuncs {
if sf(fa, fb) {
return true
}
if sf(fb, fa) {
break
}
}
return false
})
fmt.Println(floats) // [-1 -2 -10 0 1 2 10 20]
}
https://golang.org/pkg/sort#Search
https://golang.org/pkg/sort#Slice
The project is more complex but the blocking issue is: How to generate a sequence of words of specific length from a list?
I've found how to generate all the possible combinations(see below) but the issue is that I need only the combinations of specific length.
Wolfram working example (it uses permutations though, I need only combinations(order doesn't matter)) :
Permutations[{a, b, c, d}, {3}]
Example(pseudo go):
list := []string{"alice", "moon", "walks", "mars", "sings", "guitar", "bravo"}
var premutationOf3
premutationOf3 = premuate(list, 3)
// this should return a list of all premutations such
// [][]string{[]string{"alice", "walks", "moon"}, []string{"alice", "signs", "guitar"} ....}
Current code to premutate all the possible sequences (no length limit)
for _, perm := range permutations(list) {
fmt.Printf("%q\n", perm)
}
func permutations(arr []string) [][]string {
var helper func([]string, int)
res := [][]string{}
helper = func(arr []string, n int) {
if n == 1 {
tmp := make([]string, 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
}
I implement twiddle algorithm for generating combination in Go. Here is my implementation:
package twiddle
// Twiddle type contains all information twiddle algorithm
// need between each iteration.
type Twiddle struct {
p []int
b []bool
end bool
}
// New creates new twiddle algorithm instance
func New(m int, n int) *Twiddle {
p := make([]int, n+2)
b := make([]bool, n)
// initiate p
p[0] = n + 1
var i int
for i = 1; i != n-m+1; i++ {
p[i] = 0
}
for i != n+1 {
p[i] = i + m - n
i++
}
p[n+1] = -2
if m == 0 {
p[1] = 1
}
// initiate b
for i = 0; i != n-m; i++ {
b[i] = false
}
for i != n {
b[i] = true
i++
}
return &Twiddle{
p: p,
b: b,
}
}
// Next creates next combination and return it.
// it returns nil on end of combinations
func (t *Twiddle) Next() []bool {
if t.end {
return nil
}
r := make([]bool, len(t.b))
for i := 0; i < len(t.b); i++ {
r[i] = t.b[i]
}
x, y, end := t.twiddle()
t.b[x] = true
t.b[y] = false
t.end = end
return r
}
func (t *Twiddle) twiddle() (int, int, bool) {
var i, j, k int
var x, y int
j = 1
for t.p[j] <= 0 {
j++
}
if t.p[j-1] == 0 {
for i = j - 1; i != 1; i-- {
t.p[i] = -1
}
t.p[j] = 0
x = 0
t.p[1] = 1
y = j - 1
} else {
if j > 1 {
t.p[j-1] = 0
}
j++
for t.p[j] > 0 {
j++
}
k = j - 1
i = j
for t.p[i] == 0 {
t.p[i] = -1
i++
}
if t.p[i] == -1 {
t.p[i] = t.p[k]
x = i - 1
y = k - 1
t.p[k] = -1
} else {
if i == t.p[0] {
return x, y, true
}
t.p[j] = t.p[i]
t.p[i] = 0
x = j - 1
y = i - 1
}
}
return x, y, false
}
you can use my tweedle package as follow:
tw := tweedle.New(1, 2)
for b := tw.Next(); b != nil; b = tw.Next() {
fmt.Println(b)
}
I successfully implemented Merge Sort Parallely on Google Go, but the problem is that sometimes parallel solution takes more time to sort than normal.
Here is my code:
package main
import "fmt"
import "math/rand"
import "time"
import "sync"
const (
n = 1000000;
)
var nProcess = 1;
func generateData() [n]int {
var data [n]int;
rand.Seed(time.Now().UnixNano());
for i := 0; i < n; i++ {
data[i] = rand.Intn(100);
}
return data;
}
func merge(a []int, b []int) []int {
i, j, k := 0, 0, 0
var out = make([]int, len(a)+len(b));
for ; i < len(a) && j < len(b); k++ {
if a[i] < b[j] {
out[k] = a[i]
i++
} else {
out[k] = b[j]
j++
}
}
if i < len(a) {
copy(out[k:], a[i:])
} else {
copy(out[k:], b[j:])
}
return out;
}
func mergeSort(data []int, level int) []int {
var halfSize = len(data)/2;
var a = make([]int, halfSize);
var b = make([]int, halfSize);
var low = 0;
var mid = (0 + len(data)-1) / 2;
var high = len(data)-1;
a = data[low:mid+1];
b = data[mid+1:high+1];
level = level + 1;
var wg sync.WaitGroup
if(len(data) > 1) {
if( level < nProcess ) {
wg.Add(2);
go func() { go func() { b = mergeSort(b[:], level); wg.Done(); }(); a = mergeSort(a[:], level); wg.Done(); }()
wg.Wait();
}else {
a = mergeSort(a[:], level);
b = mergeSort(b[:], level);
}
}
var out = merge(a[:], b[:]);
return out;
}
func main() {
var data = generateData();
nProcess = 1;
start := time.Now();
var data2 = mergeSort(data[:], 1);
duration := time.Since(start);
fmt.Println("Processes: ", nProcess);
fmt.Println("Data: ", len(data2));
fmt.Println("Duration: ", duration);
nProcess = 4;
start = time.Now();
data2 = mergeSort(data[:], 1);
duration = time.Since(start);
fmt.Println("Processes: ", nProcess);
fmt.Println("Data: ", len(data2));
fmt.Println("Duration: ", duration);
}
I need to compare results with how many processes do the job. I decided to declare a nProcess. For example if it is = 1 then no parallel code will be executed as you can see from if statement. Everything will be calculated in normal flow. The bigger number is, the deeper in merge sort portions will be executed parallely. The problem is that results are not that impressively different as I think it should be. Maybe you can spot where I did a mistake? Is merging is really executed parallely?
EDIT: The question essentially asks to generate prime numbers up to a certain limit. The original question follows.
I want my if statement to become true if only these two conditions are met:
for i := 2; i <= 10; i++ {
if i%i == 0 && i%1 == 0 {
} else {
}
}
In this case every possible number gets past these conditions, however I want only the numbers 2, 3, 5, 7, 11... basically numbers that are divisible only with themselves and by 1 to get past, with the exception being the very first '2'. How can I do this?
Thanks
It seems you are looking for prime numbers. However the conditions you described are not sufficient. In fact you have to use an algorithm to generate them (up to a certain limit most probably).
This is an implementation of the Sieve of Atkin which is an optimized variation of the ancient Sieve of Eratosthenes.
Demo: http://play.golang.org/p/XXiTIpRBAu
For the sake of completeness:
package main
import (
"fmt"
"math"
)
// Only primes less than or equal to N will be generated
const N = 100
func main() {
var x, y, n int
nsqrt := math.Sqrt(N)
is_prime := [N]bool{}
for x = 1; float64(x) <= nsqrt; x++ {
for y = 1; float64(y) <= nsqrt; y++ {
n = 4*(x*x) + y*y
if n <= N && (n%12 == 1 || n%12 == 5) {
is_prime[n] = !is_prime[n]
}
n = 3*(x*x) + y*y
if n <= N && n%12 == 7 {
is_prime[n] = !is_prime[n]
}
n = 3*(x*x) - y*y
if x > y && n <= N && n%12 == 11 {
is_prime[n] = !is_prime[n]
}
}
}
for n = 5; float64(n) <= nsqrt; n++ {
if is_prime[n] {
for y = n * n; y < N; y += n * n {
is_prime[y] = false
}
}
}
is_prime[2] = true
is_prime[3] = true
primes := make([]int, 0, 1270606)
for x = 0; x < len(is_prime)-1; x++ {
if is_prime[x] {
primes = append(primes, x)
}
}
// primes is now a slice that contains all primes numbers up to N
// so let's print them
for _, x := range primes {
fmt.Println(x)
}
}
Here's a golang sieve of Eratosthenes
package main
import "fmt"
// return list of primes less than N
func sieveOfEratosthenes(N int) (primes []int) {
b := make([]bool, N)
for i := 2; i < N; i++ {
if b[i] == true { continue }
primes = append(primes, i)
for k := i * i; k < N; k += i {
b[k] = true
}
}
return
}
func main() {
primes := sieveOfEratosthenes(100)
for _, p := range primes {
fmt.Println(p)
}
}
The simplest method to get "numbers that are divisible only with themselves and by 1", which are also known as prime numbers is: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
It's not a "simple if statement".
If you don't mind a very small chance (9.1e-13 in this case) of them not being primes you can use ProbablyPrime from math/big like this (play)
import (
"fmt"
"math/big"
)
func main() {
for i := 2; i < 1000; i++ {
if big.NewInt(int64(i)).ProbablyPrime(20) {
fmt.Printf("%d is probably prime\n", i)
} else {
fmt.Printf("%d is definitely not prime\n", i)
}
}
}
Just change the constant 20 to be as sure as you like that they are primes.
Simple way(fixed):
package main
import "math"
const n = 100
func main() {
print(1, " ", 2)
L: for i := 3; i <= n; i += 2 {
m := int(math.Floor(math.Sqrt(float64(i))))
for j := 2; j <= m; j++ {
if i%j == 0 {
continue L
}
}
print(" ", i)
}
}
just change the 100 in the outer for loop to the limit of the prime number you want to find. cheers!!
for i:=2; i<=100; i++{
isPrime:=true
for j:=2; j<i; j++{
if i % j == 0 {
isPrime = false
}
}
if isPrime == true {
fmt.Println(i)
}
}
}
Here try this by checking all corner cases and optimised way to find you numbers and run the logic when the function returns true.
package main
import (
"math"
"time"
"fmt"
)
func prime(n int) bool {
if n < 1 {
return false
}
if n == 2 {
return true
}
if n % 2 == 0 && n > 2 {
return false
}
var maxDivisor = int(math.Floor(math.Sqrt(float64 (n))))
//d := 3
for d:=3 ;d <= 1 + maxDivisor; d += 2 {
if n%d == 0 {
return false
}
}
return true
}
//======Test Function=====
func main() {
// var t0 = time.Time{}
var t0= time.Second
for i := 1; i <= 1000; i++ {
fmt.Println(prime(i))
}
var t1= time.Second
println(t1 - t0)
}
package main
import (
"fmt"
)
func main() {
//runtime.GOMAXPROCS(4)
ch := make(chan int)
go generate(ch)
for {
prime := <-ch
fmt.Println(prime)
ch1 := make(chan int)
go filter(ch, ch1, prime)
ch = ch1
}
}
func generate(ch chan int) {
for i := 2; ; i++ {
ch <- i
}
}
func filter(in, out chan int, prime int) {
for {
i := <-in
if i%prime != 0 {
out <- i
}
}
}
A C like logic (old school),
package main
import "fmt"
func main() {
var num = 1000
for j := 2; j < num ; j++ {
var flag = 0
for i := 2; i <= j/2 ; i++ {
if j % i == 0 {
flag = 1
break
}
}
if flag == 0 {
fmt.Println(j)
}
}
}
Simple solution for generating prime numbers up to a certain limit:
func findNthPrime(number int) int {
if number < 1{
fmt.Println("Please provide positive number")
return number
}
var primeCounter, nthPrimeNumber int
for i:=2; primeCounter < number; i++{
isPrime := true
for j:=2; j <= int(math.Sqrt(float64(i))) && i != 2 ; j++{
if i % j == 0{
isPrime = false
}
}
if isPrime{
primeCounter++
nthPrimeNumber = i
fmt.Println(primeCounter, "th prime number is ", nthPrimeNumber)
}
}
fmt.Println("Nth prime number is ", nthPrimeNumber)
return nthPrimeNumber
}
A prime number is a positive integer that is divisible only by 1 and itself. For example: 2, 3, 5, 7, 11, 13, 17.
What is Prime Number?
A Prime Number is a whole number that cannot be made by multiplying other whole numbers
A prime number (or a prime) is a natural number greater than 1 that is not a product of two smaller natural numbers. A natural number greater than 1 that is not prime is called a composite number.
Go Language Program to Check Whether a Number is Prime or Not
https://www.golanguagehub.com/2021/01/primenumber.html