I need to count by ascii characters. Seems tricky!

Hey guys, I'm doing an expirement and I need to basically "count" but using a set of ascii characters. I'm having a heck of time. And using VB.NET Express.
For example, in Decimal, you count 1,2,3...8,9,10. As you know, once your first character reaches 9, a new character is added, 0, to the left, and then you start over counting the 1st character such as 10,11,12...18,19,20. Each time the rightmost character reaches 9, the next one over goes up one, and if another char doesn't exists, it is created. Okay, I need to do this but instead of doing it with numbers 0 - 9, I need to do it with 93 ascii characters! Ranging from chr(33) to chr(126), and all inbetween.
So each column cycles from "!"(chr33) to numbers to capitol letters to lowercase to brackets and everything. Up until the last char which is "~"(chr126).
So as the system counts, each time it goes from ! to ~, a new char is added to the left, which starts to count up also with each cycle. Then a 3rd char is added, and so on. Each new sequence is printed on its own line in a text box. When the textbox fills with about 10,000,000 characters or so, it is written to a standalone text file. Actually, it will fit as many lines as I can get into a text file about 10mb in size. When the file is created, the text box is cleared and it keeps going with a new file, each file having a dynamicly created name to keep track of it.
I hope this is making sense!
The plot thickens though. I don't need to start with one digit, or char, this is going to START with 15 digits, all ! because this is the first in the sqence, chr(33). The number will grow continually in digits until it reaches 56 chars in length. So it goes from:
!!!!!!!!!!!!!!!
to
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Okay, don't ask what this is for, has to do with running a server of sorts. I tried for a couple hours to figure out a loop or routine to cycle the numbers, trying to use arrays and counters and so on. I couldn't find a suitable solution that doesn't involve hugely nested IF statements and FOR loops.
I mean, can't I just declare a variable that ranges from 33 to 126. Then just say VAR = VAR + 1. And then echo chr(VAR)
Surely there is some fancy way to count ascii chars like this And I don't care if it counts by hex or decimal or binary, as long as I can echo out each new sequence in its ascii form.
And yes, I know this is a huge number! There are 93 ascii characters per column. With an eventual 56 digits, this is 93 to the power of 56 of combinations. I know that will be a lot of processing and a lot of time!
The trick is that I really have no idea how to create a loop like this. And possibly even more important, to be able to stop and start this loop, so it doesn't just continue on until infinity.
And if it isn't good enough already, I'd like to be able to "start" counting, at any sequence I choose. So if I input, for example, the string "#$(U#)(EDdkjd(#U()#U", it will beging counting again with the rightmost character, and so on.
Does anybody have any idea what I'm talking about And further, could anybody give me some pointers on creating such a loop And being able to stop and start the loop quickly, and start counting from any string
Thanks a billion if you get this one!



Answer this question

