# Anagram Solver

## Recommended Posts

BEFORE I START: I just want to say a quick thanks to martin and Xand3r, for their help on a part of this in the General Help Forum - cheers guys!

OK, so this was part of a MUCH larger project of mine...but i thought i might as well, share this seriously good finding on the internet that i...well...found. The site being: http://www.f1compiler.com/samples/Anagram123.f1.html

Brief explanation of code from site:

If you give each letter of the alphabet a different PRIME NUMBER, so..

```a=2
b=3
c=5
d=7
e=11
..and so on```

...and then multiply the letters numerical values in a given word, eg. BAT

```B=3
A=2
T=71

BAT=3*2*71=426```

This will have the same numerical value as the word, TAB

```T=71
A=2
B=3

TAB=71*2*3=426```

Therefore, all the program needs to do is find the numerical value of the anagram that the user has input, and find that exact same numerical value in a pre-built dictionary file.

So, this is nothing neat as i've just put pieces of code together that i used, but it works, and it does so beautifully...

on my old school 2.8GHz P4, it calculates all possible words of the anagram input by the user in these time periods:

```ANAGRAM LENGTH --- TIME (secs)
2 letters      --- 0.017
3 letters      --- 0.026
4 letters      --- 0.043
5 letters      --- 0.101
6 letters      --- 0.201
7 letters      --- 0.432
8 letters      --- 1.054
9 letters      --- 2.277
10 letters     --- 6.423
11 letters     --- 19.50```

I need to point out this is giving EVERY POSSIBLE word that can be found in the anagram...right down to two letter words, so when searching a 9 letter anagram, it is giving all the words of letter length; 9, 8, 7, 6, 5, 4, 3 and 2.

If you just want to find the exact anagram + the exact anagram with an additional letter to the anagram, this only takes 0.021 secs on my computer.

SO

Here is all the code you need, with a GUI as well, so all you need to do is run it, and bob's your uncle.

THIS IS THE ANAGRAM SOLVER

