Finding Max Value Below Zero - go

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

Related

Is my golang func run time analysis correct?

enter image description here
This code snippet is for give two slice of binary number a1 and a2 to return sum slice r1, and I want to figure out how long spend with this code snippet figure out the result.
and I figure out the factorial result.
Is my analysis right?
my analysis for time complexity is:
cn + (n*n!) + c
the Code is:
func BinaryPlus(a1 []int, a2 []int) []int {
var r1 = make([]int, len(a1), 2*(len(a1)))
for i := 0; i < len(a1); i++ {
r1[i] = a1[i] + a2[i]
}
// 二分反转
ReverseSlice(r1)
r1 = append(r1, 0)
final := 0
for i := 0; final != 1; i++ {
isOver := 1
for j := 0; j < len(r1); j++ {
if r1[j] > 1 {
r1[j] = r1[j] % 2
r1[j+1] += 1
if r1[j+1] > 1 {
isOver = 0
}
}
}
if isOver == 1 {
final = 1
}
}
// 二分反转
ReverseSlice(r1)
return r1
}
func ReverseSlice(s interface{}) {
n := reflect.ValueOf(s).Len()
swap := reflect.Swapper(s)
for i, j := 0, n-1; i < j; i, j = i+1, j-1 {
swap(i, j)
}
}
It is not entirely clear that your code, as written, is correct. The size cap for your result array could be too small. Consider the case that len(a2) > 2*len(a1): the r1 := make(...) will not reserve enough in this case. Further, the initial for loop will miss adding in the more significant bits of a2.
Binary addition should have no more than O(n) complexity. You can do it with a single for loop. n = 1+max(len(a1),len(a2)):
package main
import (
"fmt"
"reflect"
)
func BinaryPlus(a1 []int, a2 []int) []int {
reserve := len(a1) + 1
if x := len(a2) + 1; x > reserve {
reserve = x
}
hold := 0
maxBit := 1
ans := make([]int, reserve)
for i := 1; i <= reserve; i++ {
hold = hold / 2
if i <= len(a1) {
hold += a1[len(a1)-i]
}
if i <= len(a2) {
hold += a2[len(a2)-i]
}
ans[reserve-i] = hold & 1
if hold != 0 && i > maxBit {
maxBit = i
}
}
return ans[reserve-maxBit:]
}
func main() {
tests := []struct {
a, b, want []int
}{
{
a: []int{1},
b: []int{0},
want: []int{1},
},
{
a: []int{1, 0},
b: []int{0, 0, 1},
want: []int{1, 1},
},
{
a: []int{1, 0, 0, 1},
b: []int{1, 1, 1, 1, 0},
want: []int{1, 0, 0, 1, 1, 1},
},
{
a: []int{0, 0},
b: []int{0, 0, 0, 0, 0},
want: []int{0},
},
}
bad := false
for i := 0; i < len(tests); i++ {
t := tests[i]
c := BinaryPlus(t.a, t.b)
if !reflect.DeepEqual(c, t.want) {
fmt.Println(t.a, "+", t.b, "=", c, "; wanted:", t.want)
bad = true
}
}
if bad {
fmt.Println("FAILED")
} else {
fmt.Println("PASSED")
}
}

Unexpected outcome of while loop?

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 {
// ...
}

Most efficient method of finding the number of common factors of two numbers

