word jumble solver

i have tried writing a script that takes a jumbled word that the user inputs and spits out the word unjumbled. Unfortunately my efforts have failed dismally.
Here is what I have:

set found to false
repeat until found is true
	set j_word to text returned of (display dialog "Enter the jumbled word" default answer "")
	set j_letters to text items of j_word as Unicode text
	set nchex to (do shell script "cat /usr/share/dict/words | grep -i -x \"" & j_letters & "\"")
	set theresult to nchex's words
	repeat with i from 1 to j_letters
		if item i of j_letters = theresult then
			display dialog theresult
			set found to true
		else
			display dialog "No dice"
		end if
	end repeat
end repeat

but it didn’t work at all :confused:

Any idea on how to do this properly?

I remember this problem from way back, sorry I don’t have my original code. I created the program to beat my wife with the Sunday morning scramble - mean huh? ; ) .

You’ll need to create a hash dictionary.

  1. ask the user for a dictionary.
  2. create a hash dictionary from #1.
    This basically sorts the letters alphabetically for each word. (aemt = mate;team;meat etc.) So you get all words that may possibly work.
  3. Perform lookup on the hash table.
    I vaguely remember that double letters are omitted so I think you have to do a string length check as well somewhere in the process.

You’ll only need to create the hash dictionary once. Once this is done- lookups are FAST! Of course it’s totally dependent on the dictionary, so use a dictionary that has 80K+ words. You can of course use other language dictionaries too and scrabble in French or German etc. (watch the diacritical marks though).
.
Google “scrabble hash table” should give you a start…

i was actuallly trying to base it ff of a hangman solver that someone made a while back which looked like this:

set que to missing value
repeat until (que is false)
	set str to text returned of (display dialog "Enter string." & return & return & "Use underscores ( _ ) for unknown characters." default answer "h_ngm_n")
	
	set astid to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "_"
	set knownBits to str's text items
	set AppleScript's text item delimiters to ""
	set knownChrs to characters of (knownBits as Unicode text)
	set AppleScript's text item delimiters to ","
	set AppleScript's text item delimiters to ("[^" as Unicode text) & knownChrs & "]"
	set nstr to knownBits as Unicode text
	set astid to AppleScript's text item delimiters
	
	try
		set nchex to (do shell script "cat /usr/share/dict/words | grep -i -x \"" & nstr & "\"")
		set nstr to nchex's words
	end try
	if (nstr contains "[") then
		display alert "Error - there are no possible answers." message "Check for typos and try again?" buttons {"Cancel", "Try Again"} cancel button 1 default button 2
	else
		set que to (choose from list nstr with title "Hang Man:" with prompt "Possible Answers" OK button name "Next Word" cancel button name "Done" with empty selection allowed)
	end if
end repeat

I’m sure there is a simpler way

That looks pointless.

I’m not sure how you would programatically determine the possible combinations (that should be the hardest part, though).

Try something like this:

on anagrammatize(someText, dictionaryPath)
	if length of someText is 1 then return someText
	
	-- This subroutine must be able to find its dictionary
	if dictionaryPath is "" then
		set dictionaryPath to path to me as Unicode text
		
		set prevTIDs to text item delimiters of AppleScript
		set text item delimiters of AppleScript to ":"
		try
			tell dictionaryPath to ¬
				set dictionaryPath to text 1 thru text item (((last character is not ":") as integer) - 3) & ":"
			
		end try
		set text item delimiters of AppleScript to prevTIDs
		
		set dictionaryPath to POSIX path of (dictionaryPath & "anagrammatize.txt")
	end if
	
	set signature to {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	
	repeat with thisChar in characters of someText
		set i to ASCII number thisChar
		
		-- Handle uppercase letters [A-Z] as lowercase
		if i ≥ 65 and i ≤ 90 then set i to i + 32
		
		-- Only lowercase letters are handled [a-z]
		if i ≥ 97 and i ≤ 122 then
			set i to i - 96
			set item i of signature to (item i of signature) + 1
		end if
	end repeat
	
	set prevTIDs to text item delimiters of AppleScript
	set text item delimiters of AppleScript to ""
	set signature to "" & signature
	set text item delimiters of AppleScript to prevTIDs
	
	do shell script "/usr/bin/grep " & quoted form of ("^" & signature) & " " & quoted form of dictionaryPath & " | /usr/bin/cut -f 2 | /usr/bin/grep --invert-match " & quoted form of ("^" & someText & "$")
	return paragraphs of result
end anagrammatize

anagrammatize("manice", "")
--> {"anemic", "cinema", "iceman"}

You’ll need to download the dictionary (based off of /usr/share/dict/words on Leopard), and possibly provide a path to it when you call the subroutine.

Thanks goes to the appropriate people on the python mailing list.

that worked great: doesnt have every word in say a real paperback dictionary but oh well :stuck_out_tongue:

actually sometimes you just have to omit the “s” to make it work :smiley:

I’m trying to get this so when it finds the word(s) it displays each option in a list and has a next word button and done button but when it finds a word and you click cancel or next word it just executes the error handler I put in…

property thewords : missing value
on anagrammatize(someText, dictionaryPath)
	if length of someText is 1 then return someText
	
	-- This subroutine must be able to find its dictionary
	if dictionaryPath is "" then
		set dictionaryPath to path to me as Unicode text
		
		set prevTIDs to text item delimiters of AppleScript
		set text item delimiters of AppleScript to ":"
		try
			tell dictionaryPath to ¬
				set dictionaryPath to text 1 thru text item (((last character is not ":") as integer) - 3) & ":"
			
		end try
		set text item delimiters of AppleScript to prevTIDs
		
		set dictionaryPath to POSIX path of (dictionaryPath & "anagrammatize.txt")
	end if
	
	set signature to {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	
	repeat with thisChar in characters of someText
		set i to ASCII number thisChar
		
		-- Handle uppercase letters [A-Z] as lowercase
		if i ≥ 65 and i ≤ 90 then set i to i + 32
		
		-- Only lowercase letters are handled [a-z]
		if i ≥ 97 and i ≤ 122 then
			set i to i - 96
			set item i of signature to (item i of signature) + 1
		end if
	end repeat
	
	set prevTIDs to text item delimiters of AppleScript
	set text item delimiters of AppleScript to ""
	set signature to "" & signature
	set text item delimiters of AppleScript to prevTIDs
	
	do shell script "/usr/bin/grep " & quoted form of ("^" & signature) & " " & quoted form of dictionaryPath & " | /usr/bin/cut -f 2 | /usr/bin/grep --invert-match " & quoted form of ("^" & someText & "$")
	set thewords to paragraphs of result
end anagrammatize
--set choice to missing value
set theword to text returned of (display dialog "Please enter your jumbled word" default answer "") as string
repeat until (thewords is false)
	try
		anagrammatize(theword, "")
		
		choose from list thewords with title "Word Unjumbler:" with prompt "Possible Answers" OK button name "Next Word" cancel button name "Done" with empty selection allowed
		set theword to ""
	on error
		display dialog "Sorry. No results found."
		set theword to text returned of (display dialog "Please enter your jumbled word" default answer "") as string
		anagrammatize(theword, "")
	end try
	
end repeat

Side note: I’ve heard that some kind of cute animal dies every time someone uses a useless as string coercion.

goodbye fluffy :frowning:

still, that won’t really solve my problem i don’t think will it?

That’s all I had time for earlier. :stuck_out_tongue:

Those are the only times where I see thewords defined…

Try something like this:

repeat
	try
		display dialog "" default answer ""
		anagrammatize(text returned of result, "")
		
		choose from list result with empty selection allowed
		if result is false then error number -128 -- cancel
	on error errMsg number errNum
		if errNum is -128 then error number -128
		
		-- Assume the final grep in `anagrammatize` didn't have any matches.
		display dialog "Sorry, no results were found."
	end try
end repeat

awesome, works great :smiley: