-
Notifications
You must be signed in to change notification settings - Fork 0
/
prime_numbers.sh
executable file
·125 lines (109 loc) · 3.48 KB
/
prime_numbers.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/bash
######################################################################
# Find prime numbers up to given script argument number with Sieve of
# Eratosthenes algorithm
#####################################################################
set -o nounset
set -o errexit
######################################################################
# Validate argument got with script invocation. Only one positive
# integer is allowed or one -h || --help string.
# Globals:
# none
# Arguments:
# $@ as all argument passed with script
# Outputs:
# return 1 || 0 depend on check's result
######################################################################
check_input() {
valid_number_arg='^[1-9]{1}[0-9]{0,9}$'
valid_help_arg='(^-h$)|(^--help$)'
if [[ $# -eq 1 ]] && [[ $1 =~ $valid_number_arg || $1 =~ $valid_help_arg ]]; then
return 0
fi
return 1
}
print_error() {
printf "%s\n" "Only one positive integer as upper limit of numbers is valid or -h or --help for help"
}
print_help() {
printf "%s\n%s\n%s\n"\
"Find prime numbers up to script's argument number"\
"Use $./prime_numbers.sh 123456 for normal use or enter arguments"\
"-h, --help to dispaly this help and exit."
}
######################################################################
# Dialog with user to inform him about potentially too much
# consumption of computing time of primes with upper limit more than
# 10000 and getting his accept of reject to procceed
######################################################################
too_long_dialog() {
local ans=''
echo "Upper limit is too high. Computing may take too much time."
while [[ !($ans =~ (^y$)|(^n$)) ]]; do
read -p "Do you want to proceed? Enter y/n: " ans
[[ !($ans =~ (^y$)|(^n$)) ]] && echo "Only 'y' or 'n' is acceptable"
done
if [[ $ans == "y" ]]; then
return 0
fi
return 1
}
######################################################################
# Get prime numbers up to limit got as script's argument using
# sieve of Eratosthenes algorithm.
# Globals:
# none
# Arguments:
# $1 as upper limit of natural numbrs row
# Output:
# Formatted output of prime numbers
######################################################################
get_primes() {
local -i upper_lim=$1
local -a natural_nums
local -i num_len=0
local -i counter=0
echo "Upper limit is $upper_lim"
# fill array with natural row numbers
for (( i=0; i<$((upper_lim-1)); i++ )); do
natural_nums[$i]=$((i+2))
done
# sieve mechanism
for (( i=0; i<$((upper_lim)); i++ )); do
if [[ natural_nums[$i] -ne 0 ]]; then
for (( j=$((i+natural_nums[$i])); j<$((upper_lim)); j+=natural_nums[$i] )); do
natural_nums[$j]=0
done
fi
done
# get length of last prime number
for (( i=$upper_lim; i>0; i-- )); do
if [[ natural_nums[$i] -ne 0 ]]; then
num_len=$((${#natural_nums[$i]}+1))
break
fi
done
echo $num_len
# formatted output of prime numbers
for (( i=0; i<$((upper_lim)); i++ )); do
if [[ natural_nums[i] -ne 0 ]]; then
counter=$((counter+1))
if [[ $((counter%20)) -eq 0 ]]; then
printf "%${num_len}s\n" "${natural_nums[$i]}"
else
printf "%${num_len}s" "${natural_nums[$i]}"
fi
fi
done
echo ""
}
main() {
check_input "$@" || { print_error; exit 1; }
[[ $1 -gt 10000 ]] && { too_long_dialog || { echo "OK, let's save your time"; exit 1; } }
case "$1" in
-h | --help ) print_help; exit 0;;
* ) get_primes $1;;
esac
}
main "$@"