Sign in to follow this  
Followers 0
glasglow

Descramble Code

21 posts in this topic

They are working on Scrambling a word here:

http://www.autoitscript.com/forum/index.ph...Scramble+String

I am interested in descrambling a word but I don't even know where to start. I'm sure I would use a dictionary list so

FileReadLine()

But I need a string contains method like stringinstring contains "T" + "A" + "C" regardless of the order to get the word out of the dictionary file and match those words that have those letters only.

I tried with StringInStr() but I can only search from the right or left, not really a "ANY ORDER" Contains type of search.

I could do a StringRegExp something like this:

Value1 = t

Value2 = a

value3 = c

$list = StringRegExp (?:[$value1|$value2|$value3])

But I can't seem to get that working properly. Any advice would be appreciated.

Share this post


Link to post
Share on other sites



glasglow,

Here is an anagram solver that I wrote a very long time ago. It uses the Word spellchecker - so if you do not have Word installed it will not work. It is limited to 7 character anagrams in this version - this is a problem with Word, not the script. Why? Because all of the possible permutations are put into a Word document and spellchecked - if Word has too many errors (and of course most of the permutations are errors!) it crashes. I did produce a better version which does not have this limitation, but I want to leave you with something to do! :-)

#include <Array.au3>
#include <Word.au3>
#include <GuiListBox.au3>

Global $letters[1], $words[1], $index[1]
Global $oWordApp = _WordCreate("", 0, 0, 0)
Global $oDoc = $oWordApp.ActiveDocument
Global $oRange = $oDoc.Range
Global $begin
Global $Total

GUICreate("Anagrams", 200, 200)

$label1 = GUICtrlCreateLabel("Enter a word", 10,10,80,20)
$label2 = GUICtrlCreateLabel("7 chars",  95, 10, 40, 20)
$label3 = GUICtrlCreateLabel("maximum", 140, 10, 60, 20)

$inputbox = GUICtrlCreateInput("", 10, 40, 100, 20)
$button = GUICtrlCreateButton("Go", 150, 40, 40, 20)
$list = GUICtrlCreateList("", 10,70, 180, 80)
$progress = GUICtrlCreateProgress(10,160,180,20)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $button
            $input = GUICtrlRead($inputbox)
            $length = StringLen($input)
            If $input <> "" And $length < 8 Then ExitLoop
            GUICtrlSetData($inputbox, "")
    EndSwitch
WEnd

ReDim $letters[$length]
For $i = 0 To $length - 1
    $letters[$i] = StringMid($input, $i + 1, 1)
Next
GUICtrlSetData($label1, "Permuting")
GUICtrlSetData($label2, "")
GUICtrlSetData($label3, "")

$anag = _ExeterPermute($letters)

GUICtrlSetData($label1, "Spellchecking")
GUICtrlSetData($label3, "of " & $anag[0])

$oRange = $oWordApp.Activedocument.Range

For $i = 2 To $anag[0]
    GUICtrlSetData($label2, $i)
    GUICtrlSetData($progress, $i*100/$anag[0])
    
    $oRange.Delete
    $oRange.InsertAfter($anag[$i])
        
    $oSpellCollection = $oRange.SpellingErrors
    If $oSpellCollection.Count = 0 Then
        _GUICtrlListBox_AddString($list, $anag[$i])
    EndIf
Next

GUICtrlSetData($button, "Exit")

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Or $msg = $button Then _Exit()
WEnd

; ----------------------

Func _Exit()
    _WordQuit($oWordApp, 0)
    Exit
EndFunc

Func _ExeterPermute(ByRef $avArray, $sDelim = "")
    Local $i, $iSize = UBound($avArray), $iFactorial = 1, $aIdx[$iSize], $aResult[1], $iCount = 1
    
    If Not IsArray($avArray) Then
        Return SetError(1, 0, 0)
    EndIf
    
    For $i = 0 To $iSize - 1
        $aIdx[$i] = $i
    Next
    For $i = $iSize To 1 Step -1
        $iFactorial *= $i
    Next
    
    Global $Total = $iFactorial 
    
    ReDim $aResult[$iFactorial + 1]
    $aResult[0] = $iFactorial
    
    Global $begin = TimerInit()
    
    _ExeterInternal($avArray, 0, $iSize, $sDelim, $aIdx, $aResult, $iCount)
    Return $aResult