```#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiEdit.au3>
#include <Array.au3>

Opt('GUIOnEventMode', 1)
Opt("TrayOnEventMode", 1)

;=========================================================
;============== USER VALUES - NEED CHANGING ==============

\$DICTDestination=@DesktopDir & "\Library\Wordlist.txt";Destination of dictionary file
\$NUMDestination=@DesktopDir & "\Library\Numlist.txt";Destination of corresponding numerical file

;=========================================================
;=========================================================

TraySetToolTip("Anagram Solver")
\$TrayEXIT = TrayCreateItem("Exit")
TrayItemSetOnEvent(\$TrayEXIT, "_Exit")

Global \$Output, \$NumFOUND, \$Words, \$arrALPHA[27]

\$FRMAnagramSolver = GUICreate("Anagram Solver", 210, 466, 421, 131)
\$LSTWords = GUICtrlCreateEdit("", 8, 96, 193, 344, \$WS_VSCROLL)
GUICtrlCreateLabel("", 8, 96, 176, 344)
GUICtrlSetState(-1, \$GUI_ONTOP)
\$LBLAnagram = GUICtrlCreateLabel("Anagram:", 8, 8, 49, 17)
\$IPAnagram = GUICtrlCreateInput("", 64, 6, 137, 21)
GUICtrlSetState(-1, \$GUI_DISABLE)

\$BUTSolve = GUICtrlCreateButton("Solve", 8, 64, 195, 25, \$WS_GROUP)
GUICtrlSetState(-1, \$GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Search")
GUICtrlSetState(-1, \$GUI_CHECKED)
\$LBLStatus = GUICtrlCreateLabel("Building Dictionaries...", 8, 448, 191, 17)

GUISetOnEvent(\$GUI_EVENT_CLOSE, "_Exit")

GUISetState(@SW_SHOW)

\$arrALPHA[1] = "A"
\$arrALPHA[2] = "B"
\$arrALPHA[3] = "C"
\$arrALPHA[4] = "D"
\$arrALPHA[5] = "E"
\$arrALPHA[6] = "F"
\$arrALPHA[7] = "G"
\$arrALPHA[8] = "H"
\$arrALPHA[9] = "I"
\$arrALPHA[10] = "J"
\$arrALPHA[11] = "K"
\$arrALPHA[12] = "L"
\$arrALPHA[13] = "M"
\$arrALPHA[14] = "N"
\$arrALPHA[15] = "O"
\$arrALPHA[16] = "P"
\$arrALPHA[17] = "Q"
\$arrALPHA[18] = "R"
\$arrALPHA[19] = "S"
\$arrALPHA[20] = "T"
\$arrALPHA[21] = "U"
\$arrALPHA[22] = "V"
\$arrALPHA[23] = "W"
\$arrALPHA[24] = "X"
\$arrALPHA[25] = "Y"
\$arrALPHA[26] = "Z"

GUICtrlSetState(\$IPAnagram, \$GUI_ENABLE)
GUICtrlSetState(\$BUTSolve, \$GUI_ENABLE)
GUICtrlSetState(\$IPAnagram, \$GUI_FOCUS)

Sleep(500)

\$Break = "--------------------------------------------------------"

While 1
Sleep(100)
WEnd

Func _Search()
If StringIsAlpha(GUICtrlRead(\$IPAnagram)) = 0 Then Return
GUICtrlSetState(\$BUTSolve, \$GUI_DISABLE)
Global \$Time = TimerInit()
_SearchLETTERS()
Else
_SearchCOMBOS()
EndIf
GUICtrlSetState(\$BUTSolve, \$GUI_ENABLE)
EndFunc   ;==>_Search

Func _AllCOMBOS(\$text)
\$a = StringSplit(\$text, "")
For \$i = 0 To 2 ^ StringLen(\$text) - 1
\$res = ''
For \$j = 1 To StringLen(\$text)
If BitAND(\$i, 2 ^ (\$j - 1)) Then \$res &= \$a[\$j]
Next
Next
EndFunc   ;==>_AllCOMBOS

Func _SearchCOMBOS()

Global \$arrWORDLIST[1], \$WordRETURN = "", \$OutputUNIQUE[1]

GUICtrlSetData(\$LSTWords, "")
GUICtrlSetData(\$LBLStatus, "Searching...")

_AllCOMBOS(\$Anagram)

\$arrWORDLIST = _ArrayUnique(\$arrWORDLIST)

\$AnagramLEN = StringLen(\$Anagram)
While 1
_GUICtrlEdit_AppendText(\$LSTWords, \$Break&@CRLF&\$AnagramLEN&" CHARACTERS"&@CRLF)
For \$i = 1 To UBound(\$arrWORDLIST) - 1

If StringLen(\$arrWORDLIST[\$i]) = \$AnagramLEN Then

\$Output = 1

\$AnagramNUM = StringSplit(\$arrWORDLIST[\$i], "")
For \$x = 1 To \$AnagramNUM[0]
_NumASSIGN(\$AnagramNUM[\$x])
Next

_SearchLIST()

If _ArraySearch(\$OutputUNIQUE, \$Output) < 0 Then
_GUICtrlEdit_AppendText(\$LSTWords, StringUpper(\$Words))
EndIf

EndIf

Next
\$AnagramLEN -= 1
If \$AnagramLEN < 2 Then ExitLoop
WEnd

GUICtrlSetData(\$LBLStatus, "Searched in " & Round(TimerDiff(\$Time) / 1000, 5) & " secs")

EndFunc   ;==>_SearchCOMBOS

Func _SearchLETTERS()
GUICtrlSetData(\$LSTWords, "")
GUICtrlSetData(\$LBLStatus, "Searching...")

\$List = ""

\$Output = 1

\$AnagramNUM = StringSplit(\$Anagram, "")
For \$x = 1 To \$AnagramNUM[0]
_NumASSIGN(\$AnagramNUM[\$x])
Next

_SearchLIST()

If \$Words = "" Then \$Words = "NONE FOUND" & @CRLF

\$List &= "ORIGINAL ANAGRAM RESULTS" & @CRLF & \$Break & @CRLF & \$Words & \$Break & @CRLF & "WITH ADDITIONAL LETTERS" & @CRLF & \$Break

\$OrigOUTPUT = \$Output
For \$x = 1 To UBound(\$arrALPHA) - 1

_NumASSIGN(\$arrALPHA[\$x])

\$Output = Number(\$Output)

_SearchLIST()

If \$NumFOUND > -1 Then \$List &= @CRLF & \$arrALPHA[\$x] & @CRLF & \$Words & \$Break

\$Output = \$OrigOUTPUT

Next

_GUICtrlEdit_AppendText(\$LSTWords, StringUpper(\$List))

GUICtrlSetData(\$LBLStatus, "Searched in "  & Round(TimerDiff(\$Time) / 1000, 5) & " secs")

EndFunc   ;==>_SearchLETTERS

Func _SearchLIST()
Global \$NumFOUND = _ArrayBinarySearch(\$NumLIST, \$Output, 1, \$NumLIST[0] - 1)

If \$NumFOUND > -1 Then
\$OrigNUM = \$NumFOUND
\$Words = \$WordLIST[\$NumFOUND] & @CRLF
While 1
\$NumFOUND += 1
If \$NumLIST[\$NumFOUND] = \$Output Then
\$Words &= \$WordLIST[\$NumFOUND] & @CRLF
Else
\$NumFOUND = \$OrigNUM
While 1
\$NumFOUND -= 1
If \$NumLIST[\$NumFOUND] = \$Output Then
\$Words &= \$WordLIST[\$NumFOUND] & @CRLF
Else
ExitLoop
EndIf
WEnd
ExitLoop
EndIf
WEnd
Else
\$Words = ""
EndIf

EndFunc   ;==>_SearchLIST

Func _NumASSIGN(\$Letter)
If \$Letter = "A" Then \$Output *= 2;
If \$Letter = "B" Then \$Output *= 3;
If \$Letter = "C" Then \$Output *= 5;
If \$Letter = "D" Then \$Output *= 7;
If \$Letter = "E" Then \$Output *= 11;
If \$Letter = "F" Then \$Output *= 13;
If \$Letter = "G" Then \$Output *= 17;
If \$Letter = "H" Then \$Output *= 19;
If \$Letter = "I" Then \$Output *= 23;
If \$Letter = "J" Then \$Output *= 29;
If \$Letter = "K" Then \$Output *= 31;
If \$Letter = "L" Then \$Output *= 37;
If \$Letter = "M" Then \$Output *= 41;
If \$Letter = "N" Then \$Output *= 43;
If \$Letter = "O" Then \$Output *= 47;
If \$Letter = "P" Then \$Output *= 53;
If \$Letter = "Q" Then \$Output *= 59;
If \$Letter = "R" Then \$Output *= 61;
If \$Letter = "S" Then \$Output *= 67;
If \$Letter = "T" Then \$Output *= 71;
If \$Letter = "U" Then \$Output *= 73;
If \$Letter = "V" Then \$Output *= 79;
If \$Letter = "W" Then \$Output *= 83;
If \$Letter = "X" Then \$Output *= 89;
If \$Letter = "Y" Then \$Output *= 97;
If \$Letter = "Z" Then \$Output *= 101;
EndFunc   ;==>_NumASSIGN

Func _Exit()

Exit

EndFunc   ;==>_Exit```