I need to count by ascii characters. Seems tricky!

  • MiLambert

    Asc and AscW both return an Integer (Int32) and Chr and ChrW both take an Integer as an argument.  Integer is the "standard" numerical type which is why I have always used it when converting Chars to their Unicode (or ASCII) values.  Because arithmetic was difficult with unsigned types in previous versions of VB.NET they were best avoided.  Now that VB.NET properly supports unsigned types I guess UShort would be the most appropriate type because, as you say, a Char is implemented as an unsigned 16-bit value.

    As for Const, it is the standard way to declare a constant value.  A constant and a ReadOnly variable are similar but they are not the same thing.  A Const must be assigned a value when it is declared, it cannot be assigned a value anywhere else and the value assigned must be known at compile time.  The only restriction on a ReadOnly variable is that it can only be assigned when it is declared or in a class constructor.

  • ingsgr01

    Thank you

    Chr and Asc
    Microsoft.VisualBasic.Strings.AscW uses a cast (no computation).
    AscW is compiled directly into this casts (at least with the architect version).
    Microsoft.VisualBasic.Strings.Asc takes encoding into account.

    Int32 / UInt16 / UShort / Int64
    I agree on the Int32-arithmetic. To some extent. It goes towards making the code CLS-complient. The problem I have with Int32 is that I do most work on 64-bit computers, I try to shift my focus from the 32--bit way of thought and focus on the actual data size needed. I guess it is likely that this will put extra conversions in the final IL, but I don't care.
    I feel that UShort is a less descriptive way of saying UInt16. UShort is bound to VB, UInt16 is common for all of .NET (all though not CLS-complient).

    The actual IL
    "Convert.ToChar(AscW(s(digit)) + 1)"
    is equivalent to
    "Convert.ToChar(CType((s.Chars(digit) + ChrW(1)), Integer))"
    looks OK to me.

    Const
    The point with ReadOnly was that ZERO_CHAR and N_VALUE can be set different values without changing other parts of the code, possibly at run-time to. It is psychologically worse for me to change a Const in some old source than a ReadOnly. I have learned to use Const, even though I think it was missing in the first version of MS Basic I used (SV Microsoft Basic). The practical reason for using ReadOnly here is that I can, possibly in the constructor, read the prefered value from somewhere if I choose to build on this code. If I were to use Const, NaryNumberIncrementDigit() would take two parameters, not four.

    Good to have someone looking over my code, I learn much from that.
    Thank you



  • ykagoma

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim i As Integer
    Dim j As Integer
    Dim Number As String = ""
    For j = 33 To 126
    For i = 33 To 126
    Number = Number & Chr(i)
    Next
    If j > 33 Or j < 126 Then Number = Number & Chr(j) Else Number = Chr(j)
    Next
    RichTextBox1.Text = Number

    End Sub

    Much Ado About Nothing..... Base 94 Number System Using Ascii as Numbers.....


  • hyng

    Use Convert.ToInt32 and Convert.ToChar instead of Asc and Chr. Although it won't cause an issue, it also seems an odd choice to use ReadOnly variables instead of constants, i.e. Const.

  • DexIT

    Hey Vigilante... I've been looking at my solution in some degenerant cases.... It's not quite right.... Allthough the Concept of a number system of Base 94 with Ascii characters as numbers seems sound to me.... This Concept would make it somewhat of a Trivial Solution for many(All) number Systems..... I am doing something else and frankly lost interest in your Problem..... Maybe someone could correct and expand my code..... I would also check the other guys solution also for correctness..... I ain't much on recurssion... Every time I ever called myself I got a Busy Signal...... Sorry about the crummy small Font..... Cheers


  • Burbank Steve

    Hi.

    It will take about a googol years (no, I am not kidding).
    http://en.wikipedia.org/wiki/googol

    Hope this helps...



  • Bay Tran

    Hi

    Thank you for commenting.

    After running reflector on .Net 2.0, I agree with the functions being imperfect. If you want, you can replace the recursive function with

    <code>

    Private Sub NaryNumberIncrementDigit(ByRef s As System.Text.StringBuilder, ByVal zero_char As Char, ByVal n_value As UInt16, ByVal digit As Byte)

    Dim cLastDigitAsc As UInt32 = Convert.ToUInt16(zero_char) + n_value - 1

    If cLastDigitAsc > 65535 Then

    Throw New Exception("Unable to represent n-ary number system in string, decrease zero_char or n_value")

    End If

    If AscW(s(digit)) < cLastDigitAsc - 1 Then

    s(digit) = Convert.ToChar(AscW(s(digit)) + 1)

    Else

    s(digit) = zero_char

    If digit > 0 Then

    NaryNumberIncrementDigit(s, zero_char, n_value, digit - 1)

    Else

    Throw New Exception("n-ary value too large")

    End If

    End If

    End Sub

    </code>

    ToT()
    AscW seems to do an implicit cast.
    ToUInt16 seems to me more logical than ToInt32, since chars are 16-bit unsigned values, no

    Const
    Const is unknown to me. There is no such thing. the only Const I know of is volatile (or maybe change). If you want, you can put your Const-values directly in the recursive function, and you will get rid of two parameters...



  • fp101

    Hey Gorm

    The Top Two Mathematicians in the USA had a Competition to name the Biggest Number..... The First One said Google..... The Other One Quit.....

    Never Tell a Swede a Joke on Friday.... He will Bust out laughing in Church on Sunday....

    Cheers


  • Aces

    Hi.

    Be aware that 93^56 is about 17180868705902981879472417033669171808687059029818794724170336691718086870590298187947241703366917180868705902
    or 17180868705 googol
    A googol is greater than the number of particles in the known universe.
    If you are counting something, you are counting the same thing more than twice, which leads me to believe there might be a better solution to your problem.

    Anyway,
    you need a recursive function, here is a general one
    <code>

    Private Sub NaryNumberIncrementDigit(ByRef s As System.Text.StringBuilder, ByVal zero_char As Char, ByVal n_value As Byte, ByVal digit As Byte)

    Dim cLastDigitAsc As Byte = Asc(zero_char) + n_value - 1

    If Asc(s(digit)) < cLastDigitAsc - 1 Then

    s(digit) = Chr(Asc(s(digit)) + 1)

    Else

    s(digit) = zero_char

    If digit > 0 Then

    NaryNumberIncrementDigit(s, zero_char, n_value, digit - 1)

    End If

    End If

    End Sub

    </code>

    Call it like this:

    <code>

    ReadOnly ZERO_CHAR As Char = "#"

    ReadOnly N_VALUE As Byte = 93

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim s As New System.Text.StringBuilder("#$(U#)(EDdkjd(#U()#U")

    NaryNumberIncrementDigit(s, ZERO_CHAR, N_VALUE, s.Length - 1) ' Increment last n-ary digit

    MessageBox.Show(s.ToString())

    s = New System.Text.StringBuilder("2~~~~~~~~~~")

    NaryNumberIncrementDigit(s, ZERO_CHAR, N_VALUE, s.Length - 1) ' Increment last n-ary digit

    MessageBox.Show(s.ToString())

    End Sub

    </code>



  • Wes Shaddix

    I haven't actually tested this code but I believe it should do the job.  You could generalise it if you wanted to.



    Const MIN_CHAR_CODE As Integer = 33 'The Unicode value of the character that represents zero.

    Const MAX_CHAR_CODE As Integer = 126 'The Unicode value of the character that represents the maximum single didgit value.

    Const BASE As Integer = MAX_CHAR_CODE - MIN_CHAR_CODE + 1 'The base of this numbering system, i.e. how many digits there are.

    Private Function ToBase94String(ByVal num As Decimal) As String

    Dim str As String = String.Empty
    Do

    str = Convert.ToChar((num Mod BASE) + MIN_CHAR_CODE) & str
    num =
    Decimal.Truncate(num / BASE)
    Loop While num > 0D
    Return str
    End Function

    Private Function FromBase94String(ByVal str As String) As Decimal

    Dim num As Decimal = 0
    For i As Integer = 0 To str.Length - 1
    num += (Convert.ToDecimal(str.Chars(str.Length - 1 - i)) - MIN_CHAR_CODE) * Convert.ToDecimal(Math.Pow(BASE, Convert.ToDouble(i)))
    Next

    Return num
    End Function

     


  • thn

    Alright, thanks a ton for the code.

    I'm going to try some of it tonight or tomorrow.

    Yes I know the number is huge. I'm trying a distributed computing expirement. This "counting" is going to be split up into as many as 10 PCs. The text files that this program creates will have work done on them by many PCs.

    Anyway, I'll see what I come up with and then get back to ya.

    Needless to say, how long do you suppose it would take a single PC to count this "number" to 56 digits, starting with 15 digits We talking years



  • Stevey

    Here's that code again cleaned up a little.



    Const MIN_CHAR_CODE As Integer = 33 'The Unicode value of the character that represents zero.

    Const MAX_CHAR_CODE As Integer = 126 'The Unicode value of the character that represents the maximum single didgit value.

    Const BASE As Integer = MAX_CHAR_CODE - MIN_CHAR_CODE 'The base of this numbering system, i.e. how many digits there are.

    Private Function ToBase94String(ByVal num As Decimal) As String

    Dim str As String = String.Empty
    Do

    'Get the next digit by calculating the remainder of dividing by the base.

    str = Convert.ToChar((num Mod BASE) + MIN_CHAR_CODE) & str
    'Divide by the base and remove the remainder.

    num = Decimal.Truncate(num / BASE)
    Loop While num > 0D
    Return str
    End Function

    Private Function FromBase94String(ByVal str As String) As Decimal

    Dim num As Decimal = 0 'The final numerical value of the input string.

    Dim numValOfChar As Integer 'The numerical value of the current character.

    Dim multiplier As Decimal = 1D 'The multiplier that indicates the order of magnitude of the current digit.

    For i As Integer = 0 To str.Length - 1
    'Get the Unicode value of the right-most character and subtract the Unicode value of the zero character.

    numValOfChar = Convert.ToInt32(str.Chars(str.Length - 1 - i)) - MIN_CHAR_CODE
    'Add the value of the current digit.

    num += numValOfChar * multiplier
    'Increase the multiplier by one order of magnitude.

    multiplier *= BASE
    Next i
    Return num
    End Function


  • BrendaLL

    Aw, lost interest already

    That's alright, I'm going to be using your code and everybodies to see what I can come up with. I thank you for the time it took to create what you did.

    A number system may or may not work, because I wouldn't want any single number to be 93^56. I don't believe any variable could hold an every-increasing value. Which is why I'd rather have just a looping system using a few variables of 33to126 in size, if possible.

    Anyway, I'll see if this stuff works. Thanks again.



  • Sean Sandys - MS

    Hi Vigilante.... I also have some serious misunderstanding of your misunderstanding of All number systems.... They all are for counting..... They ALL can count to GOOGLE and more..... Number systems are a matter of Ordering symbols to count..... Our(Modern Culture) Bases go from 1 to Infinity.... Ie. Base1, Base2, Base3..... Base Infinity.... Base1 counts as 0 00 000 000 which translates to Base 10 counts as 0 1 2 3........ Long Live uninary and the one fingered Math Society.......
  • I need to count by ascii characters. Seems tricky!