Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

150 lines (117 sloc) 2.718 kB
require "spec_helper"
describe "sieve of Eratosthenes" do
# http://golang.org/doc/go_tutorial.html#tmp_353
it "should work using Channel primitives" do
# send the sequence 2,3,4, ... to returned channel
def generate(channels)
ch = channel!(Integer)
channels << ch
go!{ i = 1; loop { ch << i+= 1} }
return ch
end
# filter out input values divisible by *prime*, send rest to returned channel
def filter(in_channel, prime, channels)
out = channel!(Integer)
channels << out
go! do
loop do
i, _ = in_channel.receive
out << i if (i % prime) != 0
end
end
return out
end
def sieve(channels)
out = channel!(Integer)
channels << out
go! do
ch = generate(channels)
loop do
prime, _ = ch.receive
out << prime
ch = filter(ch, prime, channels)
end
end
return out
end
# run the sieve
n = 20
nth = false
channels = []
primes = sieve(channels)
result = []
if nth
n.times { primes.receive }
puts primes.receive[0]
else
loop do
p, _ = primes.receive
if p <= n
result << p
else
break
end
end
end
result.should == [2,3,5,7,11,13,17,19]
channels.each(&:close)
end
it "should work with Ruby blocks" do
# send the sequence 2,3,4, ... to returned channel
generate = Proc.new do |channels|
ch = channel!(Integer)
channels << ch
go! do
i = 1
loop { ch << i+= 1 }
end
ch
end
# filter out input values divisible by *prime*, send rest to returned channel
filtr = Proc.new do |in_channel, prime, channels|
out = channel!(Integer)
channels << out
go! do
loop do
i, _ = in_channel.receive
out << i if (i % prime) != 0
end
end
out
end
sieve = Proc.new do |channels|
out = channel!(Integer)
channels << out
go! do
ch = generate.call(channels)
loop do
prime, _ = ch.receive
out << prime
ch = filtr.call(ch, prime, channels)
end
end
out
end
# run the sieve
n = 20
nth = false
channels = []
primes = sieve.call(channels)
result = []
if nth
n.times { primes.receive }
puts primes.receive[0]
else
loop do
p, _ = primes.receive
if p <= n
result << p
else
break
end
end
end
result.should == [2,3,5,7,11,13,17,19]
channels.each(&:close)
end
end
Jump to Line
Something went wrong with that request. Please try again.