Last active
December 6, 2023 23:57
-
-
Save lovasoa/55550cb561110300ad97398d2cf93214 to your computer and use it in GitHub Desktop.
Generic dichotomic search as a shell script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Dichotomic search in bash | |
# This is a bash-specific function that uses bash features. | |
# This is not guaranteed to work in other shells. | |
# | |
# Usage: | |
# source dichotomic-bash.sh | |
# result=$(dichotomic_search min max command) | |
# | |
# Returns the largest i for which `command i` succeeds (exits with a null exit code) | |
# This supposes that there is an i such that : | |
# forall min <= n <= i, `command n` succeeds, | |
# and forall i < n <= max, `command n` fails | |
# | |
# This script is public domain | |
function dichotomic_search { | |
min=$1 | |
max=$2 | |
command=$3 | |
while (( $min < $max )); do | |
# Compute the mean between min and max, rounded up to the superior unit | |
current=$(( (min + max + 1 ) / 2 )) | |
if $command $current | |
then min=$current | |
else max=$((current - 1)) | |
fi | |
done | |
echo $min | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Dichotomic search in shell | |
# Usage: dichotomic.sh min max command | |
# Returns the largest i for which `command i` succeeds (exits with a null exit code) | |
# This supposes that there is an i such that : | |
# forall min <= n <= i, `command n` succeeds, | |
# and forall i < n <= max, `command n` fails | |
# This script works in any shell (not just bash) and is public domain | |
if [ "$#" -ne 3 ]; then | |
echo "$0: invalid number of parameters. | |
Usage: $0 min max command" >&2 | |
exit 1 | |
fi | |
min=$1 | |
max=$2 | |
command=$3 | |
while [ $min -lt $max ]; do | |
# Compute the mean between min and max, rounded up to the superior unit | |
current=`expr '(' "$min" + "$max" + 1 ')' / 2` | |
if $command $current | |
then min=$current | |
else max=`expr $current - 1` | |
fi | |
done | |
echo $min |
Thank you very much for the script, but [[ $min < $max ]]
will not work correctly in bash, it should be changed to [[ $min -lt $max ]]
just like in the POSIX version (Changing [
to [[
doesn't magically change <
from string comparison to integer comparison). Or use (( $min < $max ))
instead.
@William8915 : you are right, thanks ! I changed it
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yo this is super sexy. thanks