Skip to content

Instantly share code, notes, and snippets.

@Janiczek
Last active December 10, 2015 21:38
Show Gist options
  • Select an option

  • Save Janiczek/4496732 to your computer and use it in GitHub Desktop.

Select an option

Save Janiczek/4496732 to your computer and use it in GitHub Desktop.
Imitation of http://numbersimulation.com/ using different languages and techniques, currently Go and Erlang.
-module(go).
-export([prime/3,
server/0,
server/4,
start/0]).
prime(OldTick, N, Server) ->
receive
false -> ok
end,
Tick = OldTick + 1,
if Tick =:= N ->
Server ! true,
prime(0, N, Server);
true ->
Server ! false,
prime(Tick, N, Server)
end.
server() ->
Current = 2,
Count = 0,
Primes = dict:new(),
PID = self(),
server(Current,Count,Primes,PID).
server(Current,Count,Primes,PID) ->
% send tick to all primes
dict:map(fun (_,V) -> V ! false end, Primes),
% wait for all ACKs
Falses = lists:sum(lists:map(fun (_) -> receive false -> 1;
_ -> 0 end end,
lists:seq(1,Count))),
% if you get ACKs from everybody, create a new prime
if Falses =:= Count ->
PrimePID = spawn(?MODULE,prime,[0,Current,PID]),
NewPrimes = dict:store(Current,PrimePID,Primes),
io:format("~p~n",[Current]),
server(Current+1, Count+1, NewPrimes, PID);
true ->
server(Current+1, Count, Primes, PID)
end.
start() ->
spawn(?MODULE,server,[]),
ok.
// inspired by http://www.numbersimulation.com/
package main
import "fmt"
// prime = worker
// --------------
// waits n ticks, then shoots true ("my composite"),
// else shoots false ("not my composite" or "ACK'd the tick")
func prime (n int, ch_tick chan bool, ch_server chan bool) {
tick := 0
for
{
<- ch_tick // get a tick
tick++
if tick == n {
tick = 0
ch_server <- true // hey! that's our multiple
} else {
ch_server <- false // ACK a tick
}
}
}
// server - make tick, wait for n messages,
// and if they are all ACKs (falses), you've got a new prime!
func server () {
current := 2
count := 0
msgs_for_me := make(chan bool)
primes := make(map [int] chan bool)
for
{
// send tick to all primes
for _,p := range primes {
p <- false // tick
}
// wait for all the ACKs
falses := 0
for i := 0; i < count; i++ {
response := <- msgs_for_me // get response
if response == false { falses++ }
}
// if you get ACKs from everybody, create a new prime
if falses == count {
primes[current] = make(chan bool)
go prime(current, primes[current], msgs_for_me)
count++
fmt.Println(current) // we've got a new prime!
}
// get to the next number
current++
}
}
func main() {
server()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment