LDP/LDP/guide/docbook/abs-guide/ex68.sh

135 lines
2.2 KiB
Bash
Raw Permalink Normal View History

2001-07-10 14:25:50 +00:00
#!/bin/bash
2005-02-09 20:53:43 +00:00
# sieve.sh (ex68.sh)
2001-09-04 13:27:31 +00:00
2002-06-17 13:17:07 +00:00
# Sieve of Eratosthenes
2001-07-10 14:25:50 +00:00
# Ancient algorithm for finding prime numbers.
2005-02-09 20:53:43 +00:00
# This runs a couple of orders of magnitude slower
#+ than the equivalent program written in C.
2001-07-10 14:25:50 +00:00
2001-09-04 13:27:31 +00:00
LOWER_LIMIT=1 # Starting with 1.
UPPER_LIMIT=1000 # Up to 1000.
2005-03-21 13:51:11 +00:00
# (You may set this higher . . . if you have time on your hands.)
2001-07-10 14:25:50 +00:00
PRIME=1
NON_PRIME=0
let SPLIT=UPPER_LIMIT/2
# Optimization:
2008-11-23 22:43:47 +00:00
# Need to test numbers only halfway to upper limit. Why?
2001-07-10 14:25:50 +00:00
declare -a Primes
# Primes[] is an array.
initialize ()
{
# Initialize the array.
i=$LOWER_LIMIT
until [ "$i" -gt "$UPPER_LIMIT" ]
do
Primes[i]=$PRIME
let "i += 1"
done
2005-02-09 20:53:43 +00:00
# Assume all array members guilty (prime)
#+ until proven innocent.
2001-07-10 14:25:50 +00:00
}
print_primes ()
{
2001-09-04 13:27:31 +00:00
# Print out the members of the Primes[] array tagged as prime.
2001-07-10 14:25:50 +00:00
i=$LOWER_LIMIT
until [ "$i" -gt "$UPPER_LIMIT" ]
do
if [ "${Primes[i]}" -eq "$PRIME" ]
then
printf "%8d" $i
2001-09-04 13:27:31 +00:00
# 8 spaces per number gives nice, even columns.
2001-07-10 14:25:50 +00:00
fi
let "i += 1"
done
}
2001-09-04 13:27:31 +00:00
sift () # Sift out the non-primes.
2001-07-10 14:25:50 +00:00
{
let i=$LOWER_LIMIT+1
2009-09-29 15:08:03 +00:00
# Let's start with 2.
2001-07-10 14:25:50 +00:00
until [ "$i" -gt "$UPPER_LIMIT" ]
do
if [ "${Primes[i]}" -eq "$PRIME" ]
2001-09-04 13:27:31 +00:00
# Don't bother sieving numbers already sieved (tagged as non-prime).
2001-07-10 14:25:50 +00:00
then
t=$i
while [ "$t" -le "$UPPER_LIMIT" ]
do
let "t += $i "
Primes[t]=$NON_PRIME
2001-09-04 13:27:31 +00:00
# Tag as non-prime all multiples.
2001-07-10 14:25:50 +00:00
done
fi
let "i += 1"
done
}
2005-02-09 20:53:43 +00:00
# ==============================================
# main ()
2001-07-10 14:25:50 +00:00
# Invoke the functions sequentially.
initialize
sift
print_primes
# This is what they call structured programming.
2005-02-09 20:53:43 +00:00
# ==============================================
2001-07-10 14:25:50 +00:00
2001-09-04 13:27:31 +00:00
echo
2001-07-10 14:25:50 +00:00
exit 0
2005-03-21 13:51:11 +00:00
# -------------------------------------------------------- #
# Code below line will not execute, because of 'exit.'
2001-07-10 14:25:50 +00:00
2005-02-09 20:53:43 +00:00
# This improved version of the Sieve, by Stephane Chazelas,
#+ executes somewhat faster.
2001-07-10 14:25:50 +00:00
# Must invoke with command-line argument (limit of primes).
2008-11-23 22:43:47 +00:00
UPPER_LIMIT=$1 # From command-line.
2001-09-04 13:27:31 +00:00
let SPLIT=UPPER_LIMIT/2 # Halfway to max number.
2001-07-10 14:25:50 +00:00
Primes=( '' $(seq $UPPER_LIMIT) )
i=1
until (( ( i += 1 ) > SPLIT )) # Need check only halfway.
do
2012-04-04 22:51:18 +00:00
if [[ -n ${Primes[i]} ]]
2001-07-10 14:25:50 +00:00
then
t=$i
until (( ( t += i ) > UPPER_LIMIT ))
do
Primes[t]=
done
fi
done
echo ${Primes[*]}
2001-09-04 13:27:31 +00:00
2007-11-08 15:52:23 +00:00
exit $?