package simulation.sieve.try2;

/*
 * Objectize the algorithm.
 */

class Sieve2
{
    def eratosthenes(a_limit)
    {
        def primes = []

        sieve(a_limit) { primeNumber ->
       
            primes << primeNumber
        }

        primes
    }

    def sieve(a_limit, a_foundPrime)
    {
        def numbers = Numbers.newInstance(a_limit)

        (2..a_limit).each { factor ->

            numbers.each(factor) { number ->
               
                if (number.hasPrimeFactor(factor))
                {
                    number.isNotPrime()
                }
            }

            if (numbers.contains(factor))
            {
                a_foundPrime(factor)
            }
        }
    }
}

class Numbers
{
    def numbers = []

    Numbers(a_limit)
    {
        a_limit.times { number ->
            numbers << Number.newInstance(number)
        }
    }
   
    def contains(a_number)
    {
        def contains = false
       
        for (number in numbers)
        {
            if (number.number == a_number)
            {
                contains = true
                break
            }
        }
       
        contains
    }
   
    def each(a_factor, a_closure)
    {
        numbers.each { number ->

            if (number.number > a_factor && number.mayBePrime())
            {
                a_closure(number)
            }
        }
    }

    def String toString()
    {
        numbers.toString()
    }
}

class Number
{
    def number

    Number(a_number)
    {
        number = a_number
    }
   
    def isNotPrime()
    {
        number = 0
    }
   
    def mayBePrime()
    {
        number != 0
    }
   
    def hasPrimeFactor(a_factor)
    {
        number != a_factor && number % a_factor == 0
    }

    def String toString()
    {
        number
    }
}


...