Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dc40033
Showing
4 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]); | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |