#!/usr/bin/env bash array.min2() { (( $1 < $2 )) && echo "$1" && return echo "$2" } _int.insertion_sort() { local -n _int_isort_arr="$1" local _int_isort_left="$2" _int_isort_right="$3" local i=0 j=0 for (( i=_int_isort_left+1; i<=_int_isort_right; i+=1 )) do local value="${_int_isort_arr["$i"]}" j=$((i-1)) while (( j>=_int_isort_left && _int_isort_arr[j] > value )); do _int_isort_arr[j+1]="${_int_isort_arr["$j"]}" ((j-=1)) done _int_isort_arr[j+1]="$value" done } _int.merge() { local -n _int_merge_arr="$1" local l="$2" m="$3" r="$4" _int_merge_left=() _int_merge_right=() local _int_merge_left_len=$((m-l+1)) _int_merge_right_len=$((r-m)) for (( i=0; i < _int_merge_left_len; i+=1 )); do _int_merge_left[i]="${_int_merge_arr[$((l+i))]}" done for (( i=0; i < _int_merge_right_len; i+=1 )); do _int_merge_right[i]="${_int_merge_arr[$((m+1+i))]}" done local i=0 j=0 k="$l" while (( i < _int_merge_left_len && j < _int_merge_right_len )); do if (( _int_merge_left[i] <= _int_merge_right[j] )); then _int_merge_arr[k]="${_int_merge_left[$i]}" ((i+=1)) else _int_merge_arr[k]="${_int_merge_right[$j]}" ((j+=1)) fi ((k+=1)) done while (( i < _int_merge_left_len )); do _int_merge_arr[k]="${_int_merge_left[$i]}" ((k+=1)) ((i+=1)) done while (( j < _int_merge_right_len )); do _int_merge_arr[k]="${_int_merge_right[$j]}" ((k+=1)) ((j+=1)) done } _int.min_run() { local len="$1" r=0 while (( len >= 32 )); do r=$((r | (len & 1))) len=$((len >> 1)) done echo $((len + r)) } array.timsort() { local -n _array_timsort_arr="$1" local len="${#_array_timsort_arr[@]}" local min_run; min_run="$(_int.min_run "$len")" local i=0 j=0 size=0 _array_timsort_left=0 _int_timsort_mid=0 _array_timsort_right=0 for (( i=0; i < len; i+=min_run )); do _int.insertion_sort _array_timsort_arr "$i" "$(array.min2 "$((i+min_run-1))" "$((len-1))")" done for (( size=min_run; size < len; size*=2 )); do for (( _array_timsort_left=0; _array_timsort_left < len; _array_timsort_left+=2*size )); do _int_timsort_mid=$((_array_timsort_left+size-1)) _array_timsort_right=$(array.min2 "$((_array_timsort_left+2*size-1))" "$((len-1))") if (( _int_timsort_mid < _array_timsort_right )); then _int.merge _array_timsort_arr "$_array_timsort_left" "$_int_timsort_mid" "$_array_timsort_right" fi done done } array.insertion_sort() { local -n _array_isort_arr="$1" _int.insertion_sort _array_isort_arr 0 "$((${#_array_isort_arr[@]}-1))" } array.qsort() { read -ra arr <<< "$@" ((${#arr[@]} == 0)) && echo && return local smaller=() bigger=() pivot="${arr[0]}" res=() for i in "${arr[@]}"; do if ((i < pivot)); then smaller+=("$i") elif ((i > pivot)); then bigger+=("$i") fi done read -ra smaller_sorted <<< "$(array.qsort "${smaller[@]}")" read -ra bigger_sorted <<< "$(array.qsort "${bigger[@]}")" res=("${smaller_sorted[@]}" "$pivot" "${bigger_sorted[@]}") echo "${res[@]}" } array.sum() { local -n _array_sum_input="$1" local result=0 for i in "${_array_sum_input[@]}"; do ((result+=i)) done echo "$result" } array.from_bytes() { local input="$1" output=() while IFS= read -rd '' -n1 byte; do output+=("$byte") done <<< "$input" echo "${output[@]}" }