How to resolve the algorithm Sieve of Eratosthenes step by step in the UNIX Shell programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Sieve of Eratosthenes step by step in the UNIX Shell programming language

Table of Contents

Problem Statement

The Sieve of Eratosthenes is a simple algorithm that finds the prime numbers up to a given integer.

Implement the   Sieve of Eratosthenes   algorithm, with the only allowed optimization that the outer loop can stop at the square root of the limit, and the inner loop may start at the square of the prime just found. That means especially that you shouldn't optimize by using pre-computed wheels, i.e. don't assume you need only to cross out odd numbers (wheel based on 2), numbers equal to 1 or 5 modulo 6 (wheel based on 2 and 3), or similar wheels based on low primes. If there's an easy way to add such a wheel based optimization, implement it as an alternative version.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Sieve of Eratosthenes step by step in the UNIX Shell programming language

Source code in the unix programming language

function primes {
  typeset -a a
  typeset i j
  a[1]=""
  for (( i = 2; i <= $1; i++ )); do
    a[$i]=$i
  done
  for (( i = 2; i * i <= $1; i++ )); do
    if [[ ! -z ${a[$i]} ]]; then
      for (( j = i * i; j <= $1; j += i )); do
        a[$j]=""
      done
    fi
  done
  printf '%s' "${a[2]}"
  printf ' %s' ${a[*]:3}
  printf '\n'
}

primes 1000

#! /bin/sh

LIMIT=1000

# As a workaround for missing arrays, we use variables p2, p3, ...,
# p$LIMIT, to represent the primes. Values are true or false.
#   eval p$i=true     # Set value.
#   eval \$p$i        # Run command: true or false.
#
# A previous version of this script created a temporary directory and
# used files named 2, 3, ..., $LIMIT to represent the primes. We now use
# variables so that a killed script does not leave extra files. About
# performance, variables are about as slow as files.

i=2
while [ $i -le $LIMIT ]
do
    eval p$i=true               # was touch $i
    i=`expr $i + 1`
done

i=2
while
    j=`expr $i '*' $i`
    [ $j -le $LIMIT ]
do
    if eval \$p$i               # was if [ -f $i ]
    then
        while [ $j -le $LIMIT ]
        do
            eval p$j=false      # was rm -f $j
            j=`expr $j + $i`
        done
    fi
    i=`expr $i + 1`
done

# was echo `ls|sort -n`
echo `i=2
      while [ $i -le $LIMIT ]; do
          eval \\$p$i && echo $i
          i=\`expr $i + 1\`
      done`

sourc() {
    seq 2 1000
}

cull() {
    while
        read p || exit
    do
        (($p % $1 != 0)) && echo $p
    done
}

sink() {
    read p || exit
    echo $p
    cull $p | sink &
}

sourc | sink

# Fill $1 characters with $2.
fill () {
	# This pipeline would begin
	#   head -c $1 /dev/zero | ...
	# but some systems have no head -c. Use dd.
	dd if=/dev/zero bs=$1 count=1 2>/dev/null | tr '\0' $2
}

filter () {
	# Use sed to put an 'x' after each multiple of $1, remove
	# first 'x', and mark non-primes with '0'.
	sed -e s/$2/\&x/g -e s/x// -e s/.x/0/g | {
		if expr $1 '*' $1 '<' $3 > /dev/null; then
			filter `expr $1 + 1` .$2 $3
		else
			cat
		fi
	}
}

# Generate a sequence of 1s and 0s indicating primality.
oz () {
	fill $1 1 | sed s/1/0/ | filter 2 .. $1
}

# Echo prime numbers from 2 to $1.
prime () {
	# Escape backslash inside backquotes. sed sees one backslash.
	echo `oz $1 | sed 's/./&\\
/g' | grep -n 1 | sed s/:1//`
}

prime 1000

# Sieve of Eratosthenes: Echoes all prime numbers through $limit.
@ limit = 80

if ( ( $limit * $limit ) / $limit != $limit ) then
	echo limit is too large, would cause integer overflow.
	exit 1
endif

# Use $prime[2], $prime[3], ..., $prime[$limit] as array of booleans.
# Initialize values to 1 => yes it is prime.
set prime=( `repeat $limit echo 1` )

# Find and echo prime numbers.
@ i = 2
while ( $i <= $limit )
	if ( $prime[$i] ) then
		echo $i

		# For each multiple of i, set 0 => no it is not prime.
		# Optimization: start at i squared.
		@ m = $i * $i
		while ( $m <= $limit )
			set prime[$m] = 0
			@ m += $i
		end
	endif
	@ i += 1
end

  

You may also check:How to resolve the algorithm Pascal's triangle step by step in the F# programming language
You may also check:How to resolve the algorithm Random numbers step by step in the ALGOL 68 programming language
You may also check:How to resolve the algorithm Loops/For step by step in the Octave programming language
You may also check:How to resolve the algorithm Floyd's triangle step by step in the Bracmat programming language
You may also check:How to resolve the algorithm UTF-8 encode and decode step by step in the Go programming language