If you DO NOT WANT TO USE MY DICTIONARY FILE and you have your own you want to use, then i have written this quick program to read your dictionary, and output two new files, 1. the NEW dictionary file and 2. the corresponding numerical dictionary. NOTE: ENSURE YOUR OWN DICTIONARY FILE HAS ONE WORD PER LINE.

THIS IS THE DICTIONARY BUILDER

```#include <Array.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt("TrayOnEventMode", 1)

TraySetToolTip("Library Builder")
\$TrayEXIT = TrayCreateItem("Exit")
TrayItemSetOnEvent(\$TrayEXIT, "_Exit")

Global \$Letter, \$Output

\$FRMLibraryBuilder = GUICreate("Library Builder", 482, 50, 235, 180)
\$LBLDictSOURCE = GUICtrlCreateLabel("Dictionary File:", 8, 16, 73, 17)
\$IPDictSOURCE = GUICtrlCreateInput("", 88, 14, 265, 21)
GUICtrlSetState(-1,\$GUI_DISABLE)
\$BUTBuild = GUICtrlCreateButton("Build", 400, 12, 75, 25, \$WS_GROUP)
\$BUTDictSOURCE = GUICtrlCreateButton("...", 360, 12, 27, 25, \$WS_GROUP)
GUISetState(@SW_SHOW)

While 1

\$msg = GUIGetMsg()
Select
Case \$msg = \$BUTBuild
Else
GUICtrlSetState(\$BUTDictSOURCE,\$GUI_DISABLE)
GUICtrlSetState(\$BUTBuild,\$GUI_DISABLE)
_BuildARRAY()
_WriteDICTIONARY()
Sleep(1000)
WinSetTitle("Library Builder","","Library Builder")
GUICtrlSetState(\$BUTDictSOURCE,\$GUI_ENABLE)
GUICtrlSetState(\$BUTBuild,\$GUI_ENABLE)
EndIf

Case \$msg = \$BUTDictSOURCE
\$DestSOURCE=FileOpenDialog ( "Dictionary file destination", "", "Text Files (*.txt)" ,1, "" ,\$FRMLibraryBuilder)
If Not @ERROR Then GUICtrlSetData(\$IPDictSOURCE,\$DestSOURCE)

Case \$msg=\$GUI_EVENT_CLOSE
_Exit()

EndSelect

WEnd

WinSetTitle("Library Builder","","Library Builder - Reading Dictionary")

Global \$NumLIST[UBound(\$WordLIST)]

For \$x=1 To \$WordLIST[0]

\$WordSPLIT=StringSplit(\$WordLIST[\$x],"")

\$Output=1

For \$a=1 To \$WordSPLIT[0]

\$Letter=\$WordSPLIT[\$a]

_NumASSIGN()

Next

\$NumLIST[\$x]=Number(\$Output)

WinSetTitle("Library Builder","","Library Builder - Assigning Values - "&\$x&"\"&\$WordLIST[0])

Next

EndFunc

Func _BuildARRAY()

WinSetTitle("Library Builder","","Library Builder - Building 2D Array")

_Array2D_From1D(\$WordLIST)
_Array2D_From1D(\$NumLIST)

WinSetTitle("Library Builder","","Library Builder - Building 2D Array - Done")

Sleep(500)

WinSetTitle("Library Builder","","Library Builder - Sorting 2D Array")

_ArraySort(\$WordLIST, 0, 0, 0, 1)

WinSetTitle("Library Builder","","Library Builder - Sorting 2D Array - Done")

Sleep(500)

EndFunc

Func _WriteDICTIONARY()

For \$x = 1 To UBound(\$WordLIST) - 1

FileWrite(\$DestWORD, \$WordLIST[\$x][0] & @CRLF)
FileWrite(\$DestNUM, \$WordLIST[\$x][1] & @CRLF)

WinSetTitle("Library Builder","","Library Builder - Writing Dictionary - "&\$x&"\"&UBound(\$WordLIST) - 1)

Next

Sleep(500)

WinSetTitle("Library Builder","","Library Builder - Finished")

EndFunc

Func _NumASSIGN()

If \$Letter = "A" Then \$Output *= 2;
If \$Letter = "B" Then \$Output *= 3;
If \$Letter = "C" Then \$Output *= 5;
If \$Letter = "D" Then \$Output *= 7;
If \$Letter = "E" Then \$Output *= 11;
If \$Letter = "F" Then \$Output *= 13;
If \$Letter = "G" Then \$Output *= 17;
If \$Letter = "H" Then \$Output *= 19;
If \$Letter = "I" Then \$Output *= 23;
If \$Letter = "J" Then \$Output *= 29;
If \$Letter = "K" Then \$Output *= 31;
If \$Letter = "L" Then \$Output *= 37;
If \$Letter = "M" Then \$Output *= 41;
If \$Letter = "N" Then \$Output *= 43;
If \$Letter = "O" Then \$Output *= 47;
If \$Letter = "P" Then \$Output *= 53;
If \$Letter = "Q" Then \$Output *= 59;
If \$Letter = "R" Then \$Output *= 61;
If \$Letter = "S" Then \$Output *= 67;
If \$Letter = "T" Then \$Output *= 71;
If \$Letter = "U" Then \$Output *= 73;
If \$Letter = "V" Then \$Output *= 79;
If \$Letter = "W" Then \$Output *= 83;
If \$Letter = "X" Then \$Output *= 89;
If \$Letter = "Y" Then \$Output *= 97;
If \$Letter = "Z" Then \$Output *= 101;

EndFunc   ;==>_NumASSIGN

Func _Exit()

Exit

EndFunc

;****************************************************************
;================================================================

;REST OF CODE IS JUST THE REQUIRED FUNCTIONS FROM AN _ARRAY2D UDF

;================================================================
;****************************************************************

Func _Array2D_Add(ByRef \$avArray, \$vValue, \$iDim = 1, \$iSubItem = 0, \$iDoubleRedim = 0);== AUTHOR ==  JOS VAN DER ZANDE
If \$iDim = Default Then \$iDim = 1
If \$iSubItem = Default Then \$iSubItem = 0
If \$iDoubleRedim = Default Then \$iDoubleRedim = 0
\$vValue = __Array2D_GetValue(\$vValue)

Local \$iUbound, \$iSize, \$iElement
Switch UBound(\$avArray, 0)
Case 0
If Not IsArray(\$vValue) Then
Dim \$avArray [1] = [\$vValue]
ElseIf UBound(\$vValue, 0) = 1 Or UBound(\$vValue, 0) = 2 Then
\$avArray = \$vValue
Else
Return SetError(4, 0, 0)
EndIf
Return SetError(0, 0, 1)
Case 1
If Not IsArray(\$vValue) Then
\$iSize = 1
ElseIf UBound(\$vValue, 0) = 1 Then
\$iSize = UBound(\$vValue)
Else
Return SetError(4, 0, 0)
EndIf
\$iElement = UBound(\$avArray)
ReDim \$avArray [UBound(\$avArray) + \$iSize]
Case 2
Local \$iUbound2, \$iSize2
If \$iDim <> 1 And \$iDim <> 2 Then Return SetError(3, 0, 0)
If (Not IsArray(\$vValue)) Or UBound(\$vValue, 0) = 1 Then
\$iSize = 1
ElseIf UBound(\$vValue, 0) = 2 Then
\$iSize = UBound(\$vValue, \$iDim)
Else
Return SetError(4, 0, 0)
EndIf
\$iElement = UBound(\$avArray, \$iDim)

If Not \$iDoubleRedim Then
\$iUbound2 = UBound(\$avArray, Mod(\$iDim, 2) + 1)
Else
If Not IsArray(\$vValue) Then
\$iSize2 = 0
ElseIf UBound(\$vValue, 0) = 1 Then
\$iSize2 = UBound(\$vValue)
Else
\$iSize2 = UBound(\$vValue, Mod(\$iDim, 2) + 1)
EndIf
\$iUbound2 = __Max(UBound(\$avArray, Mod(\$iDim, 2) + 1), \$iSubItem + \$iSize2)
EndIf
\$iUbound = UBound(\$avArray, \$iDim) + \$iSize

If \$iDim = 1 Then
ReDim \$avArray [\$iUbound][\$iUbound2]
Else
ReDim \$avArray [\$iUbound2][\$iUbound]
EndIf
Case Else
Return SetError(2, 0, 0)
EndSwitch

If UBound(\$avArray, 0) = 2 And \$iDim = 2 And IsArray(\$vValue) Then _Array2D_Swap(\$iElement, \$iSubItem)
_Array2D_PutValue(\$avArray, \$vValue, \$iElement, \$iDim, \$iSubItem)

Return SetError(0, 0, 1)

Func _Array2D_PutValue(ByRef \$avArray, \$vValue, \$iElement = 0, \$iDim = 1, \$iSubItem = 0) ;== AUTHOR == TOLF
If \$iElement = Default Then \$iElement = 0
If \$iDim = Default Then \$iDim = 1
If \$iSubItem = Default Then \$iSubItem = 0
\$vValue = __Array2D_GetValue(\$vValue)

If Not IsArray(\$avArray) Then Return SetError(1, 0, 0)
If UBound(\$avArray, 0) = 1 Then \$iDim = 1
If \$iDim <> 1 And \$iDim <> 2 Then Return SetError(3, 0, 0)
If \$iElement < 0 Then \$iElement = 0

Local \$i, \$j
Local \$iUbound = UBound(\$avArray) - 1
Switch UBound(\$avArray, 0)
Case 1
If UBound(\$vValue, 0) > 1 Then Return SetError(4, 0, 0)
If Not IsArray(\$vValue) Then
If \$iElement < UBound(\$avArray) Then \$avArray [\$iElement] = \$vValue
ElseIf UBound(\$vValue, 0) = 1 Then
For \$i = \$iElement To __Min(\$iElement + UBound(\$vValue) - 1, \$iUbound)
\$avArray [\$i] = \$vValue [\$i - \$iElement]
Next
EndIf
Case 2
If UBound(\$vValue, 0) > 2 Then Return SetError(4, 0, 0)
Local \$iUbound2 = UBound(\$avArray, 2) - 1
If \$iSubItem < 0 Then \$iSubItem = 0
Switch \$iDim
Case 1
If Not IsArray(\$vValue) Then
If \$iElement < UBound(\$avArray) And \$iSubItem < UBound(\$avArray, 2) Then \$avArray [\$iElement][\$iSubItem] = \$vValue
ElseIf UBound(\$vValue, 0) = 1 Then
For \$i = \$iSubItem To __Min(\$iSubItem + UBound(\$vValue) - 1, \$iUbound2)
\$avArray [\$iElement][\$i] = \$vValue [\$i - \$iSubItem]
Next
ElseIf UBound(\$vValue, 0) = 2 Then
For \$i = \$iElement To __Min(\$iElement + UBound(\$vValue) - 1, \$iUbound)
For \$j = \$iSubItem To __Min(\$iSubItem + UBound(\$vValue, 2) - 1, \$iUbound2)
\$avArray [\$i][\$j] = \$vValue [\$i - \$iElement][\$j - \$iSubItem]
Next
Next
EndIf
Case 2
If Not IsArray(\$vValue) Then
If \$iElement < UBound(\$avArray, 2) And \$iSubItem < UBound(\$avArray) Then \$avArray [\$iSubItem][\$iElement] = \$vValue
ElseIf UBound(\$vValue, 0) = 1 Then
For \$i = \$iElement To __Min(\$iElement + UBound(\$vValue) - 1, \$iUbound)
\$avArray [\$i][\$iSubItem] = \$vValue [\$i - \$iElement]
Next
ElseIf UBound(\$vValue, 0) = 2 Then
For \$i = \$iElement To __Min(\$iElement + UBound(\$vValue) - 1, \$iUbound)
For \$j = \$iSubItem To __Min(\$iSubItem + UBound(\$vValue, 2) - 1, \$iUbound2)
\$avArray [\$i][\$j] = \$vValue [\$i - \$iElement][\$j - \$iSubItem]
Next
Next
EndIf
EndSwitch
Case Else
Return SetError(2, 0, 0)
EndSwitch

Return SetError(0, 0, 1)
EndFunc   ;==>_Array2D_PutValue

Func __Array2D_GetValue(\$vValue);== AUTHOR = TOLF
If IsString(\$vValue) And \$ARRAY2D_DELIM_STRING <> "" And \$vValue <> "" Then Return stringsplit (\$vValue, \$ARRAY2D_DELIM_STRING, \$ARRAY2D_DELIM_FLAG)
Return \$vValue
EndFunc   ;==>__Array2D_GetValue

Func _Array2D_From1D(ByRef \$avArray, \$iTranspose = 0);==AUTHOR = TOLF
If \$iTranspose = Default Then \$iTranspose = 0

If Not IsArray(\$avArray) Then Return SetError(1, 0, 0)
If Not UBound(\$avArray, 0) = 1 Then Return SetError(2, 0, 0)

Local \$i
Switch \$iTranspose
Case 0
Local \$avTransposed [UBound(\$avArray) ][1]
For \$i = 1 To UBound(\$avArray)
\$avTransposed [\$i - 1][0] = \$avArray [\$i - 1]
Next
Case 1
Local \$avTransposed [1][UBound(\$avArray) ]
For \$i = 1 To UBound(\$avArray)
\$avTransposed [0][\$i - 1] = \$avArray [\$i - 1]
Next
Case Else
Return SetError(3, 0, 0)
EndSwitch
\$avArray = \$avTransposed

Return SetError(0, 0, 1)
EndFunc   ;==>_Array2D_From1D

Func _Array2D_Max(Const ByRef \$avArray, \$iCompNumeric = 0, \$iStart = 0, \$iEnd = -1, \$iDim = 1, \$iSubItem = 0);==AUTHOR = CEPHAS
If \$iCompNumeric = Default Then \$iCompNumeric = 0
If \$iStart = Default Then \$iStart = 0
If \$iEnd = Default Then \$iEnd = -1
If \$iDim = Default Then \$iDim = 1
If \$iSubItem = Default Then \$iSubItem = 0

Local \$iResult = _Array2D_MaxIndex(\$avArray, \$iCompNumeric, \$iStart, \$iEnd, \$iDim, \$iSubItem)
If @error Then Return SetError(@error, 0, "")
Select
Case UBound(\$avArray, 0) = 1
Return SetError(0, 0, \$avArray[\$iResult])
Case UBound(\$avArray, 0) = 2 And \$iDim = 1
Return SetError(0, 0, \$avArray[\$iResult][\$iSubItem])
Case UBound(\$avArray, 0) = 2 And \$iDim = 2
Return SetError(0, 0, \$avArray[\$iSubItem][\$iResult])
EndSelect
EndFunc   ;==>_Array2D_Max

Func _Array2D_Min(Const ByRef \$avArray, \$iCompNumeric = 0, \$iStart = 0, \$iEnd = -1, \$iDim = 1, \$iSubItem = 0);==AUTHOR = CEPHAS
If \$iCompNumeric = Default Then \$iCompNumeric = 0
If \$iStart = Default Then \$iStart = 0
If \$iEnd = Default Then \$iEnd = -1
If \$iDim = Default Then \$iDim = 1
If \$iSubItem = Default Then \$iSubItem = 0

Local \$iResult = _Array2D_MinIndex(\$avArray, \$iCompNumeric, \$iStart, \$iEnd, \$iDim, \$iSubItem)
If @error Then Return SetError(@error, 0, "")
Select
Case UBound(\$avArray, 0) = 1
Return SetError(0, 0, \$avArray[\$iResult])
Case UBound(\$avArray, 0) = 2 And \$iDim = 1
Return SetError(0, 0, \$avArray[\$iResult][\$iSubItem])
Case UBound(\$avArray, 0) = 2 And \$iDim = 2
Return SetError(0, 0, \$avArray[\$iSubItem][\$iResult])
EndSelect
EndFunc   ;==>_Array2D_Min

Func _Array2D_MaxIndex(Const ByRef \$avArray, \$iCompNumeric = 0, \$iStart = 0, \$iEnd = -1, \$iDim = 1, \$iSubItem = 0);==AUTHOR = CEPHAS
If \$iCompNumeric = Default Then \$iCompNumeric = 0
If \$iStart = Default Then \$iStart = 0
If \$iEnd = Default Then \$iEnd = -1
If \$iDim = Default Then \$iDim = 1
If \$iSubItem = Default Then \$iSubItem = 0

If Not IsArray(\$avArray) Then Return SetError(1, 0, -1)
If UBound(\$avArray, 0) <> 1 And UBound(\$avArray, 0) <> 2 Then Return SetError(2, 0, -1)

If UBound(\$avArray, 0) = 1 Then \$iDim = 1
If \$iDim <> 1 And \$iDim <> 2 Then Return SetError(3, 0, -1)
Local \$iUbound = UBound(\$avArray, \$iDim) - 1
; Bounds checking
If \$iEnd < 0 Or \$iEnd > \$iUbound Then \$iEnd = \$iUbound
If \$iStart < 0 Then \$iStart = 0
If \$iStart > \$iEnd Then Return SetError(4, 0, -1)

Local \$iMaxIndex = \$iStart, \$i
; Search
Select
Case UBound(\$avArray, 0) = 1
If \$iCompNumeric Then
For \$i = \$iStart To \$iEnd
If Number(\$avArray[\$iMaxIndex]) < Number(\$avArray[\$i]) Then \$iMaxIndex = \$i
Next
Else
For \$i = \$iStart To \$iEnd
If \$avArray[\$iMaxIndex] < \$avArray[\$i] Then \$iMaxIndex = \$i
Next
EndIf
Case UBound(\$avArray, 0) = 2 And \$iDim = 1
If \$iSubItem < 0 Or \$iSubItem > UBound(\$avArray, 2) - 1 Then SetError(5, 0, -1)
If \$iCompNumeric Then
For \$i = \$iStart To \$iEnd
If Number(\$avArray[\$iMaxIndex][\$iSubItem]) < Number(\$avArray[\$i][\$iSubItem]) Then \$iMaxIndex = \$i
Next
Else
For \$i = \$iStart To \$iEnd
If \$avArray[\$iMaxIndex][\$iSubItem] < \$avArray[\$i][\$iSubItem] Then \$iMaxIndex = \$i
Next
EndIf
Case UBound(\$avArray, 0) = 2 And \$iDim = 2
If \$iSubItem < 0 Or \$iSubItem > UBound(\$avArray) - 1 Then SetError(5, 0, -1)
If \$iCompNumeric Then
For \$i = \$iStart To \$iEnd
If Number(\$avArray[\$iSubItem][\$iMaxIndex]) < Number(\$avArray[\$iSubItem][\$i]) Then \$iMaxIndex = \$i
Next
Else
For \$i = \$iStart To \$iEnd
If \$avArray[\$iSubItem][\$iMaxIndex] < \$avArray[\$iSubItem][\$i] Then \$iMaxIndex = \$i
Next
EndIf
EndSelect

Return SetError(0, 0, \$iMaxIndex)
EndFunc   ;==>_Array2D_MaxIndex

Func _Array2D_Swap(ByRef \$vItem1, ByRef \$vItem2);== AUTHOR - DAVID NUTALL
Local \$vTmp = \$vItem1
\$vItem1 = \$vItem2
\$vItem2 = \$vTmp
EndFunc   ;==>_Array2D_Swap

Func __Max(\$nNum1, \$nNum2)
If \$nNum1 > \$nNum2 Then Return \$nNum1
Return \$nNum2
EndFunc   ;==>__Max

Func __Min(\$nNum1, \$nNum2)
If \$nNum1 < \$nNum2 Then Return \$nNum1
Return \$nNum2
EndFunc   ;==>__Min

Func _Array2D_MinIndex(Const ByRef \$avArray, \$iCompNumeric = 0, \$iStart = 0, \$iEnd = -1, \$iDim = 1, \$iSubItem = 0);==AUTHOR = CEPHAS
If \$iCompNumeric = Default Then \$iCompNumeric = 0
If \$iStart = Default Then \$iStart = 0
If \$iEnd = Default Then \$iEnd = -1
If \$iDim = Default Then \$iDim = 1
If \$iSubItem = Default Then \$iSubItem = 0

If Not IsArray(\$avArray) Then Return SetError(1, 0, -1)
If UBound(\$avArray, 0) <> 1 And UBound(\$avArray, 0) <> 2 Then Return SetError(2, 0, -1)

If UBound(\$avArray, 0) = 1 Then \$iDim = 1
If \$iDim <> 1 And \$iDim <> 2 Then Return SetError(3, 0, -1)
Local \$iUbound = UBound(\$avArray, \$iDim) - 1
; Bounds checking
If \$iEnd < 0 Or \$iEnd > \$iUbound Then \$iEnd = \$iUbound
If \$iStart < 0 Then \$iStart = 0
If \$iStart > \$iEnd Then Return SetError(4, 0, -1)

Local \$iMinIndex = \$iStart, \$i
; Search
Select
Case UBound(\$avArray, 0) = 1
If \$iCompNumeric Then
For \$i = \$iStart To \$iEnd
If Number(\$avArray[\$iMinIndex]) > Number(\$avArray[\$i]) Then \$iMinIndex = \$i
Next
Else
For \$i = \$iStart To \$iEnd
If \$avArray[\$iMinIndex] > \$avArray[\$i] Then \$iMinIndex = \$i
Next
EndIf
Case UBound(\$avArray, 0) = 2 And \$iDim = 1
If \$iSubItem < 0 Or \$iSubItem > UBound(\$avArray, 2) - 1 Then SetError(5, 0, -1)
If \$iCompNumeric Then
For \$i = \$iStart To \$iEnd
If Number(\$avArray[\$iMinIndex][\$iSubItem]) > Number(\$avArray[\$i][\$iSubItem]) Then \$iMinIndex = \$i
Next
Else
For \$i = \$iStart To \$iEnd
If \$avArray[\$iMinIndex][\$iSubItem] > \$avArray[\$i][\$iSubItem] Then \$iMinIndex = \$i
Next
EndIf
Case UBound(\$avArray, 0) = 2 And \$iDim = 2
If \$iSubItem < 0 Or \$iSubItem > UBound(\$avArray) - 1 Then SetError(5, 0, -1)
If \$iCompNumeric Then
For \$i = \$iStart To \$iEnd
If Number(\$avArray[\$iSubItem][\$iMinIndex]) > Number(\$avArray[\$iSubItem][\$i]) Then \$iMinIndex = \$i
Next
Else
For \$i = \$iStart To \$iEnd
If \$avArray[\$iSubItem][\$iMinIndex] > \$avArray[\$iSubItem][\$i] Then \$iMinIndex = \$i
Next
EndIf
EndSelect

Return SetError(0, 0, \$iMinIndex)
EndFunc   ;==>_Array2D_MinIndex```

