Bash Century From Year
century_from_year() {
local _year=$1
echo $(( (_year + 99) / 100 ))
}
This converts a year into its century. Years 1-100 are century 1, 101-200 are century 2, and so on.
Bash Check Palindrome
check_palindrome() {
local _s=$1
local _rev=""
local _i
for ((_i = ${#_s} - 1; _i >= 0; _i--)); do
_rev="${_rev}${_s:_i:1}"
done
if [[ "$_rev" == "$_s" ]]; then echo true; else echo false; fi
}
This compares the string with its reverse. If they match, it is a palindrome.
Bash Chocolates By Numbers
gcd() {
local _n=$1 _m=$2
if (( _n % _m == 0 )); then
echo "$_m"
return
fi
gcd "$_m" $(( _n % _m ))
}
chocolates_by_numbers() {
local _n=$1 _m=$2
local _g
_g=$(gcd "$_n" "$_m")
echo $(( (_n * _m / _g) / _m ))
}
This uses the greatest common divisor to figure out how many chocolates get eaten before the pattern repeats.
Bash Common Prime Divisors
gcd() {
local _n=$1 _m=$2
if (( _n % _m == 0 )); then
echo "$_m"
return
fi
gcd "$_m" $(( _n % _m ))
}
remove_common_prime_divisors() {
local _n=$1 _m=$2 _d
while (( _n != 1 )); do
_d=$(gcd "$_n" "$_m")
if (( _d == 1 )); then
break
fi
_n=$(( _n / _d ))
done
echo "$_n"
}
common_prime_divisors() {
local -n _arrA="$1"
local -n _arrB="$2"
local _counter=0 _i _x _y _d _rx _ry
for _i in "${!_arrA[@]}"; do
_x=${_arrA[$_i]}
_y=${_arrB[$_i]}
_d=$(gcd "$_x" "$_y")
_rx=$(remove_common_prime_divisors "$_x" "$_d")
if (( _rx != 1 )); then
continue
fi
_ry=$(remove_common_prime_divisors "$_y" "$_d")
if (( _ry == 1 )); then
((_counter++))
fi
done
echo "$_counter"
}
This checks whether two numbers are built from the same prime factors by repeatedly dividing out their shared parts.
Bash Count Div
count_div() {
local _a=$1 _b=$2 _k=$3
local _firstDiv
if (( _a % _k == 0 )); then _firstDiv=$_a; else _firstDiv=$(( _a + (_k - _a % _k) )); fi
local _lastDiv=$(( _b - _b % _k ))
echo $(( (_lastDiv - _firstDiv) / _k + 1 ))
}
This counts how many numbers in a range are divisible by K without looping through every value.
Bash Count Factors
count_factors() {
local _n=$1
local _count=0 _i=1
while (( _i * _i < _n )); do
if (( _n % _i == 0 )); then
_count=$(( _count + 2 ))
fi
((_i++))
done
if (( _i * _i == _n )); then
((_count++))
fi
echo "$_count"
}
This checks divisors in pairs up to the square root, which keeps the work much smaller than testing every number.
Bash Count Non Divisible
count_non_divisible() {
local -n _a="$1"
local -n _out="$2"
local _size=${#_a[@]}
local _maxv=${_a[0]} _v
for _v in "${_a[@]}"; do (( _v > _maxv )) && _maxv=$_v; done
local -a _occ
for ((_v = 0; _v <= _maxv; _v++)); do _occ[_v]=0; done
for _v in "${_a[@]}"; do _occ[_v]=$(( _occ[_v] + 1 )); done
_out=()
local _k
for _k in "${!_a[@]}"; do
_v=${_a[$_k]}
local _count=0 _i=1
while (( _i * _i <= _v )); do
if (( _v % _i == 0 )); then
_count=$(( _count + _occ[_i] ))
if (( _v / _i != _i )); then
_count=$(( _count + _occ[_v/_i] ))
fi
fi
((_i++))
done
_out[_k]=$(( _size - _count ))
done
}
This counts how often each value appears, then subtracts the divisor matches so you get the non-divisible count for each item.
Bash Count Semi Primes
count_semi_primes() {
local _n=$1
local -n _pArr="$2"
local -n _qArr="$3"
local -n _outArr="$4"
local -a _is_prime _semi _cum
local _i _k _idx
for ((_i = 0; _i <= _n; _i++)); do _is_prime[_i]=1; _semi[_i]=0; done
for ((_i = 2; _i * _i <= _n; _i++)); do
if (( _is_prime[_i] )); then
for ((_k = _i * _i; _k <= _n; _k += _i)); do
_is_prime[_k]=0
done
fi
done
for ((_k = 2; _k * _k <= _n; _k++)); do
if (( _is_prime[_k] )); then
for ((_i = 2; _i * _k <= _n; _i++)); do
if (( _is_prime[_i] )); then
_semi[_k * _i]=1
fi
done
fi
done
_cum[0]=${_semi[0]}
for ((_i = 1; _i <= _n; _i++)); do
_cum[_i]=$(( _cum[_i-1] + _semi[_i] ))
done
_outArr=()
for _idx in "${!_pArr[@]}"; do
local _lo=${_pArr[$_idx]}
local _hi=${_qArr[$_idx]}
_outArr[_idx]=$(( _cum[_hi] - _cum[_lo-1] ))
done
}
This precomputes semiprimes and prefix sums so each range query becomes a quick subtraction.
Bash Cyclic Rotation
cyclic_rotation() {
local -n _a="$1"
local -n _out="$2"
local _k=$3
local _size=${#_a[@]}
if (( _size == 0 )); then
_out=()
return
fi
_k=$(( _k % _size ))
_out=()
local _i
for ((_i = 0; _i < _size; _i++)); do
_out[(_i + _k) % _size]=${_a[_i]}
done
}
This rotates the array to the right by K steps and keeps the wrap-around values in the correct order.
Bash Distinct
distinct() {
local -n _a="$1"
local -A _seen
local _v
for _v in "${_a[@]}"; do _seen[$_v]=1; done
echo "${#_seen[@]}"
}
This counts unique values by tracking what has already been seen.