I have two numbers for example the numbers are 12 and 16.
factors of 12 are 1, 2, 3, 4, 6, 12
factors of 16 are 1, 2, 4, 8, 16
common factors of these two numbers are 1, 2 and 4.
So the number of common factors are 3. I need to build a Go program for finding the number common factors of two numbers. But the program should be efficient and with minimum number of loops or without loops.
I will provide my code and you can also contribute and suggest with another best methods.
package main
import "fmt"
var (
fs []int64
fd []int64
count int
)
func main() {
commonFactor(16, 12)
commonFactor(5, 10)
}
func commonFactor(num ...int64) {
count = 0
if num[0] < 1 || num[1] < 1 {
fmt.Println("\nFactors not computed")
return
}
for _, val := range num {
fs = make([]int64, 1)
fmt.Printf("\nFactors of %d: ", val)
fs[0] = 1
apf := func(p int64, e int) {
n := len(fs)
for i, pp := 0, p; i < e; i, pp = i+1, pp*p {
for j := 0; j < n; j++ {
fs = append(fs, fs[j]*pp)
}
}
}
e := 0
for ; val&1 == 0; e++ {
val >>= 1
}
apf(2, e)
for d := int64(3); val > 1; d += 2 {
if d*d > val {
d = val
}
for e = 0; val%d == 0; e++ {
val /= d
}
if e > 0 {
apf(d, e)
}
}
if fd == nil {
fd = fs
}
fmt.Println(fs)
}
for _, i := range fs {
for _, j := range fd {
if i == j {
count++
}
}
}
fmt.Println("Number of common factors =", count)
}
Output is :
Factors of 16: [1 2 4 8 16] Factors of 12: [1 2 4 3 6 12]
Number of common factors = 3
Factors of 5: [1 5] Factors of 10: [1 2 5 10]
Number of common factors = 2
Goplayground
Answer 1, with no loops just recursion
package main
import (
"fmt"
"os"
"strconv"
)
func factors(n int, t int, res *[]int) *[]int {
if t != 0 {
if (n/t)*t == n {
temp := append(*res, t)
res = &temp
}
res = factors(n, t-1, res)
}
return res
}
func cf(l1 []int, l2 []int, res *[]int) *[]int {
if len(l1) > 0 && len(l2) > 0 {
v1 := l1[0]
v2 := l2[0]
if v1 == v2 {
temp := append(*res, v1)
res = &temp
l2 = l2[1:]
}
if v2 > v1 {
l2 = l2[1:]
} else {
l1 = l1[1:]
}
res = cf(l1, l2, res)
}
return res
}
func main() {
n, err := strconv.Atoi(os.Args[1])
n2, err := strconv.Atoi(os.Args[2])
if err != nil {
fmt.Println("give a number")
panic(err)
}
factorlist1 := factors(n, n, &[]int{})
factorlist2 := factors(n2, n2, &[]int{})
fmt.Printf("factors of %d %v\n", n, factorlist1)
fmt.Printf("factors of %d %v\n", n2, factorlist2)
common := cf(*factorlist1, *factorlist2, &[]int{})
fmt.Printf("number of common factors = %d\n", len(*common))
}
However, this blows up with larger numbers such as 42512703
replacing the func that do the work with iterative versions can cope with bigger numbers
func factors(n int) []int {
res := []int{}
for t := n; t > 0; t-- {
if (n/t)*t == n {
res = append(res, t)
}
}
return res
}
func cf(l1 []int, l2 []int) []int {
res := []int{}
for len(l1) > 0 && len(l2) > 0 {
v1 := l1[0]
v2 := l2[0]
if v1 == v2 {
res = append(res, v1)
l2 = l2[1:]
}
if v2 > v1 {
l2 = l2[1:]
} else {
l1 = l1[1:]
}
}
return res
}
func Divisors(n int)int{
prev := []int{}
for i := n;i > 0;i--{
prev = append(prev,i)
}
var res int
for j := prev[0];j > 0;j--{
if n % j == 0 {
res++
}
}
return res
}

Too many results in a loop for Project Euler #145

