Skip to content

Commit

Permalink
First Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
x1m3 committed May 14, 2016
0 parents commit dc40033
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 0 deletions.
25 changes: 25 additions & 0 deletions main.go
@@ -0,0 +1,25 @@
package main

import "fmt"
import "os"
import "strconv"

func main() {

if len(os.Args)!=4 {
fmt.Printf("Usage %s <min> <max> [parallel|sequential]\n", os.Args[0])
fmt.Printf("Returns the list of prime numbers between <min> and <max>.\n")
fmt.Printf("The third parameter changes the algorithm used\n")
} else {
min,_ := strconv.ParseInt(os.Args[1],10,64)
max,_ := strconv.ParseInt(os.Args[2],10,64)
if os.Args[3]=="parallel" {
fmt.Printf("\nLa lista de primos es", primesInRangeParallel(min,max))
}else if os.Args[3]=="sequential" {
fmt.Printf("\nLa lista de primos es", primesInRange(min,max))
} else {
fmt.Printf("Don't know what does %s means. Valid values are parallel or sequential",os.Args[3]);
}
}
}

39 changes: 39 additions & 0 deletions prime.go
@@ -0,0 +1,39 @@
package main

import "math"

/**
* A non very optimal function that checks if a number is prime
*
* A prime number is one that only is divisible by 1 or itself
*
* The algorithm is pure brute force, iterating by numbers smaller
* than the candidate and calculating the modulus
*
* We only use 3 optimizations.
* 1) If the number is different than 2, but divisible by 2, it is not a prime.
* 2) Then, we only test for odd divisors (3,5,7,9, etc..)
* 3) We only check for numbers smaller or equal the root square
* of the candidate. It is imposible to have divisors greater
* than this value
*/
func isPrime(candidate int64) (bool) {
var i,limit int64

if candidate==2 {
return true
}

if math.Mod(float64(candidate), 2)==0 {
return false;
}


limit = int64( math.Ceil( math.Sqrt(float64(candidate) )))
for i=3; i<=limit; i+=2 { //Only odd numbers
if math.Mod(float64(candidate), float64(i))==0 {
return false
}
}
return true
}
82 changes: 82 additions & 0 deletions rangeParallel.go
@@ -0,0 +1,82 @@
package main

import "fmt"

// We will use this struct to communicate results via a channel
type PrimeResult struct {
number int64 // A number
prime bool // Is prime or not
}


/**
* A function to return a prime calculation over a channel. This way
* we don't need to have 2 versions of isPrime function, one for
* sequential calculations and another for paralel
*/

func isPrimeAsync(number int64, channel chan PrimeResult) {

result:= new (PrimeResult)
result.number= number
result.prime= isPrime(number)
channel <- *result
}



/**
* Accepts a range of integers [min, max] and a channel and it executes
* in PARALEL the processes that check if a number is prime or not.
*
* This function does nothing with the result. In another point, somebody
* will have to read the channel and process the results
*/
func firePrimeCalculations( min int64, max int64, channel chan PrimeResult) {
var i int64
for i=min; i<=max; i++ {
go isPrimeAsync(i, channel)
}
}


/**
* Accepts a range of integers [min, max] and
* returns an array with all the prime numbers in this range.
*
* Execution is done in paralel. First it fires all the
* processes that check for a prime number. These processes
* will write the result in a channel.
*
* We will receive the results over this channel creating the
* list of prime numbers and returning it
*
*/

func primesInRangeParallel( min int64, max int64) []int64 {
var primeNumbers []int64
var res PrimeResult
var prev int64

channel := make(chan PrimeResult)
defer close(channel)

go firePrimeCalculations(min, max, channel)

prev=0
for i:=min; i<=max; i++ {
res = <- channel
if res.prime {
primeNumbers= append( primeNumbers, res.number)

done := 100 * (i-min)/(max-min)
if prev!=done {
fmt.Printf("%d %% done.\n",done)
prev=done
}
}
}
return primeNumbers
}


31 changes: 31 additions & 0 deletions rangeSequential.go
@@ -0,0 +1,31 @@
package main

import "fmt"


/**
* Accepts a range of integers [min, max] and
* returns an array with all the prime numbers in this range.
*
* Execution is done sequentially
*/

func primesInRange( min int64, max int64) []int64 {
var primeNumbers []int64
var prev int64

prev=0
for i:=min; i<=max; i++ {
if isPrime(i) {
primeNumbers= append(primeNumbers, i)

// -- Stupid code that shows the progress to the user.
done := 100 * (i-min)/(max-min)
if prev!=done {
fmt.Printf("%d %% done.\n",done)
prev=done
}
}
}
return primeNumbers
}

0 comments on commit dc40033

Please sign in to comment.