OK, so the dictionary files are too big to attach :S

Here is a .zip file, CONTENTS:

```Wordlist.txt ;SIZE=2259KB
Numlist.txt ;SIZE=3018KB
AnagramSOLVER.au3 ;SIZE=7KB
LibraryBUILDER.au3 ;SIZE=4KB```

http://FastFreeFileHosting.com/file/35445/Anagram-zip.html

If you want to download the SOWPODS or TWL06 dictionaries, you can do so here:

http://www.isc.ro/en/commands/lists.html ;You want the whole dictionary not the 2/3/4 letter dictionaries

Although they will have pretty much all the words you would need in a dictionary, i am not sure how up-to-date these are. If you do download one of these dictionaries, make sure to run it in my DICTIONARY BUILDER.

Edited by furrycow

Instant Lockerz Invite - www.instantlockerzinvite.co.uk

##### Share on other sites

Looks pretty cool. Thanks.

Is this free to use -err- in another project? I made one like this (without the numeric part). So, it took near a minute to do the work. Your method is much better.

[Not using this account any more. Using "iShafayet" instead]

##### Share on other sites

Is this free to use -err- in another project? I made one like this (without the numeric part). So, it took near a minute to do the work. Your method is much better.

Thanks, although i can't really take any credit for this method as i just stumbled across it on the internet. But yes, feel free to use it as you wish!

