Hi --

On Sat, 25 Jul 2009, Lloyd Linklater wrote:

> I am writing a little thing to find all the prime numbers to a million.
> I got it to work this way:
>
> highestPrime = 1_000_000
> primes = Array.new(highestPrime, true)
>
> currentNum = 3
> while currentNum < highestPrime do
>  (currentNum*currentNum).step(highestPrime, currentNum * 2) { |i|
> primes[i] = false }
>  currentNum += 2
>  while primes[currentNum] == false do
>    currentNum += 2
>  end
> end
>
> I am unhappy with using currentNum += 2 twice.  I very much want to
> write something like this:
>
> while currentNum < highestPrime do
>  (currentNum*currentNum).step(highestPrime, currentNum * 2) { |i|
> primes[i] = false }
>  currentNum += 2 until primes[currentNum] == true
> end
>
> but that just hangs the program.  What am I missing?

When you do:

   statement until condition

statement isn't executed at all unless condition is true. Since
primes[3] is false, the incrementation never takes place.

You can guarantee that the body of an until statement gets executed at
least once by doing it like this:

   begin
     num +=2
   end while primes[num]

There's another issue here, though. Since the default value for
non-existent array values is nil, the test for truth will fail even if
num has gone over the maximum. So you might want to flip the logic:

max = 10
non_primes = Array.new(max)
num = 3

while num < max do
   (num * num).step(max, num * 2) { |i| non_primes[i] = true }
   begin
     num += 2
   end while non_primes[num]
end


David

-- 
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN)