View Raw SPL
/*****************************************************************************
*                                                                            *
*   PRIMES.SPL  Copyright (C) 2011-2024 DSP Development Corporation          *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Returns a series of prime numbers                           *
*                                                                            *
*   Revisions:   25 Feb 2011  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/

#if @HELP_PRIMES

    PRIMES

    Purpose: Generates a series of prime numbers in ascending order.

    Syntax:  PRIMES(n, "count", "nth", "silent")

                     n - An integer, the maximum prime value. The returned
                         series contains primes less than or equal to N.

               "count" - Optional. A string. If specified, only return the
                         count of primes <= N. Defaults to return the full
                         series of prime values.

                 "nth" - Optional. A string. If specified, only return the
                         nth prime <= n. Defaults to return the full
                         series of prime values.

              "silent" - Optional. A string. If specified, operate without
                         status messages. Defaults to "verbose", show
                         status messages.

    Alternate Syntax:

             PRIMES(pmin, pmax, "count", "nth", "silent")

                  pmin - An integer, the minimum prime value. The returned
                         series contains primes greater than or equal to PMIN.

                  pmax - An integer, the maximum prime value. The returned
                         series contains primes less than or equal to PMAX.

               "count" - Optional. A string. If specified, only return the
                         count of primes >= PMIN and <= PMAX. Defaults to
                         return the series of prime values within the range.

                 "nth" - Optional. A string. If specified, only return the
                         nth prime <= PMAX. The value of PMIN is ignored.
                         Defaults to return the series of prime values
                         within the range.

              "silent" - Optional. A string. If specified, operate without
                         status messages. Defaults to "verbose", show
                         status messages.

    Returns: A series, the prime values less than or equal to N or
             PMIN <= primes <= PMAX.

             If "count" or "nth" is specifed, a single integer is returned.

    Example:
             W1: primes(10)

             W2 contains the series {2, 3, 5, 7}.

    Example:
             primes(10, "count")

             returns 4 indicating there are 4 prime values less than or equal
             to 10.

    Example:
             primes(4, "nth")

             returns 7, the 4th prime.

    Example:
             W1: primes(10)
             W2: isprime(W1)

             W2 contains the series {1, 1, 1, 1}, indicating that all
             the values of W1 are prime.

    Example:
             W1: primes(10, 20)

             W1 contains the series {11, 13, 17, 19}, the primes values
             between 10 and 20.

    Example:
             primes(10, 20, "count")

             returns 4, indicating there are 4 prime values between 10 and 20.

    Remarks:
             A prime number is a natural number (positive integer) with 
             exactly two divisors, 1 and itself. Thus, 0 and 1 are not
             prime.

             PRIMES uses a segmented sieve of Eratosthenes algorithm with
             wheel factorization written by Kim Walisch licensed under the
             MIT license.

    See Also:
             Isprime
             Factors
#endif


/* generate prime numbers <= n */
primes(argv)
{
        local pmin, pmax, opt1, opt2;

        /* parse args */
        (pmin, pmax, opt1, opt2) = primes_parse_args(argv);

        /* fast prime number generator */
        p = primesieve(pmin, pmax, opt1, opt2);
                
        return(p);
}


/* parse input args */
primes_parse_args(argv)
{
        local j, pmin, pmax, str1, str2;

        pmin = pmax = str1 = str2 = {};

        loop (j = 1..argc)
        {
                if (isscalar(getargv(j)))
                {
                        if (isempty(pmax))
                        {
                                pmax = getargv(j);
                        }
                        else if (isempty(pmin))
                        {
                                pmin = pmax;
                                pmax = getargv(j);
                        }
                        else
                        {
                                error(sprintf("%s - only minimum and/or maximum prime value accepted", __CALLER__));
                        }
                }
                else if (isstring(getargv(j)))
                {
                        if (isempty(str1))
                        {
                                str1 = getargv(j);
                        }
                        else if (isempty(str2))
                        {
                                str2 = getargv(j);
                        }
                        else
                        {
                                error(sprintf("%s - too many string options", __CALLER__));
                        }
                }
                else
                {
                        error(sprintf("%s - input must be an integer or a string", __CALLER__));
                }
        }

        if (isempty(pmin))
        {
                pmin = 2;
        }

        if (isempty(pmax))
        {
                error(sprintf("%s - maximum prime value required", __CALLER__));
        }

        if (isempty(str1))
        {
                str1 = "";
        }

        if (isempty(str2))
        {
                str2 = "";
        }

        return(pmin, pmax, str1, str2);
}