Instant Lockerz Invite - www.instantlockerzinvite.co.uk

##### Share on other sites

Hah, very clever! I'm going to have a good play with this!

##### Share on other sites

WOW!

That is a fantastic find and a great translation into AutoIt.

Five stars from me.

I cannot believe how fast it is.

Do you know if it would be difficult to modify it to produce a combination of words from a word or short phrase?

i.e. given input something like:

Calamity: It comes back with (among other combinations) = ay calm it

The earthquakes: It comes back with (among other combinations) = That queer shake

Debit card: It comes back with (among other combinations) = Bad credit

Slot machines: It comes back with (among other combinations) = Cash lost in â€˜em

School master: It comes back with (among other combinations) = The classroom

Dormitory: It comes back with (among other combinations) = Dirty room

Desperation: It comes back with (among other combinations) = A rope ends it

The Morse code: It comes back with (among other combinations) = Here come dots

and here are some more:

A decimal point: Iâ€™m a dot in place

Fir cones: Conifers

The eyes: They see

Conversation: Voices rant on

Election results: Lies â€“ letâ€™s recount

Schoolmaster: The classroom

Listen: Silent

The Country Side: No City Dust Here

Evangelist: Evilâ€™s Agent

Astronomers: No more stars

The eyes: They see

The Cockroach: Cook, Catch Her

Desperation: A Rope Ends It

The Morse Code: Here Come Dots

Slot Machines: Cash Lost inâ€™em

Conversation: Voices Rant On

Funeral: Real Fun

The Hilton: Hint: Hotel

Vacation Times: Iâ€™m Not as Active

The Detectives: Detect Thieves

Semolina: Is No Meal

Christmas tree: Search, Set, Trim

Presbyterian: Best In Prayer

Statue of Liberty: Built to Stay Free

Source of the above funny anagrams.

I'm afraid I wouldn't even begin to know where to start to do such a program, but it sure would be fun to be able to such anagrams.

Once again Thank you for sharing.

DeMo.

Quote of the week:"BASIC programmers never die, they GOSUB and don't RETURN." -- UnknownWisdom of the ages:

• I'd be unstoppable... if not for law enforcement and physics.
• Marriage, the number 1 cause of divorce.
• Don't steal... the government hates competition.
• Irish Government Motto: Weâ€™ve got what it takes to take what youâ€™ve got.
• Birthdays are good for you. Statistics show that the people who have the most live the longest.
• Failure is not an option. It comes bundled with your Microsoft product.-- Ferenc Mantfeld
• If you learn from your mistakes, then why ain't I a genius?! -- Anonymous
• Remember, live every day as if it was your last day! one day you will be right.
• How is it one careless match can start a forest fire, but it takes a whole box to start a campfire?
• Sure my system is secure, it just locked up again.
• I haven't lost my mind; I have a tape back-up somewhere.  ~Author Unknown