EndFunc

Func _ExeterInternal(ByRef $avArray, $iStart, $iSize, $sDelim, ByRef $aIdx, ByRef $aResult, ByRef $iCount)
    Local $i, $sTemp = "", $iTemp
    
    $now = TimerDiff($begin)
    GUICtrlSetData($progress, $now*400/$Total)
    
    If $iStart == $iSize - 1 Then
        For $i = 0 To $iSize - 1
            $aResult[$iCount] &= $avArray[$aIdx[$i]] & $sDelim
        Next
        If $sDelim <> "" Then $aResult[$iCount] = StringTrimRight($aResult[$iCount], 1)
        $iCount += 1
    Else
        For $i = $iStart To $iSize - 1
        
            $iTemp = $aIdx[$i]
            
            $aIdx[$i] = $aIdx[$iStart]
            $aIdx[$iStart] = $iTemp
            _ExeterInternal($avArray, $iStart + 1, $iSize, $sDelim, $aIdx, $aResult, $iCount)
            $aIdx[$iStart] = $aIdx[$i]
            $aIdx[$i] = $iTemp
        Next
    EndIf
EndFunc

The permutation method is open source. I found the AutoIt translation and the spell checking code somewhere on the forums, but I do not have record of the authors. If either or both of you read this - much of the credit goes to you!

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Hey why don't u do this:

#include<array.au3>
$string="laba"
$array=StringSplit($string,"")
_ArrayDisplay($array,"")

This will breakup the word into letters.. do the same for every word having the same no. of letters in the dictionary.. match the arrays.. if u get all matching elements.. that's ur word.. this is an idea.. tell me what u think.. i might help u do this.. as it was something that i wanted to do for some time now..


[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

something like this:

#include<array.au3>
$dic="ball"
$arraydic=StringSplit($dic,"")

$string="laba"
$array=StringSplit($string,"")
$count=0
For $i=1 To $array[0]
_ArraySearch($arraydic,$array[$i])

if Not @error Then 
    $count=$count+1
EndIf
Next
If $count=$array[0] Then 
    MsgBox(4096,"matched??","full match")
Else
    MsgBox(4096,"match??","not at all")
EndIf

[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

Manjish,

I see a couple of snags with that approach.

First, each array would have to be sorted alphabetically or they would not be able to match correctly and every array manipulation in AutoIt adds very significant time to the processing - as I have discovered!

Second, and perhaps more important, have you any idea of how many words you are talking about? The number of words in English of 2 to 7 seven letters must be in the order of millions! Admittedly the number of permutations of the string to be unscrambled increases as the factorial of the number of letters and rapidly reaches very big proportions, but it must be smaller unless you are dealing with pretty long strings. If you were really dealing with very long strings, you could probably get rid of a lot of the permutations early by checking if they held non-English letter combinations.

Third, who is populating your dictionary? I prefer to use MicroSoft's hard work at compiling one - at least I get some extra value from my license payment!

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

First, each array would have to be sorted alphabetically or they would not be able to match correctly and every array manipulation in AutoIt adds very significant time to the processing - as I have discovered!

y shud the arrays be sorted alphabetically.. i think u must not have seen my second post with the complete idea.. please see.. as u can see over there, i am taking a single element in the array, and searching the dictionary array with it.. so u don't need the array to be formatted alphabetically.. just need to have the same characters.. that's it..

Second, and perhaps more important, have you any idea of how many words you are talking about? The number of words in English of 2 to 7 seven letters must be in the order of millions! Admittedly the number of permutations of the string to be unscrambled increases as the factorial of the number of letters and rapidly reaches very big proportions, but it must be smaller unless you are dealing with pretty long strings. If you were really dealing with very long strings, you could probably get rid of a lot of the permutations early by checking if they held non-English letter combinations.

I agree.. this will take a hell lot of a time.. but it has an advantage, here.. if there are words like "bat" and "tab", they are valid english words.. and still have the same letters.. so if the scrambled word was "tba" my method could tell u both the words, possible..

Also about the time, see it can be greatly reduced, like this.. whenever there is a letter which is not in the dictionary word, i.e $arraydic, the loop will exit then and there.. so no time wasted in comparing any more.. 1 mismatch and wham.. next word please..

Third, who is populating your dictionary? I prefer to use MicroSoft's hard work at compiling one - at least I get some extra value from my license payment!

I agree, though my company paid the money for my license.. :) :)


