Link to home
Start Free TrialLog in
Avatar of andreba
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!

:-)

Avatar of r_a_j_e_s_h
r_a_j_e_s_h

store 0 to z

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
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



SOLUTION
Avatar of r_a_j_e_s_h
r_a_j_e_s_h

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
Avatar of andreba

ASKER

Thanks Raj, anything in VB.NET?

:-)
Avatar of andreba

ASKER

lol..
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
have u run the c code?....

convert that to vb.net ... then u will go smooth afterwards


there won't be a problem



Avatar of andreba

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
ya S-Twilley  is correct... he implemented in vb.net....his code is following the second snippet i posted....


regards
Rajesh
Avatar of andreba

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!

:-)
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of andreba

ASKER

Brilliant, as usual..

Thanks so much!

:-)
Avatar of andreba

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!

:-)
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!

Avatar of andreba

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?
Avatar of andreba

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!

:-)
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.
Avatar of andreba

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!

:-)
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?
Avatar of andreba

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!

:-)
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(_charPos(_currentPos2), 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.GetComplexity
        MsgBox("New Code:    '" & newcode & "'" & vbCrLf & _
               "Code Number: " & codenumber & vbCrLf & _
               "Total Codes: " & thisGenerator.GetComplexity & 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
Avatar of andreba

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!

:-)
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
Avatar of andreba

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!

:-)  
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.GetComplexity
        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