##### Share on other sites

@furrycow

Hi, in my last post I asked...

...

Do you know if it would be difficult to modify it to produce a combination of words from a word or short phrase?

i.e. given input something like:

Calamity: It comes back with (among other combinations) = ay calm it

The earthquakes: It comes back with (among other combinations) = That queer shake

...

Well I guess that was a mistake in my wording, what I really meant was (Due to my brainfreeze) "Is there any way you could modify your code to produce a combination of words from a word or short phrase?"

i.e. given input something like:

Calamity: It comes back with (among other combinations) = ay calm it

The earthquakes: It comes back with (among other combinations) = That queer shake

(The rest as per last post.)

I have seen such an app in on-line web page a long time ago, but thought when I saw your app that this would be very useful/FUN to be able to do in AutoIt.

I'm sorry, I know what I am asking is 'almost' rent-a-coder but I'm hoping it is an easy modification for you (or one of the other wizards here) to do.

I would not even have a clue how to start to make the necessary changes/additions.

If it is way too much to ask then please accept my apologies and thank you once again for sharing.

DeMo.

Quote of the week:"BASIC programmers never die, they GOSUB and don't RETURN." -- UnknownWisdom of the ages:

• I'd be unstoppable... if not for law enforcement and physics.
• Marriage, the number 1 cause of divorce.
• Don't steal... the government hates competition.
• Irish Government Motto: Weâ€™ve got what it takes to take what youâ€™ve got.
• Birthdays are good for you. Statistics show that the people who have the most live the longest.
• Failure is not an option. It comes bundled with your Microsoft product.-- Ferenc Mantfeld
• If you learn from your mistakes, then why ain't I a genius?! -- Anonymous
• Remember, live every day as if it was your last day! one day you will be right.
• How is it one careless match can start a forest fire, but it takes a whole box to start a campfire?
• Sure my system is secure, it just locked up again.
• I haven't lost my mind; I have a tape back-up somewhere.  ~Author Unknown

##### Share on other sites

You ought to do something with that NumAssign() paragraph. It has to be painfully slow, and would probably be more evident in the Builder program.

Maybe a predefined array like:

```Global \$Ascii2Prime[123] = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, _ ; asc 0-47
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,1,1,1,1,1, _ ; asc 48-95
1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101] ; asc 96-122```

And then:

```Func _NumASSIGN(\$Letter)
\$Output *= \$Ascii2Prime[Asc(\$Letter)]
EndFunc   ;==>_NumASSIGN```

would be useful.

## Create an account

Register a new account