andreba
asked on
Word Generator
Preparing some tests to be delivered as "training" (who knows what will they come out with next..)
Need a snippet that will give me combinations of characters (0-9, a-z) given a particular constraint (ex: How many pairs of 2 characters can be combined into a 4-character word?)
Now, my starting point is probably the most troubling part: creating a DB of all character combinations upto 5 characters.. Once I built the DB, I'll easily surf through with SQL or some extra code..
How can I get that done?
Example of output:
0
1
2
...
9
a
b
c
...
00
01
02
...
0a
0b
0c
...
zzzzz
Thanks!
:-)
Need a snippet that will give me combinations of characters (0-9, a-z) given a particular constraint (ex: How many pairs of 2 characters can be combined into a 4-character word?)
Now, my starting point is probably the most troubling part: creating a DB of all character combinations upto 5 characters.. Once I built the DB, I'll easily surf through with SQL or some extra code..
How can I get that done?
Example of output:
0
1
2
...
9
a
b
c
...
00
01
02
...
0a
0b
0c
...
zzzzz
Thanks!
:-)
this may be the rough algo....
for j=0 to 4
for i='0' to 'z'
store "value in i" & "j digit previous elements in the database"
next i
next j
for j=0 to 4
for i='0' to 'z'
store "value in i" & "j digit previous elements in the database"
next i
next j
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
that code is a rough one... there are some memory leaks in that.... i think u can solve that.... if u want me to solve , leave a message back....
regards
Rajesh
regards
Rajesh
ASKER
Thanks Raj, anything in VB.NET?
:-)
:-)
ASKER
lol..
I mean.. Would those two initial snippets do the trick?
:-)
I mean.. Would those two initial snippets do the trick?
:-)
u can simply convert this in to vb.net code...
i hope there won't be much problem in converting
i hope there won't be much problem in converting
have u run the c code?....
convert that to vb.net ... then u will go smooth afterwards
there won't be a problem
convert that to vb.net ... then u will go smooth afterwards
there won't be a problem
ASKER
how to convert? I'm not familiar with C++..
:-)
:-)
Well here's a different way to generate a set of codes:
Public Class CodeGenerator
Public CharacterSet As String = "abcd" ' Test using this one so you can see... then make it bigger when needed
Sub Generate(ByVal Length As Integer, Optional ByVal PrecedingCode As String = "")
Dim currentChar As Char
Dim currentCode As String
For Each currentChar In CharacterSet.ToCharArray
currentCode = PrecedingCode & currentChar
RaiseEvent CodeCreated(currentCode)
If Length > 1 Then Generate(Length - 1, currentCode)
Next
End Sub
Public Event CodeCreated(ByVal CodeWord As String)
End Class
====================
then create a form and put a button on it to test:
Dim WithEvents CodeMaker As New CodeGenerator()
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
CodeMaker.Generate(3)
End Sub
Public Sub CodeMade(ByVal NewCode As String) Handles CodeMaker.CodeCreated
MsgBox(NewCode)
End Sub
========================
The order it generates them might not be as nice... but it's quick n easy... anyway, I'm gonna be out of a few hours so can't answer about it... good luck
Public Class CodeGenerator
Public CharacterSet As String = "abcd" ' Test using this one so you can see... then make it bigger when needed
Sub Generate(ByVal Length As Integer, Optional ByVal PrecedingCode As String = "")
Dim currentChar As Char
Dim currentCode As String
For Each currentChar In CharacterSet.ToCharArray
currentCode = PrecedingCode & currentChar
RaiseEvent CodeCreated(currentCode)
If Length > 1 Then Generate(Length - 1, currentCode)
Next
End Sub
Public Event CodeCreated(ByVal CodeWord As String)
End Class
====================
then create a form and put a button on it to test:
Dim WithEvents CodeMaker As New CodeGenerator()
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
CodeMaker.Generate(3)
End Sub
Public Sub CodeMade(ByVal NewCode As String) Handles CodeMaker.CodeCreated
MsgBox(NewCode)
End Sub
========================
The order it generates them might not be as nice... but it's quick n easy... anyway, I'm gonna be out of a few hours so can't answer about it... good luck
ya S-Twilley is correct... he implemented in vb.net....his code is following the second snippet i posted....
regards
Rajesh
regards
Rajesh
ASKER
hey raj, can you rearrange S-Twilley's code to sort them in the order I posted originally? Will it go through all the permutations as intended?
I'll only be able to test tomorrow..
Thanks all!
:-)
I'll only be able to test tomorrow..
Thanks all!
:-)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Brilliant, as usual..
Thanks so much!
:-)
Thanks so much!
:-)
ASKER
One thing though S-Twilley. If I use
Private Sub CodeCaught(ByVal NewCode As String) Handles x.CodeGenerated
lbl1.text=NewCode
End Sub
It NEVER gets displayed! Only if I add the "MsgBox(NewCode)" line..
Why and how to sort that out?
Thanks!
:-)
Private Sub CodeCaught(ByVal NewCode As String) Handles x.CodeGenerated
lbl1.text=NewCode
End Sub
It NEVER gets displayed! Only if I add the "MsgBox(NewCode)" line..
Why and how to sort that out?
Thanks!
:-)
Doing it that way will only display the last item... and also remember that the code generator is running in the same threat so the form is locked till it is complete (that can be fixed).
As for another reason ... this event is raised for EVERY code that is made, it's not just one event for all. Just by using lbl1.text =NewCode, you are setting it to a newcode, but as soon as the event is fired again, it is overwritten.
If you want to display all the codes... you could use a listbox, or a multiline textbox... but just be careful when generating large lists of codes!
As for another reason ... this event is raised for EVERY code that is made, it's not just one event for all. Just by using lbl1.text =NewCode, you are setting it to a newcode, but as soon as the event is fired again, it is overwritten.
If you want to display all the codes... you could use a listbox, or a multiline textbox... but just be careful when generating large lists of codes!
ASKER
How can it be fixed? I need to ensure that, after each code, I can DO something with the code, before I move on to the next one..
:-)
:-)
The idea of that event is so you can use each code as you see fit... while you're within that method (CodeCaught)... the program won't be moving on until you exit the sub ... so within this sub/method... you could append it to a list... or put it into a database or something...
... the code generator can be modified to generate ONLY ONE code at a time... but I figure as the number of codes increase... doing one code at a time and pausing for user input would take a while.
What exactly do you want to do with each code before moving onto the next?
... the code generator can be modified to generate ONLY ONE code at a time... but I figure as the number of codes increase... doing one code at a time and pausing for user input would take a while.
What exactly do you want to do with each code before moving onto the next?
ASKER
It would be great if I could 'see' what code is currently being generated (by having it on a label or something) so that I can roughly estimate how much is left to be done..
As it is, I can actually use it already.. Now I just want to be able to 'monitor'.. User input is not necessary, as you correctly stated..
I'm guessing it has to do with the form locking, which you said can be fixed..
Thanks again!
:-)
As it is, I can actually use it already.. Now I just want to be able to 'monitor'.. User input is not necessary, as you correctly stated..
I'm guessing it has to do with the form locking, which you said can be fixed..
Thanks again!
:-)
If you give me a moment to work out the math... I'll edit the code generator class so it runs in its own thread and also passes an extra value to the event handler giving a percent done.
ASKER
You're the sweetest!
Is it out of place to ask for a way to 'break' the process of code generation halfway?
I'll open another question if needed..
I wished I could do this in VB6.. I found it so much easier than .net..
Thanks!
:-)
Is it out of place to ask for a way to 'break' the process of code generation halfway?
I'll open another question if needed..
I wished I could do this in VB6.. I found it so much easier than .net..
Thanks!
:-)
You want to be able to force the code generator to stop mid-process? If that's the case it's very easy to do (and no need for a seperate post).... only question about doing that is would you just restart the code generation from the beginning the next time around... or would expect it to resume?
ASKER
From beginning should do.. At least at this stage.. Not sure actually, I haven't looked too far ahead on HOW MUCH will they use this 'training' and whether it will grow or it's a one time thing and then archive..
lol, I was panicking for not being able of putting it together, and now I HAVE TOO MANY OPTIONS! This is great!
:-)
lol, I was panicking for not being able of putting it together, and now I HAVE TOO MANY OPTIONS! This is great!
:-)
I've put in code to pause and resume ... although I've not tested that part:
========================== ========== ========== ====
Public Class SimpleCodeGenerator
Private _charSet As String = ""
Private _codeLength As Integer = 0
Private _inProcess As Boolean = False
Private _pauseFlag As Boolean = False
Private _currentCodeNumber As Integer = 0
Private _thisThread As Threading.Thread
Private _charPos() As Integer
Private _currentPos, _currentPos2, _carryPos As Integer
Public ReadOnly Property CodeLength()
Get
Return _codeLength
End Get
End Property
Public ReadOnly Property CharacterSet()
Get
Return _charSet
End Get
End Property
Public ReadOnly Property Processing()
Get
Return _inProcess
End Get
End Property
Public Sub Start(ByVal NewCharacterSet As String, ByVal NewCodeLength As Integer, Optional ByVal ForceRestart As Boolean = False)
If _inProcess And Not ForceRestart Then
RaiseEvent Error_InProcess(Me)
Exit Sub
End If
_pauseFlag = True
If Not _thisThread Is Nothing Then
Try
_thisThread.Abort()
Catch
End Try
End If
_currentCodeNumber = 1
_charSet = NewCharacterSet
_codeLength = NewCodeLength
_pauseFlag = False
ReDim _charPos(_codeLength)
For _currentPos = 0 To _codeLength - 1
_charPos(_currentPos) = -1
Next
_thisThread = New Threading.Thread(AddressOf Generate)
_thisThread.Start()
End Sub
Private Sub Generate()
_inProcess = True
Dim Forever As Boolean = True
While Forever
If _pauseFlag Then Exit Sub
Dim currString As String = ""
For _currentPos2 = 0 To _codeLength - 1
If _charPos(_currentPos2) >= 0 Then
currString &= _charSet.Substring(_charPo s(_current Pos2), 1)
End If
Next
RaiseEvent CodeGenerated(Me, currString, _currentCodeNumber)
_currentCodeNumber += 1
Dim carryInt As Integer = 1
For _carryPos = _codeLength - 1 To 0 Step -1
If carryInt = 0 Then Exit For
_charPos(_carryPos) += 1
If _charPos(_carryPos) > _charSet.Length - 1 Then
_charPos(_carryPos) = 0
carryInt = 1
If _carryPos = 0 Then Exit While
Else
carryInt = 0
End If
Next
End While
_inProcess = False
End Sub
Public Sub Quit()
If Not _thisThread Is Nothing Then
Try
_thisThread.Abort()
Catch
End Try
End If
_inProcess = False
_pauseFlag = False
End Sub
Public Sub Pause()
If _inProcess Then
_pauseFlag = True
End If
End Sub
Public Sub Continue()
If _inProcess Then
_pauseFlag = False
If Not _thisThread Is Nothing Then
Try
_thisThread.Abort()
Catch
End Try
End If
_thisThread = New Threading.Thread(AddressOf Generate)
_thisThread.Start()
End If
End Sub
Public Function GetComplexity()
Dim prevTotal As Integer = 1
Dim currTotal As Integer
Dim grandTotal As Integer = 1
Dim currentLevel As Integer
For currentLevel = 1 To _codeLength
currTotal = _charSet.Length * prevTotal
grandTotal += currTotal
prevTotal = currTotal
Next
Return grandTotal
End Function
Public Event CodeGenerated(ByVal Sender As Object, ByVal CodeString As String, ByVal CodeNumber As Integer)
Public Event Error_InProcess(ByVal Sender As Object)
End Class
========================== ======
Dim WithEvents x As New SimpleCodeGenerator()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
x.Start("ABCD", 3)
End Sub
Private Sub CodeCaught(ByVal sender As Object, ByVal newcode As String, ByVal codenumber As Integer) Handles x.CodeGenerated
Dim percent As Single
Dim thisGenerator As SimpleCodeGenerator = sender
percent = 100 * codenumber / thisGenerator.GetComplexit y
MsgBox("New Code: '" & newcode & "'" & vbCrLf & _
"Code Number: " & codenumber & vbCrLf & _
"Total Codes: " & thisGenerator.GetComplexit y & vbCrLf & _
"Percent: " & Format(percent, "0.0"))
End Sub
==========================
The function GetComplexity... im not happy with that, my head isn't working now to get a single line equation to work out the number... it works i think anyway. Let me know of any bugs, ya can reach me on the email on profile, but no new project questions there, only about this one :P
==========================
Public Class SimpleCodeGenerator
Private _charSet As String = ""
Private _codeLength As Integer = 0
Private _inProcess As Boolean = False
Private _pauseFlag As Boolean = False
Private _currentCodeNumber As Integer = 0
Private _thisThread As Threading.Thread
Private _charPos() As Integer
Private _currentPos, _currentPos2, _carryPos As Integer
Public ReadOnly Property CodeLength()
Get
Return _codeLength
End Get
End Property
Public ReadOnly Property CharacterSet()
Get
Return _charSet
End Get
End Property
Public ReadOnly Property Processing()
Get
Return _inProcess
End Get
End Property
Public Sub Start(ByVal NewCharacterSet As String, ByVal NewCodeLength As Integer, Optional ByVal ForceRestart As Boolean = False)
If _inProcess And Not ForceRestart Then
RaiseEvent Error_InProcess(Me)
Exit Sub
End If
_pauseFlag = True
If Not _thisThread Is Nothing Then
Try
_thisThread.Abort()
Catch
End Try
End If
_currentCodeNumber = 1
_charSet = NewCharacterSet
_codeLength = NewCodeLength
_pauseFlag = False
ReDim _charPos(_codeLength)
For _currentPos = 0 To _codeLength - 1
_charPos(_currentPos) = -1
Next
_thisThread = New Threading.Thread(AddressOf
_thisThread.Start()
End Sub
Private Sub Generate()
_inProcess = True
Dim Forever As Boolean = True
While Forever
If _pauseFlag Then Exit Sub
Dim currString As String = ""
For _currentPos2 = 0 To _codeLength - 1
If _charPos(_currentPos2) >= 0 Then
currString &= _charSet.Substring(_charPo
End If
Next
RaiseEvent CodeGenerated(Me, currString, _currentCodeNumber)
_currentCodeNumber += 1
Dim carryInt As Integer = 1
For _carryPos = _codeLength - 1 To 0 Step -1
If carryInt = 0 Then Exit For
_charPos(_carryPos) += 1
If _charPos(_carryPos) > _charSet.Length - 1 Then
_charPos(_carryPos) = 0
carryInt = 1
If _carryPos = 0 Then Exit While
Else
carryInt = 0
End If
Next
End While
_inProcess = False
End Sub
Public Sub Quit()
If Not _thisThread Is Nothing Then
Try
_thisThread.Abort()
Catch
End Try
End If
_inProcess = False
_pauseFlag = False
End Sub
Public Sub Pause()
If _inProcess Then
_pauseFlag = True
End If
End Sub
Public Sub Continue()
If _inProcess Then
_pauseFlag = False
If Not _thisThread Is Nothing Then
Try
_thisThread.Abort()
Catch
End Try
End If
_thisThread = New Threading.Thread(AddressOf
_thisThread.Start()
End If
End Sub
Public Function GetComplexity()
Dim prevTotal As Integer = 1
Dim currTotal As Integer
Dim grandTotal As Integer = 1
Dim currentLevel As Integer
For currentLevel = 1 To _codeLength
currTotal = _charSet.Length * prevTotal
grandTotal += currTotal
prevTotal = currTotal
Next
Return grandTotal
End Function
Public Event CodeGenerated(ByVal Sender As Object, ByVal CodeString As String, ByVal CodeNumber As Integer)
Public Event Error_InProcess(ByVal Sender As Object)
End Class
==========================
Dim WithEvents x As New SimpleCodeGenerator()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
x.Start("ABCD", 3)
End Sub
Private Sub CodeCaught(ByVal sender As Object, ByVal newcode As String, ByVal codenumber As Integer) Handles x.CodeGenerated
Dim percent As Single
Dim thisGenerator As SimpleCodeGenerator = sender
percent = 100 * codenumber / thisGenerator.GetComplexit
MsgBox("New Code: '" & newcode & "'" & vbCrLf & _
"Code Number: " & codenumber & vbCrLf & _
"Total Codes: " & thisGenerator.GetComplexit
"Percent: " & Format(percent, "0.0"))
End Sub
==========================
The function GetComplexity... im not happy with that, my head isn't working now to get a single line equation to work out the number... it works i think anyway. Let me know of any bugs, ya can reach me on the email on profile, but no new project questions there, only about this one :P
ASKER
Crazily amazing.. How come SO MUCH CODE is required for such a simple task?? We'd think VB could be smarter than that..
Thanks a bizillion S-Twilley, i'll be testing it tomorrow, but even if there are bugs, I'll open another question for it.. You really love the job!
:-)
Thanks a bizillion S-Twilley, i'll be testing it tomorrow, but even if there are bugs, I'll open another question for it.. You really love the job!
:-)
Well there might be a shorter way of doing it... that way is long because im trying to prevent using nested calls to the same function (which can use up a lot of memory).... it's also spaced out and such so it's clear to read.
It can probably be shortened but I think while it's still being tested you should keep it like that.
Anyway, good luck with it
PS... not so much that I love the job, more like I'd rather be doing this than my own project
It can probably be shortened but I think while it's still being tested you should keep it like that.
Anyway, good luck with it
PS... not so much that I love the job, more like I'd rather be doing this than my own project
ASKER
Your latest program STOPS after every code generated to show me a MSGBOX! That's gonna take EONS..
Like I said, the previous one is workable.. I'm trying to figure out how to, maybe, use a Timer to that I can update my labels, instead of the While Forever loop..
Will keep you posted..
Thanks again!
:-)
Like I said, the previous one is workable.. I'm trying to figure out how to, maybe, use a Timer to that I can update my labels, instead of the While Forever loop..
Will keep you posted..
Thanks again!
:-)
only used a msgbox in it to show you the updated code and how you can calculate the %age.
u should be able to change the code to something like:
Private Sub CodeCaught(ByVal sender As Object, ByVal newcode As String, ByVal codenumber As Integer) Handles x.CodeGenerated
Dim percent As Single
Dim sPercent As String
Dim thisGenerator As SimpleCodeGenerator = sender
percent = 100 * codenumber / thisGenerator.GetComplexit y
sPercent = Format(percent, "0.0")
If sPercent <> lblPercent.Text Then
lblPercent.Text = sPercent
lblPercent.Refresh
End If
lblLastCode.Text = newcode 'This will probably be going so fast that you wont see it properly
' one options is that when the code is > 4 characters long, or 3... that you ignore
' the last 3 characters and put in *** so it's not constantly changing...
'then you'd see what kinda place you are with the code e.g. ABA***
lblLastCode.Refresh
End Sub
u should be able to change the code to something like:
Private Sub CodeCaught(ByVal sender As Object, ByVal newcode As String, ByVal codenumber As Integer) Handles x.CodeGenerated
Dim percent As Single
Dim sPercent As String
Dim thisGenerator As SimpleCodeGenerator = sender
percent = 100 * codenumber / thisGenerator.GetComplexit
sPercent = Format(percent, "0.0")
If sPercent <> lblPercent.Text Then
lblPercent.Text = sPercent
lblPercent.Refresh
End If
lblLastCode.Text = newcode 'This will probably be going so fast that you wont see it properly
' one options is that when the code is > 4 characters long, or 3... that you ignore
' the last 3 characters and put in *** so it's not constantly changing...
'then you'd see what kinda place you are with the code e.g. ABA***
lblLastCode.Refresh
End Sub
for i='0' to 'z'
store "value in i" & "one digit previous elements in the database"
next i
for i='0' to 'z'
store "value in i" & "two digit previous elements in the database"
next i
for i='0' to 'z'
store "value in i" & "three digit previous elements in the database"
next i
for i='0' to 'z'
store "value in i" & "four digit previous elements in the database"
next i
--------------------------
this is a first level of algo...
u can also make this simple by making one more loop