Skip to content

Instantly share code, notes, and snippets.

@andrewgho
Last active August 29, 2015 13:56
Show Gist options
  • Save andrewgho/9147062 to your computer and use it in GitHub Desktop.
Save andrewgho/9147062 to your computer and use it in GitHub Desktop.
is_steal_count.sh - return true for GrabScrab steal (via letter counting)
#!/bin/sh
# is_steal_count.sh - return true for GrabScrab steal (via letter counting)
# Andrew Ho (andrew@zeuscat.com)
#
# Given two words, exits with zero return status if the second word is a
# GrabScrab steal for the first (see <http://grabscrab.com>).
#
# This solution counts letters and compares the letter counts, with best
# case linear performance, by total letter count.
ME=`basename "$0"`
USAGE="usage: $ME base steal"
# Main loop, run at end
main() {
# Check for valid inputs
[ $# -ge 2 ] || usage 'both base and steal word inputs are required'
base=`normalize "$1"`
[ -n "$base" ] || die 'base word must have at least one English letter'
steal=`normalize "$2"`
[ -n "$steal" ] || die 'steal word must have at least one English letter'
# Shell does not offer dictionary structure, so use eval to simulate it
for letter in `splitletters ABCDEFGHIJKLMNOPQRSTUVWXYZ`; do
eval "count_$letter=0"
done
# Increment letter count for letters in steal word
steallen=0
for letter in `splitletters "$steal"`; do
eval "count_$letter=\`expr \"\$count_$letter\" + 1\`"
steallen=`expr "$steallen" + 1`
done
# Decrement letter count for letters in base word, exit false if not found
baselen=0
for letter in `splitletters "$base"`; do
eval "count=\"\$count_$letter\""
[ "$count" -eq 0 ] && return 1
eval "count_$letter=\`expr \"\$count_$letter\" - 1\`"
baselen=`expr "$baselen" + 1`
done
# All letters in base found; return true as long as steal is longer
[ "$baselen" -lt "$steallen" ]
}
# Print error message and usage to stderr, exit with non-zero return status
usage() { echo "$ME: $@" 1>&2; echo "$USAGE" 1>&2; exit 1; }
# Print error message to stderr, exit with non-zero return status
die() { echo "$ME: $@" 1>&2; exit 1; }
# Given a string, output it with only uppercase English letters
normalize() { echo "$1" | tr a-z A-Z | sed 's/[^A-Z]//g'; }
# Given a string, split it into letters
splitletters() { echo "$1" | fold -w1; }
# Run main loop
main $@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment