prime numbers program gives wrong answer - go

I recently created a program which will tell you if a number is prime or not. It gets all answers right but the prime number of 9.
package main
import "fmt"
func isPrime(num int) bool {
for x := 2; x > 1; x++ {
if num%2 == 0 {
return false
} else {
return true
}
}
return true
}
func main() {
fmt.Printf("is it a prime number: %v \n", isPrime(9))
}
What is the problem?
Thanks in advance!

1- Here is the working version of your code: try it on The Go Playground.
package main
import "fmt"
func isPrime(num int) bool {
if num < 2 {
return false
}
for x := 2; x < num; x++ {
if num%x == 0 {
return false
}
}
return true
}
func main() {
fmt.Printf("is it a prime number: %v \n", isPrime(9))
}
2- The only even prime is 2, so it is better to check it first:
if n == 2 {
return true
}
Then there is no other even prime number: remove them all, and there is no prime number less than 2:
if n < 2 || n&1 == 0 {
return false
}
and you don't need to check more than square root of n:
sqrt := int(math.Sqrt(float64(n)))
And now you may start from 3, with just odd numbers (i += 2):
for i := 3; i <= sqrt; i += 2 {
if n%i == 0 {
return false
}
}
Try it on The Go Playground:
package main
import (
"fmt"
"math"
)
func isPrime(n int) bool {
if n == 2 {
return true
}
if n < 2 || n&1 == 0 {
return false
}
sqrt := int(math.Sqrt(float64(n)))
for i := 3; i <= sqrt; i += 2 {
if n%i == 0 {
return false
}
}
return true
}
func main() {
fmt.Printf("is it a prime number: %v \n", isPrime(9))
for i := 0; i < 120; i++ {
if isPrime(i) {
fmt.Print(i, " ")
}
}
fmt.Println()
}
output:
is it a prime number: false
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113
See:
Prime number
Generating primes

As it is, your code is only checking if a number's parity and returning false if it is even. I don't actually know Go, but I did manage to work out this problem for you using the following code:
func isPrime(num int) bool {
for x := 2; x < num; x++{
if num%x == 0 && num!=2{
return false
}
}return true;
}

According to prime number definition A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself, in your code you're only checking if it's odd or not.
I left you a fast solution in Go https://play.golang.org/p/2XXTUFbjhy It does only go until the square root of the number.
func isPrime(n int) bool {
if n <= 1 {
return false
}
for ix, sqn := 2, int(math.Sqrt(float64(n))); ix <= sqn; ix++ {
if n%ix == 0 {
return false
}
}
return true
}
Also if you're interested in a faster way to know if a number is primer or not I recommend you read about the Sieve of Eratosthenes

Related

how to simplimize my go script because always get time out in hackerrank

I have a test interview as a Go Developer and have to do some of the tasks on hackerrank.
I've done the task, but when I submit my script it always "times out".. maybe because there are a lot of loops that I use to do this function, and the task is :
So, my solution are :
Loop from a to b with a increment.
Define the digit sum with modulus by 10, sum the result with the leftover.
Define the square sum with converting int(a) to string then use for-range to sum the values.
checking if digit sum and square sum is a prime number, if so then count++
My script is :
func main() {
fmt.Printf("Jadi ada %d bilangan prima \n", luckyNumbers(1, 20))
}
func luckyNumbers(a int64, b int64) int64 {
count := 0
for min, max := a, b; min <= max; min++ {
squareSum := digitSquare(min)
digitSum := digitSum(min)
if isPrime(digitSum) && isPrime(squareSum) {
count++
}
}
return int64(count)
}
func digitSquare(number int64) int64 {
numStr := strconv.Itoa(int(number))
var firstDigit, secondDigit int
for _, digit := range numStr {
numInt, _ := strconv.Atoi(string(digit))
pow := int(math.Pow(float64(numInt), 2))
if firstDigit == 0 {
firstDigit += pow
} else {
secondDigit += pow
}
}
squareSum := int64(firstDigit + secondDigit)
return squareSum
}
func digitSum(number int64) int64 {
var remainder, sumResult int64 = 0, 0
for number != 0 {
remainder = number % 10
sumResult += remainder
number /= 10
}
return sumResult
}
func isPrime(num int64) bool {
if num < 2 {
return false
}
for i := int64(2); i <= int64(math.Sqrt(float64(num))); i++ {
if num%i == 0 {
return false
}
}
return true
}
The script above is the best script that I can make right now, I understand that I do a lot of iterations, so when I try to submit it will always show "time out". So I want to learn from you and want to see if there is a simpler script so that it can be submitted.
Thank you,
Regards

is power of 2 with golang

I want to check whether the number given is a power of 2. I have written a code but I cannot return true or false, I think somewhere there is an infinite loop. I am only allowed to use functions from imported packages on the code. I could not figure out what to do to correct the mistake. I would be glad if you can help me :)
package main
import (
"os"
"strconv"
)
func main() {
for len(os.Args) == 2 {
numbers, err := strconv.Atoi(os.Args[1])
if err != nil {
panic(err)
}
newnum := numbers
counts := 0
for numbers != 1 {
if newnum%2 != 0 {
} else {
newnum = newnum / 2
}
counts++
}
var x int = 2 ^ counts
if x == numbers {
return true
} else {
return false
}
}
}
`
As commented by #phuclv , I have created a sample program for your scenario by using n & (n - 1) == 0 as follows :
//Let's assume n = 16(00010000)
//Now find x = n-1 => 15(00001111) => x & n => 0
func CheckPowerOfTwo(n int) int {
//added one corner case if n is zero it will also consider as power 2
if n==0{
return 1
}
return n & (n - 1)
}
func main() {
var n = 16
flag := CheckPowerOfTwo(n)
if flag == 0 {
fmt.Printf("Given %d number is the power of 2.\n", n)
} else {
fmt.Printf("Given %d number is not the power of 2.\n", n)
}
}
You can run it here : https://go.dev/play/p/9cRWwiFAIn8

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

Go and a bad prime number algorithm

I wrote this prime number sieving algorithm and it doesn't run properly. I can't find the error in the algorithm itself. Could someone help me?
This is what it's supposed to print:
[2 3 5 7 11 13 17 19 23 29]
Versus what it actually prints:
[3 5 7 11 13 17 19 23 25 29]
.
package main
import "fmt"
func main() {
var primes = sieve(makeNumbers(29))
fmt.Printf("%d\n", primes);
}
func makeNumbers(n int) []int {
var numbers = make([]int, n - 1)
for i := 0; i < len(numbers); i++ {
numbers[i] = i + 2
}
return numbers
}
func sieve(numbers []int) []int {
var numCopy = numbers
var max = numbers[len(numbers)-1]
var sievedNumbers = make([]int, 0)
for i := 0; numCopy[i]*numCopy[i] <= max; i++ {
for j := i; j < len(numCopy); j++ {
if numCopy[j] % numCopy[i] != 0 || j == i {
sievedNumbers = append(sievedNumbers, numCopy[j])
}
}
numCopy = sievedNumbers
sievedNumbers = make([]int, 0)
}
return numCopy
}
It should be "for j := 0" rather than "for j := i".

Resources