I am trying to create a solution for Project Euler #145. I am writing in Go. When I run my program I get a result of 125. The expected result is 120. I have 2 different ways I have tried to write the code but both come up with the same answer. Any help pointing out my error would be appreciated.
Code option #1 using strings:
package main
import (
"fmt"
"strconv"
)
//checks to see if all the digits in the number are odd
func is_Odd(sum int) bool {
intString := strconv.Itoa(sum)
for x := len(intString); x > 0; x-- {
newString := intString[x-1]
if newString%2 == 0 {
return false
}
}
return true
}
//reverse the number passed
func reverse_int(value int) int {
intString := strconv.Itoa(value)
newString := ""
for x := len(intString); x > 0; x-- {
newString += string(intString[x-1])
}
newInt, err := strconv.Atoi(newString)
if err != nil {
fmt.Println("Error converting string to int")
}
return newInt
}
//adds 2 int's passed to it and returns an int
func add(x int, y int) int {
return x + y
}
func main() {
//functions test code
/*y := 35
x := reverse_int(y)
z := add(x,y)
fmt.Println(is_Odd(z))*/
counter := 1
for i := 1; i < 1000; i++ {
flipped := reverse_int(i)
sum := add(flipped, i)
oddCheck := is_Odd(sum)
if oddCheck {
fmt.Println(counter, ":", i, "+", flipped, "=", sum)
counter++
}
}
counter--
fmt.Println("total = ", counter)
}
Code option #2 using only ints:
package main
import (
"fmt"
)
var counter int
//breaks down an int number by number and checks to see if
//all the numbers in the int are odd
func is_Odd(n int) bool {
for n > 0 {
remainder := n % 10
if remainder%2 == 0 {
return false
}
n /= 10
}
return true
}
//adds 2 int's passed to it and returns an int
func add(x int, y int) int {
return x + y
}
//reverses the int passed to it and returns an int
func reverse_int(n int) int {
var new_int int
for n > 0 {
remainder := n % 10
new_int *= 10
new_int += remainder
n /= 10
}
return new_int
}
func main() {
//functions test code
/*y := 35
x := reverse_int(y)
z := add(x,y)
fmt.Println(is_Odd(z))*/
counter = 1
for i := 1; i < 1000; i++ {
flipped := reverse_int(i)
sum := add(flipped, i)
oddCheck := is_Odd(sum)
if oddCheck {
//fmt.Println(counter,":",i,"+",flipped,"=",sum)
counter++
}
}
counter--
fmt.Println(counter)
}
Leading zeroes are not allowed in either n or reverse(n) so in reverse(n int) int remove Leading zeroes like so:
remainder := n % 10
if first {
if remainder == 0 {
return 0
}
first = false
}
try this:
package main
import (
"fmt"
)
//breaks down an int number by number and checks to see if
//all the numbers in the int are odd
func isOdd(n int) bool {
if n <= 0 {
return false
}
for n > 0 {
remainder := n % 10
if remainder%2 == 0 {
return false
}
n /= 10
}
return true
}
//adds 2 int's passed to it and returns an int
func add(x int, y int) int {
return x + y
}
//reverses the int passed to it and returns an int
func reverse(n int) int {
first := true
t := 0
for n > 0 {
remainder := n % 10
if first {
if remainder == 0 {
return 0
}
first = false
}
t *= 10
t += remainder
n /= 10
}
return t
}
func main() {
counter := 0
for i := 0; i < 1000; i++ {
flipped := reverse(i)
if flipped == 0 {
continue
}
sum := add(flipped, i)
if isOdd(sum) {
counter++
//fmt.Println(counter, ":", i, "+", flipped, "=", sum)
}
}
fmt.Println(counter)
}
output:
120
You're ignoring this part of the criteria:
Leading zeroes are not allowed in either n or reverse(n).
Five of the numbers you count as reversible end in 0. (That means their reverse has a leading zero.) Stop counting those as reversible and you're done.
Some positive integers n have the property that the sum [ n +
reverse(n) ] consists entirely of odd (decimal) digits. For instance,
36 + 63 = 99 and 409 + 904 = 1313. We will call such numbers
reversible; so 36, 63, 409, and 904 are reversible. Leading zeroes are
not allowed in either n or reverse(n).
All digits of the sum must all be odd.
Try this one: https://play.golang.org/p/aUlvKrb9SB

Generating prime numbers in Go

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

Resources