[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

Thank you for the assistance. Alright here is what I have so far. However there are a couple of things. It does find the correct word here, after I press ok on the msgbox it continues to search for more words. (I'm using a dictionary of around 4000 words so it does take some time but I don't mind, for now)

Anyway is there a way to be more precise? I mean, it does find the word that matches, but it's not a 100% match all the time and for some reason if it's a longer word at the end of the file it completely overlooks it. Anyway here is the code that I have so far.

#include<array.au3>
#include<file.au3>
#include <GUIConstants.au3>


GUICreate("Input The Scrambled Word", 320,120, @DesktopWidth/2-160, @DesktopHeight/2-45, -1, 0x00000018); WS_EX_ACCEPTFILES
$input = GUICtrlCreateInput ( "", 10,  5, 300, 20)
$btn = GUICtrlCreateButton ("Ok", 40,  75, 60, 20)

GUISetState () 

$msg = 0
While $msg <> $GUI_EVENT_CLOSE
       $msg = GUIGetMsg()
       Select
           Case $msg = $btn
               
$file_in = FileOpen('dictionary.txt', 0)
If $file_in = -1 Then
  MsgBox(0, "Mistake", "Nothing in this file")
  Exit
EndIf
               
DIM $filearray

$ray = 0
While 1
$ray = $ray + 1 
;_FileReadToArray("dictionary.txt", $filearray)

$filearray = FileReadLine($file_in)

$gotit = "Not Found"

$dic=$filearray

$arraydic=StringSplit($dic,"")

$string = GUICtrlRead($input)

;$string="laba"

$array=StringSplit($string,"")

$count=0
For $i=1 To $array[0]
$going = _ArraySearch($arraydic,$array[$i])

$found = $array[$i]

if Not @error Then 
    $count=$count+1
EndIf

ToolTip($filearray,0,15,"",2)
            
If $going = 1  AND StringLen($filearray) = StringLen($string) AND $count=$array[0] Then
$gotit = $filearray
MsgBox(4096,"match??",$gotit)
$going = 0
Endif

Next
GUISetState ()
Wend

               
EndSelect
Wend

Share this post


Link to post
Share on other sites

can u please provide the dictionary.txt file??


[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Some improvements:

$filearray = FileReadLine($file_in)
$string = GUICtrlRead($input)

You can do a comparison right here, regarding stringlength.. this will save lots of time..

Like this:

#include<array.au3>
#include<file.au3>
#include <GUIConstants.au3>


GUICreate("Input The Scrambled Word", 320,120, @DesktopWidth/2-160, @DesktopHeight/2-45, -1, 0x00000018); WS_EX_ACCEPTFILES
$input = GUICtrlCreateInput ( "", 10,  5, 300, 20)
$btn = GUICtrlCreateButton ("Ok", 40,  75, 60, 20)

GUISetState () 

$msg = 0
While $msg <> $GUI_EVENT_CLOSE
       $msg = GUIGetMsg()
       Select
           Case $msg = $btn
             
            $file_in = FileOpen('dictionary.txt', 0)
            If $file_in = -1 Then
                MsgBox(0, "Mistake", "Nothing in this file")
                Exit
            EndIf
               
            DIM $filearray

            $ray = 0
            While 1
                $ray = $ray + 1 
        ;_FileReadToArray("dictionary.txt", $filearray)

                $filearray = FileReadLine($file_in)
                $string = GUICtrlRead($input)
                    if stringlen($filearray)=StringLen($string) Then unscramble()

            Wend
              
          EndSelect
WEnd

func unscramble()
$gotit = "Not Found"
$dic=$filearray
$arraydic=StringSplit($dic,"")
$array=StringSplit($string,"")

$count=0
For $i=1 To $array[0]
$going = _ArraySearch($arraydic,$array[$i])

$found = $array[$i]

if Not @error Then 
    $count=$count+1
EndIf

ToolTip($filearray,0,15,"",2)
            
If $going = 1  AND $count=$array[0] Then
$gotit = $filearray
MsgBox(4096,"match??",$gotit)
$going = 0
Endif

Next

2) Whats ur intention with this:

$ray = $ray + 1

and

$found = $array[$i]

Didn't find any use for them, anywhere..

3) When u r using $filearray in ur end msgbox.. why r u defining it as $dic, for stringsplit..

Its better if u save up some code.. will reduce ur time drastically.. so don't keep on defining same variables again and again..

Edited by Manjish

[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Thanks a lot. The dictionary file can be here: http://www.glasglow.com/dictionary.txt

Yes I know some of the variables were redundant after changes. I was in a 'trial and error' mode. : ( With the $dic=$filearray, I was first tring to bring make the dictionary an array and run two arrays but later saw I didn't need to do that. So I took it off but left the variable. I know I know hacked up ugly code. I have no excuse.

I am trying your code now, when I type INFORMATION as the scrambled word I am getting a freeze on EXOSKELETON in the tooltip. I'll work on that. It seems to be bringing it into the function because of the StringLen match then it can't continue through the rest of the words after the function call.

Edited by glasglow

Share this post


Link to post
Share on other sites

Maybe sort the words in your dictionary by letter, and build an intermediate file that way, with links back to the original word, so if "scramble" is the 100th word in your dictionary, your intermediate file would contain an entry like "["abcelmrs", 100]"

then you could sort the word you are trying to descramble, like "masblerc" would become "abcelmrs" and whala, you'd get a hit.

Building an MS Access table, with two indexed fields per row like "Word" ("scramble") and "SortedWord" (abcelmrs") might speed things up. Then you could use ADO from Autoit and just query "Select [Word] from DICTTABLE where [sortedWord] = $SortedSearchString;

Looping though that cursor would return all words that matched the SortedSearchString.

Share this post


Link to post
Share on other sites

I checked this for most words.. It seems to work..

Did some changes.. lots rather..

#include<array.au3>
#include<file.au3>
#include <GUIConstants.au3>


GUICreate("Input The Scrambled Word", 320,120, @DesktopWidth/2-160, @DesktopHeight/2-45, -1, 0x00000018); WS_EX_ACCEPTFILES
$input = GUICtrlCreateInput ( "", 10,  5, 300, 20)
$btn = GUICtrlCreateButton ("Ok", 40,  75, 60, 20)

GUISetState () 

$msg = 0
While $msg <> $GUI_EVENT_CLOSE
       $msg = GUIGetMsg()
        Select
           Case $msg = $btn
             
            $file_in = FileOpen('dictionary.txt', 0)
            If $file_in = -1 Then
                MsgBox(0, "Mistake", "Nothing in this file")
                Exit
            EndIf
               
                For $i=1 to 10000000
                    $dic = FileReadLine($file_in,$i)
                        If $dic='' then ExitLoop
                            $word = GUICtrlRead($input)
                        if stringlen($dic)=StringLen($word) Then unscramble()
                Next
        EndSelect
WEnd

func unscramble()
$arraydic=StringSplit($dic,"")
$array=StringSplit($word,"")
$count=0
For $i=1 To $array[0]
_ArraySearch($arraydic,$array[$i])
if Not @error Then 
    $count=$count+1
EndIf

          
If $count=$array[0] Then
MsgBox(4096,"match??",$dic)
Exit
Endif

Next
EndFunc

[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

No kidding no kidding, that's it right there.

Interesting label/count there

For $i=1 to 10000000
$dic = FileReadLine($file_in,$i)

I'm going to have to learn from that one. And the removal of the variables for the _arraysearch AND I think most important the narrowing out of the blank lines as a precaution. I got that too. It would stop searching without telling me what it was doing there.

Anyway you stuck with it. For 6 hours now I have been trying to put the results that we got before into an array, then searching the second array, then putting the second results into even yet another array and then searching that. I got it down pretty good with just a few results, but still had the end of file problem where it was skipping the results completely.

Anyway it's good stuff now you are the MAN. I'm glad I didn't go to sourceforge. : )

The only thing I'm doing to this is taking off the Exit here

If $count=$array[0] Then
MsgBox(4096,"match??",$dic)
;Exit
Endif

So that I can keep looking through for more matches. For example, if I use the full dictionary and I use the word ARROGANCE, then I will get IGNORANCE first. Without the exit I can continue looping to the next match.

Edited by glasglow

Share this post


Link to post
Share on other sites

sure man.. do anything u like to make it more suiting to ur needs..

As I told u.. i wanted to do this for a long time now.. finally was able to..


[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

#include<array.au3>
#include<file.au3>
#include <GUIConstants.au3>
#include <ButtonConstants.au3>

Global $Array_Max = 1000, $Array_Increment = 100, $Dictionary_Array[$Array_Max][2], $Idx = 0, $i, $word
GUICreate("Input the Scrambled Word", 320,120, @DesktopWidth/2-160, @DesktopHeight/2-45, -1, 0x00000018); WS_EX_ACCEPTFILES
$input = GUICtrlCreateInput("", 10,  5, 300, 20)
$output = GUICtrlCreateLabel( "", 10,  40, 300, 20)
$btn = GUICtrlCreateButton("Ok", 40,  75, 60, 20, $BS_DEFPUSHBUTTON)
GUISetState () 

Process_Dictionary()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $btn
            $word = GUICtrlRead($input)
            $i = StringSplit($word,"", 2)
            _ArraySort($i)
            $word = _ArrayToString($i,"")
            $i = _ArraySearch($Dictionary_Array, $word, 0, 0, 0, 0, 0, 1)
            If @error Then
                GUICtrlSetData($output,"<not found>")
            Else;         if you like,  stick a loop here to process multiple hits
                GUICtrlSetData($output, $Dictionary_Array[$i][0])
            EndIf
        Case $GUI_EVENT_CLOSE   
            ExitLoop
    EndSwitch
WEnd
Exit

;-------------------------------------------------------------------------------
Func Process_Dictionary()
    GUICtrlSetState($input, $GUI_DISABLE)
    GUICtrlSetData($output,"Loading dictionary...")
    GuiCtrlSetColor($output, 0xFF0000); red

    $file_in = FileOpen('dictionary.txt', 0)
    If $file_in = -1 Then
        MsgBox(0, "Error", "Dictionary file not found")
        Exit
    EndIf
    While 1
        $word = FileReadLine($file_in)
        If @error = -1 Then ExitLoop
        $Dictionary_Array[$Idx][0] = $word
        $i = StringSplit($word,"", 2)
        _ArraySort($i)
        $Dictionary_Array[$Idx][1] = _ArrayToString($i,"")
        $Idx += 1
        If $Idx = $Array_Max Then
            $Array_Max += $Array_Increment
            Redim $Dictionary_Array[$Array_Max][2]
        EndIf
        
    WEnd
    Redim $Dictionary_Array[$Idx][2]
;   _ArrayDisplay($Dictionary_Array)

    GUICtrlSetData($output,"")
    GuiCtrlSetColor($output, 0x000000); black
    GUICtrlSetState($input, $GUI_ENABLE)
    GUICtrlSetState($input, $GUI_FOCUS)
EndFunc

Is a shame, _ArrayBinarySearch apparently doesn't like 2D arrays, that would speed things up.

Using a database (Access, MySQL, etc) would be much faster.

Edit: code tags. Added loop comment

Edited by Spiff59

Share this post


Link to post
Share on other sites

This one ought to handle multiple matches.

The punctuation and special-characters in some of your words would need handling, they throw the arraysort off.

#include<array.au3>
#include<file.au3>
#include <GUIConstants.au3>
#include <ButtonConstants.au3>

Global $Array_Max = 1000, $Array_Increment = 100, $Dictionary_Array[$Array_Max][2], $Idx = 0, $i, $word, $str
GUICreate("Input the Scrambled Word", 320,120, @DesktopWidth/2-160, @DesktopHeight/2-45, -1, 0x00000018); WS_EX_ACCEPTFILES
$input = GUICtrlCreateInput("", 10,  5, 300, 20)
$output = GUICtrlCreateLabel( "", 10,  40, 300, 20)
$btn = GUICtrlCreateButton("Ok", 40,  75, 60, 20, $BS_DEFPUSHBUTTON)
GUISetState () 

Process_Dictionary()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $btn
            $word = GUICtrlRead($input)
            $i = StringSplit($word,"", 2)
            _ArraySort($i)
            $word = _ArrayToString($i,"")
            $i = _ArraySearch($Dictionary_Array, $word, 0, 0, 0, 0, 1, 1)
            If @error Then
                GUICtrlSetData($output,"<not found>")
            Else        
                $str = $Dictionary_Array[$i][0]
                While $i < $Array_Max
                    $i = _ArraySearch($Dictionary_Array, $word, $i + 1, 0, 0, 0, 1, 1)
                    If @error Then ExitLoop
                    If $Dictionary_Array[$i][1] = $word Then
                        $str &= ", " & $Dictionary_Array[$i][0]
                    Else
                        ExitLoop
                    EndIf
                Wend
                GUICtrlSetData($output, $str)
            EndIf
        Case $GUI_EVENT_CLOSE   
            ExitLoop
    EndSwitch
WEnd
Exit

;-------------------------------------------------------------------------------
Func Process_Dictionary()
    GUICtrlSetState($input, $GUI_DISABLE)
    GUICtrlSetData($output,"Loading dictionary...")
    GuiCtrlSetColor($output, 0xFF0000); red

    $file_in = FileOpen('dictionary.txt', 0)
    If $file_in = -1 Then
        MsgBox(0, "Error", "Dictionary file not found")
        Exit
    EndIf
    While 1
        $word = FileReadLine($file_in)
        If @error = -1 Then ExitLoop
        $Dictionary_Array[$Idx][0] = $word
        $i = StringSplit($word,"", 2)
        _ArraySort($i)
        $Dictionary_Array[$Idx][1] = _ArrayToString($i,"")
        $Idx += 1
        If $Idx = $Array_Max Then
            $Array_Max += $Array_Increment
            Redim $Dictionary_Array[$Array_Max][2]
        EndIf
        
    WEnd
    Redim $Dictionary_Array[$Idx][2]
    $Array_Max = UBound($Dictionary_Array)
    _ArraySort($Dictionary_Array, 0, 0, 0, 1)

    GUICtrlSetData($output,"")
    GuiCtrlSetColor($output, 0x000000); black
    GUICtrlSetState($input, $GUI_ENABLE)
    GUICtrlSetState($input, $GUI_FOCUS)
EndFunc

Share this post


Link to post
Share on other sites

@spiff..

I love what u have done to my idea/script..

Awesome.. very fast too.. thanks..

I was in fact thinking of putting the words of the dic in the array.. but i thought that wud take a lot of time, for the dictionary to load.. for so many words..

But we can improve this too.. u didn't incorporate the stringlen check here.. that could indeed save hell lot of time..


[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

Well, he has duplicate words in his list, and words with control-characters embedded (MEGA, SUPER, SOIL, the second WOOL). That stuff ought to be weeded out, and punctuation stripped (or handled). Once his input dictionary is clean, he'll be able to avoid GIGO syndrome. Parking an " _ArrayDisplay($Dictionary_Array)" temporarily after "Process_Dictionary()" shows some of the troublemakers in his word list.

I didn't need that Ubound at the end of the function that preloads the dictionary, "$Array_Max = $Idx" would have been sufficient.

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

ya i saw that too.. about the temporary _arraydisplay.. but this the least of the problems.. we can easily rectify that one.. there are thousands of compilations which we can use for the dic..

To tell u the truth ur idea of _ArraySort was far better than what i had in mind.. kudos.. :)..

about the characters like in "RED-HOT".. who would put a "-" in a scrabled word anyway.. i have played a lot of unscrambling games.. but never have seen a "-"..

So let's not worry about the dictionary file.. it can be changed..

I thought of a way to incorporate the StringLen feature as well.. it could reduce time..

We could add a third column to the array containing the no. of characters in the word.. we can obtain that from $char like this:

$word = GUICtrlRead($input)
$i = StringSplit($word,"", 2)
$chars=$i[0]

And then do a search only when the no. of chars is same.. this will narrow down the search area.. Tell me if its possible..

Edited by Manjish

[font="Garamond"]Manjish Naik[/font]Engineer, Global Services - QPSHoneywell Automation India LimitedE-mail - Manjish.Naik@honeywell.com

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0