Bash Peaks
peaks() {
local -n _arr="$1"
local _n=${#_arr[@]}
if (( _n <= 2 )); then
echo 0
return
fi
local -a _sum
for ((_i = 0; _i < _n; _i++)); do _sum[_i]=0; done
local _last=-1 _dist=0 _i
for ((_i = 1; _i + 1 < _n; _i++)); do
_sum[_i]=${_sum[_i-1]}
if (( _arr[_i] > _arr[_i-1] && _arr[_i] > _arr[_i+1] )); then
if (( _i - _last > _dist )); then _dist=$(( _i - _last )); fi
_last=$_i
(( _sum[_i]++ ))
fi
done
_sum[_n-1]=${_sum[_n-2]}
if (( _sum[_n-1] == 0 )); then
echo 0
return
fi
if (( _n - _last > _dist )); then _dist=$(( _n - _last )); fi
local _j
for ((_i = (_dist >> 1) + 1; _i < _dist; _i++)); do
if (( _n % _i == 0 )); then
_last=0
for ((_j = _i; _j <= _n; _j += _i)); do
if (( _sum[_j-1] <= _last )); then
break
fi
_last=${_sum[_j-1]}
done
if (( _j > _n )); then
echo $(( _n / _i ))
return
fi
fi
done
for ((_last = _dist; _n % _last != 0; )); do
((_last++))
done
echo $(( _n / _last ))
}
This finds the peak positions, then tests how many equal blocks can each contain at least one peak.