Skip to content

Instantly share code, notes, and snippets.

@zambonin
Last active February 11, 2021 03:08
Show Gist options
  • Save zambonin/c4a426fd37ef49304b3c30b12bc4e31c to your computer and use it in GitHub Desktop.
Save zambonin/c4a426fd37ef49304b3c30b12bc4e31c to your computer and use it in GitHub Desktop.
Choose between 2^n choices with the help of a binary tree.
#!/usr/bin/env bash
# A shell script that helps a user to choose between 2^n possible choices by
# simulating a tournament through a perfect binary tree with randomly disposed
# nodes. It accepts input from /dev/stdin, i.e. through pipes or redirection.
#
# The power-of-2 input size restriction could be relaxed, but then choices
# would be probably less fair without repetitions of the classification process
# to make up for the generated tree prioritizing rightmost nodes.
CONTENTS="$(shuf < /dev/stdin)"
NUM_LINES="$(echo "$CONTENTS" | wc -l)"
NODES="$((NUM_LINES - 1))"
if ! (( NUM_LINES > 0 && (NUM_LINES & NODES) == 0 )) ; then
echo "Length of input must be a power of 2!"
exit 1
fi
ITERATIONS=0
while read -r OPT1 ; read -r OPT2 ; do
ITERATIONS="$((ITERATIONS + 1))"
ANSWER=0
until [ "$ANSWER" = "1" ] || [ "$ANSWER" = "2" ] ; do
printf "[%3d / %3d] " "$ITERATIONS" "$NODES"
read -p "Choose 1 ($OPT1) or 2 ($OPT2): " -r -N1 ANSWER < /dev/tty
[ "$ANSWER" = $'\n' ] && printf "\033[1A"
printf "\r\033[2K"
done
CHOICE="OPT$ANSWER"
echo "${!CHOICE}" > /dev/stdin
done <<< "$CONTENTS"
echo "Final choice is \"$OPT1\"!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment