#! /bin/bash -

# H.A.Trujillo
# 14 Jan 21
# Last Change:     30 Jan 2021

#  Produces anagrams of the input word:
#  	ana mast -> mast, mats, tams
#
#  Caveats:	- gets confused by capital letters
#		- doesn't produce cities, proper nouns, etc
#		- pretty slow for words >8 letters long
#		- doesn't run in Bash v3


# help blurb
if [ "$1" == "-h" ] ; then
    sed -n '7,13s/#//p ; 13q' $0
    exit
fi

# Check bash version
if  [ ${BASH_VERSION%%.*} -lt 4 ] ; then
    echo "    $(basename $0) requires bash ≥ v4  --  Exiting"
    exit 1
fi

function Swap()
{ 	# usage: Swap i j
	#  - swaps items i and j of input array, to generate output array 
	#  - prints output array w/ last 3 letters permuted

    out=(${in[@]})
    out[$1]=${in[$2]}
    out[$2]=${in[$1]}

    # Rotate last three letters manually to save a bunch of cycles.
    echo ${out[@]} #							  xyz
    echo ${out[@]:0:$y}   		 ${out[@]:$z:1} ${out[@]:$y:1}	# xzy 
    echo ${out[@]:0:$x}   ${out[@]:$y:1} ${out[@]:$x:1} ${out[@]:$z:1}	# yxz
    echo ${out[@]:0:$x}   ${out[@]:$y:2} 		${out[@]:$x:1}	# yzx
    echo ${out[@]:0:$x}   ${out[@]:$z:1} ${out[@]:$x:2}			# zxy
    echo ${out[@]:0:$x}   ${out[@]:$z:1} ${out[@]:$y:1} ${out[@]:$x:1}	# zyx
}

function DoSwap()
{	# usage: DoSwap p inArray outArray
	# - sets up looping for Swap, looping from position "p" to $imax

    declare -n in=$2		# eg: Array0
    declare -n out=$3		# eg: Array1
    local depth=$((depth+1))

    local i=$1
    until [ $i == $imax ] ; do
	local j=$((i+1))
	until [ $j == $jmax ] ; do
	    Swap $i $j
	    DoSwap $((i+1))  Array$((depth+1))  Array$((depth+2))
	    local j=$((j+1))
	done
	local i=$((i+1))
    done
}

#------------------ Start Here ----------------


# create array from input word
word=$1 	
if [ ${#word} -gt 8 ] ; then echo "this will take a minute..." ; fi
n=0
while [ $n != ${#word} ] ; do
    Array0[$n]=${word:n:1}
    let n++
done

# set up stop-limits, printing subscripts, and array-counter
imax=$((${#word}-3))
jmax=${#word}
x=$((${#word}-3))
y=$((${#word}-2))
z=$((${#word}-1))
depth=-1

# finally, do it!
{ 	# the unswapped case
  echo ${Array0[@]} #						  		  xyz
  echo ${Array0[@]:0:$y}   ${Array0[@]:$z:1} ${Array0[@]:$y:1} #		  xzy 
  echo ${Array0[@]:0:$x}   ${Array0[@]:$y:1} ${Array0[@]:$x:1} ${Array0[@]:$z:1} #yxz
  echo ${Array0[@]:0:$x}   ${Array0[@]:$y:2} 		       ${Array0[@]:$x:1} #yzx
  echo ${Array0[@]:0:$x}   ${Array0[@]:$z:1} ${Array0[@]:$x:2} #		  zxy
  echo ${Array0[@]:0:$x}   ${Array0[@]:$z:1} ${Array0[@]:$y:1} ${Array0[@]:$x:1} #zyx

  	# and now the swapping cascade
  DoSwap 0 Array0 Array1
}  | sed 's/ //g' | hunspell -G | sort | uniq

exit

