Snippet Base

Nestharus

o-o
Reaction score
84
JASS:

library Base /* v1.0.4.1
*************************************************************************************
*
*   A script used for base conversion where integers are represented as strings in
*   another base.
*
*************************************************************************************
*
*   */uses/*
*
*       */ Ascii /*         wc3c.net/showthread.php?t=110153
*       */ Table /*         hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
*
************************************************************************************
*
*   struct Base extends array
*
*       readonly integer size
*           -   number of digits in base
*       readonly string string
*           -   string representing base's character set
*
*       static method operator [] takes string base returns Base
*
*       method convertToString takes integer i returns string
*       method convertToInteger takes string i returns integer
*
*       method ord takes string c returns integer
*       method char takes integer i returns string
*
*       method isValid takes string value returns boolean
*           -   determines if all of the characters in the string are valid base character
*
*************************************************************************************/

/*************************************************************************************
*
*   Code
*
*************************************************************************************/
    globals
        private Table gt=0          //stacks of strings with same hashes
        private integer array n     //next node pointer for gt stack
        private string array b      //base of string
        private Table array t       //base character table
        private integer c=0         //base instance count
        private integer array s     //base size
    endglobals
    private module Init
        private static method onInit takes nothing returns nothing
            set gt=Table.create()
        endmethod
    endmodule
    struct Base extends array
        debug private static boolean array a        //is allocated
        method operator string takes nothing returns string
            return b[this]
        endmethod
        method operator size takes nothing returns integer
            return s[this]
        endmethod
        static method operator [] takes string base returns thistype
            local integer value     //string hash value
            local string char       //iterated character
            local integer i=0       //this
            local integer v         //stack of hashes
            local integer dv        //copy of v
            local integer hv        //copy of value
            debug if (1<StringLength(base)) then
                set value = StringHash(base)    //first get the hash
                set i = gt[value]               //get first node of hash table
                set v = i                       //copy
                if (0!=i) then                  //if stack exists, then loop through
                    loop
                        exitwhen 0==i or base==b<i>
                        set i=n<i>
                    endloop
                endif
                //if this still doesn&#039;t exist, create it
                if (0==i) then
                    //allocate
                    set c=c+1
                    set i=c
                    set dv=v
                    set hv=value
                    debug set a<i>=true
                    set t<i>=Table.create()     //character table
                    set b<i>=base               //base string
                    //value is now used for iterating through the base string
                    set value=StringLength(base)
                    set s<i>=value    
                    loop
                        set value=value-1
                        set char=SubString(base,value,value+1)
                        set v=Char2Ascii(char)
                        //if the character already exists, stop
                        //and deallocate (invalid base)
                        debug if (t<i>.has(v)) then
                            debug call t<i>.destroy()   //destroy character table
                            debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CREATION ERROR: &quot;+char+&quot; MULTIPLY DEFINED&quot;)
                            debug set c=c-1
                            debug set a<i>=false
                            debug return 0
                        //character doesn&#039;t exist
                        debug else
                            set t<i>[v]=value
                            set t<i>.string[-value]=char
                        debug endif
                        exitwhen 0==value
                    endloop
                    //if dv is 0, then allocate dv
                    if (0==dv) then
                        set gt[hv]=i
                    //otherwise add i to hash stack
                    else
                        set n<i>=n[dv]
                        set n[dv]=i
                    endif
                endif
                return i
            debug endif
            debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CREATION ERROR: &quot;+base+&quot; IS INVALID&quot;)
            debug return 0
        endmethod
        method convertToString takes integer i returns string
            local integer k=s[this]
            local string n=&quot;&quot;
            debug if (a[this]) then
                debug if (0&lt;=i) then
                    loop
                        exitwhen i&lt;k
                        set n=t[this].string[-(i-i/k*k)]+n
                        set i=i/k
                    endloop
                    return t[this].string[-i]+n
                debug endif
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CONVERSION ERROR: &quot;+I2S(i)+&quot; IS OUT OF BOUNDS&quot;)
                debug return null
            debug endif
            debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CONVERSION ERROR: &quot;+I2S(this)+&quot; IS NOT ALLOCATED&quot;)
            debug return null
        endmethod
        method convertToInteger takes string i returns integer
            local integer n=0
            local integer p=StringLength(i)
            local integer l=0
            local integer k=s[this]
            local string char
            debug if (a[this]) then
                loop
                    exitwhen 0==p
                    set p=p-1
                    set l=l+1
                    set char=SubString(i,l-1,l)
                    debug if (t[this].has(Char2Ascii(char))) then
                        set n=n+t[this][Char2Ascii(char)]*R2I(Pow(k,p))
                    debug else
                        debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CONVERSION ERROR: &quot;+char+&quot; IS OUT OF BOUNDS&quot;)
                        debug return 0
                    debug endif
                endloop
                return n
            debug endif
            debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CONVERSION ERROR: &quot;+I2S(this)+&quot; IS NOT ALLOCATED&quot;)
            debug return 0
        endmethod
        method ord takes string c returns integer
            debug if (a[this]) then
                debug if (1&lt;StringLength(c) or &quot;&quot;==c or null==c or not (t[this].has(Char2Ascii(c)))) then
                    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE ORD ERROR: &quot;+c+&quot; IS OUT OF BOUNDS&quot;)
                    debug return 0
                debug endif
                return t[this][Char2Ascii(c)]
            debug endif
            debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE ORD ERROR: &quot;+I2S(this)+&quot; IS NOT ALLOCATED&quot;)
            debug return 0
        endmethod
        method char takes integer i returns string
            debug if (a[this]) then
                debug if (i&lt;s[this] and 0&lt;=i) then
                    return t[this].string[-i]
                debug endif
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CHAR ERROR: &quot;+I2S(i)+&quot; IS OUT OF BOUNDS&quot;)
                debug return null
            debug endif
            debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,&quot;BASE CHAR ERROR: &quot;+I2S(this)+&quot; IS NOT ALLOCATED&quot;)
            debug return null
        endmethod
        method isValid takes string s returns boolean
            local integer i=StringLength(s)
            local string c
            if (0&lt;i) then
                loop
                    set c=SubString(s,i-1,i)
                    if (not t[this].has(Char2Ascii(c))) then
                        return false
                    endif
                    set i=i-1
                    exitwhen 0==i
                endloop
            else
                return false
            endif
            return true
        endmethod
        implement Init
    endstruct
endlibrary
</i></i></i></i></i></i></i></i></i></i></i></i>
 

tooltiperror

Super Moderator
Reaction score
231
That may be actually the ugliest syntax I have ever seen in a vJASS system. Ever.

JASS:
call ConvertBase(integer which, integer base)
 

Sevion

The DIY Ninja
Reaction score
413
tooltiperror, there is actually a difference between your syntax and his syntax. Yours requires the system to have a predefined alphabet. His does not. And to my knowledge, allowing for user-defined bases different than how he has it setup right now would be much less efficient.
 

tooltiperror

Super Moderator
Reaction score
231
Here, same functionality but prettier.

JASS:
globals
    private Base Octal=CreateBase(&quot;01234567&quot;)
    private Base Decimal=CreateBase(&quot;0123456789&quot;)
endglobals

private function foofunction takes nothing returns nothing
    local integer int=10203
    set int=ConvertBase(int,Decimal,Octal) // function ConvertBase takes integer which, Base current base, Base conversion 
endfunction
 

Sevion

The DIY Ninja
Reaction score
413
That includes a function call which reduces efficiency. At any rate, I do think that something could be done about that [ljass]baseN.to()[/ljass] and [ljass]baseN.from()[/ljass] syntax. That part is ugly as hell.
 

Nestharus

o-o
Reaction score
84
Yea, this is really about I2S and S2I where the string isn't necessarily in base 10.

Could do like s2i and i2s ;o.

edit
Updated API, tell me what you think.
 

Nestharus

o-o
Reaction score
84
Updated this as apparently [ljass]StringHash("d") == StringHash("D")[/ljass] ... will now work, but had to add this bs [ljass]if (c == StringCase(c, true)) then[/ljass].
 

Nestharus

o-o
Reaction score
84
Updated to run off of Ascii and Table.

Also changed the way requirements were listed in the documentation. Moved the uses keyword down to signify when requirements list starts ;D. Pretty spiffy huh? : P

Also, Bases no longer have any chance of colliding. StringHash can return 2 of the same hashes for two different strings =P.
 

Bribe

vJass errors are legion
Reaction score
67
Half of this is using a hashtable, the other half Table, and the TableArray you declared like Table array :O
 

Nestharus

o-o
Reaction score
84
Nevermind, just came up with a way that can replace the hashtable with a table. I'll update it today.

The hashtable itself points to an array of values. So one large range (requiring 1 full index) and one limited range. That array of values can also be put into a stack inside where the hashtable points to the pointer of that stack. This means then that only 1 full index is required, thus a Table can be used instead of a hashtable if using a stack instead of an array =).

Should be slightly faster and still have a max instance count of 8191.

The reason a TableArray was because it wasn't needed for this. A TableArray would be useful if I had like a 3D collection (my array + table array).

edit
updated
 

tooltiperror

Super Moderator
Reaction score
231
There are a wide variety of uses for this.

Base manipulation is important in most programming languages. I found myself needing a way to replicate the Exclusive-Or (XOR) function in JASS, and converting to binary with this was the best way.

Other things like shortening integers by converting bases is simple with this, too.

As always, your code is optimal, quite possibly some of the best ever written performance-wise for Warcraft III.

Approved.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top