Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Alphabetical sort of characters within a string.
#21
(04-25-2024, 12:17 PM)CharlieJV Wrote:
(04-25-2024, 11:13 AM)bplus Wrote:
(04-25-2024, 04:50 AM)CharlieJV Wrote:
Code: (Select All)
a$ = "this is uncopyrightable"
FOR i% = 1 TO 26
  FOR j% = 1 TO LEN(a$)
    t$ = UCASE$( MID$(a$,j%,1) )
    IF ASC(t$) = 64 + i% THEN PRINT t$;
  NEXT
NEXT

@CharlieJV almost same as Pete's only without instr both suffer from taking ucase$ or lcase$ more often than needed, asc can take a 2nd argument and work faster than mid$ for single letter.
Code: (Select All)
a$ = "this is uncopyrightable"
ua$ = UCase$(a$) ' do this once
For i% = 1 To 26
    For j% = 1 To Len(a$)
        If Asc(ua$, j%) = 64 + i% Then Print Chr$(i% + 64);
    Next
Next

i think instr will go faster than testing every letter in word 26 times.

i am suspecting steve's or my mod of anacode$ with string$ will be faster than pete's using instr in alpha order, i like the fact we count over the length of word only once and there is no if testing when producing the return string from counts array. it is count len(word$) + 26 string alpha steps versus instr length of word and if find instr again and another if find... length of word x 2 ifs over 26 letters steps ie they both have to go 26 letter steps but no if's in steve's/my mod with string$.

i will test by anacoding a dictionary with both methods, might consider throwing out the need for ucase$/lcase$ as entire dictionary is all capitals to start.

Yeah, I could have called UCASE$ once outside of the looping, but I was going for shortest amount of code vs performance.

That said, UCASE$ x times for a single character vs UCASE$ 1 time for x characters, would there be a difference? 

Yeah, not in love with that second parameter for ASC.  I'm a little bit too much old school there.

yeah strings process slower than number specially integers or long, so asc is way faster than mid$ and the more you use functions specially in loop the longer or less efficient the code, i know we are talking tiny tiny bits of time but every little bit adds up.
b = b + ...
Reply
#22
and the results are in, Petecode$ just edges out Anacode$
Code: (Select All)
_Title "anaCode$ versus peteCode$ with dictionary" ' b+ 2024-04-25 speed test
Dim a$(25000), p$(25000)
Dim i As Integer
start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        a$(i) = AnaCode$(w$)
    Wend
    Close
Next
anatime = Timer(.01) - start
start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        p$(i) = AnaCode$(w$)
    Wend
    Close
Next
petetime = Timer(.01) - start
Print anatime, petetime
For i = 1 To 25000
    If a$(i) <> p$(i) Then Print a$(i), p$(i)
Next
Print "END OF DIFF CHECK"



' return sorted ancagram code string for any word, call ucase$(wrd$) for all caps
Function AnaCode$ (wrd$) ' anaCode$ converts word to an Anagram pattern
    ' wrd$ is assumed to be in all capitals!!!
    ' number of A's in first, number of B's in 2nd, number of C's in third
    Dim As Integer L(26), i, p
    Dim rtn$
    For i = 1 To Len(wrd$)
        p = Asc(wrd$, i) - 64 ' A=1, B=2...
        L(p) = L(p) + 1
    Next
    For i = 1 To 26
        rtn$ = rtn$ + String$(L(i), Chr$(i + 64)) ' thanks steve for string$ idea
    Next
    AnaCode$ = rtn$
End Function

Function peteCode$ (a$) 'converts word to an Anagram pattern
    ' a$ is assumed to be all caps call ucase$(a$) if not
    Dim i%, seed%, rtn$
    For i% = 1 To 26
        seed% = InStr(a$, Chr$(64 + i%))
        While seed%
            rtn$ = rtn$ + Chr$(64 + i%)
            seed% = InStr(seed% + 1, a$, Chr$(64 + i%))
        Wend
    Next
    peteCode$ = rtn$
End Function

   
b = b + ...
Reply
#23
Ha!  After a little optimization and some good old fashioned "What the hell did ya do there???" coding, the results for speed have completely swapped!

Code: (Select All)
_Title "anaCode$ versus peteCode$ with dictionary" ' b+ 2024-04-25 speed test
Dim a$(25000), p$(25000)
Dim i As Integer
start = Timer(.01)
For i = 1 To 2
    Open "Scrabble WordList 2006.txt" For Binary As #1
    While Not EOF(1)
        Line Input #1, w$
        a$(i) = AnaCode$(w$)
    Wend
    Close
Next
anatime = Timer(.01) - start
start = Timer(.01)
For i = 1 To 2
    Open "Scrabble WordList 2006.txt" For Binary As #1
    While Not EOF(1)
        Line Input #1, w$
        p$(i) = peteCode$(w$)
    Wend
    Close
Next
petetime = Timer(.01) - start
Print anatime, petetime
For i = 1 To 25000
    If a$(i) <> p$(i) Then Print a$(i), p$(i)
Next
Print "END OF DIFF CHECK"

' return sorted ancagram code string for any word, call ucase$(wrd$) for all caps
Function AnaCode$ (wrd$) ' anaCode$ converts word to an Anagram pattern
    ' wrd$ is assumed to be in all capitals!!!
    ' number of A's in first, number of B's in 2nd, number of C's in third
    Dim As Integer L(65 To 91), i, p
    Dim rtn$
    For i = 1 To Len(wrd$)
        p = Asc(wrd$, i)
        L(p) = L(p) + 1
    Next
    l = 1
    rtn$ = wrd$ 'to set proper length for rtn$
    For i = 65 To 91
        If L(i) Then 'only do the string junk if a letter exists
            Mid$(rtn$, l) = String$(L(i), i) ' thanks steve for string$ idea -- You're welcome... Here's another idea:  don't add strings as that's slow too.
            l = l + L(i)
        End If
    Next
    AnaCode$ = rtn$
End Function

Function peteCode$ (a$) 'converts word to an Anagram pattern
    ' a$ is assumed to be all caps call ucase$(a$) if not
    Dim i%, seed%, rtn$
    For i% = 65 To 91
        seed% = InStr(a$, Chr$(i%))
        While seed%
            rtn$ = rtn$ + Chr$(i%)
            seed% = InStr(seed% + 1, a$, Chr$(i%))
        Wend
    Next
    peteCode$ = rtn$
End Function

I didn't have your word list, so I substituted one of my own, which I think most folks around here should have a copy of.  Wink



And in other news::




(04-25-2024, 01:56 PM)bplus Wrote: and the results are in, Petecode$ just edges out Anacode$
Code: (Select All)
_Title "anaCode$ versus peteCode$ with dictionary" ' b+ 2024-04-25 speed test
Dim a$(25000), p$(25000)
Dim i As Integer
start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        a$(i) = AnaCode$(w$)
    Wend
    Close
Next
anatime = Timer(.01) - start
start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        p$(i) = AnaCode$(w$)
    Wend
    Close
Next
petetime = Timer(.01) - start
Print anatime, petetime
For i = 1 To 25000
    If a$(i) <> p$(i) Then Print a$(i), p$(i)
Next
Print "END OF DIFF CHECK"



' return sorted ancagram code string for any word, call ucase$(wrd$) for all caps
Function AnaCode$ (wrd$) ' anaCode$ converts word to an Anagram pattern
    ' wrd$ is assumed to be in all capitals!!!
    ' number of A's in first, number of B's in 2nd, number of C's in third
    Dim As Integer L(26), i, p
    Dim rtn$
    For i = 1 To Len(wrd$)
        p = Asc(wrd$, i) - 64 ' A=1, B=2...
        L(p) = L(p) + 1
    Next
    For i = 1 To 26
        rtn$ = rtn$ + String$(L(i), Chr$(i + 64)) ' thanks steve for string$ idea
    Next
    AnaCode$ = rtn$
End Function

Function peteCode$ (a$) 'converts word to an Anagram pattern
    ' a$ is assumed to be all caps call ucase$(a$) if not
    Dim i%, seed%, rtn$
    For i% = 1 To 26
        seed% = InStr(a$, Chr$(64 + i%))
        While seed%
            rtn$ = rtn$ + Chr$(64 + i%)
            seed% = InStr(seed% + 1, a$, Chr$(64 + i%))
        Wend
    Next
    peteCode$ = rtn$
End Function

Note that the code you've shared above runs the same subroutine for BOTH timers.  You never actually call peteCode anywhere...
Reply
#24
dah yikes, my broken shift key is such a distraction, thats funny the 2nd run consistently out shone the first.

hey you didn't post the results?
b = b + ...
Reply
#25
rerun

Code: (Select All)
_Title "anaCode$ versus peteCode$ with dictionary" ' b+ 2024-04-25 speed test
Dim a$(25000), p$(25000)
Dim i As Integer
start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        a$(i) = AnaCode$(w$)
    Wend
    Close
Next
anatime = Timer(.01) - start
start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        p$(i) = peteCode$(w$)
    Wend
    Close
Next
petetime = Timer(.01) - start
Print anatime, petetime
For i = 1 To 25000
    If a$(i) <> p$(i) Then Print a$(i), p$(i)
Next
Print "END OF DIFF CHECK"



' return sorted ancagram code string for any word, call ucase$(wrd$) for all caps
Function AnaCode$ (wrd$) ' anaCode$ converts word to an Anagram pattern
    ' wrd$ is assumed to be in all capitals!!!
    ' number of A's in first, number of B's in 2nd, number of C's in third
    Dim As Integer L(26), i, p
    Dim rtn$
    For i = 1 To Len(wrd$)
        p = Asc(wrd$, i) - 64 ' A=1, B=2...
        L(p) = L(p) + 1
    Next
    For i = 1 To 26
        rtn$ = rtn$ + String$(L(i), Chr$(i + 64)) ' thanks steve for string$ idea
    Next
    AnaCode$ = rtn$
End Function

Function peteCode$ (a$) 'converts word to an Anagram pattern
    ' a$ is assumed to be all caps call ucase$(a$) if not
    Dim i%, seed%, rtn$
    For i% = 1 To 26
        seed% = InStr(a$, Chr$(64 + i%))
        While seed%
            rtn$ = rtn$ + Chr$(64 + i%)
            seed% = InStr(seed% + 1, a$, Chr$(64 + i%))
        Wend
    Next
    peteCode$ = rtn$
End Function

peteCode slightly ahead, I am going to reverse positions and teach myself to use other shift key!
   

BTW my word file is old unixdict.txt file with all words uning non letters like numbers of single quote removed and words CAPITALIZED.
b = b + ...
Reply
#26
Note the first half of my previous post -- peteCode is now no longer faster than AnaCode.  Smile
Reply
#27
i am swapping position petecode first and anacode 2nd to see if makes a difference

(04-25-2024, 05:28 PM)SMcNeill Wrote: Note the first half of my previous post -- peteCode is now no longer faster than AnaCode.  Smile

what was difference though? huge or minute
b = b + ...
Reply
#28
2.5 secs (modified ana) vs 2.9 secs (pete).

So it goes from a little slower than pete's to about 20% faster than it, on my machine.  I dunno how large a difference you consider that to be, though I'd call it worth noting.  Smile
Reply
#29
yeah see i reverse which routine runs first and anacode is tiny bit faster so disadvantage which ever routine is run first but petetime was better over anacode
Code: (Select All)
_Title "anaCode$ versus peteCode$ with dictionary" ' b+ 2024-04-25 speed test
Dim a$(25000), p$(25000)
Dim i As Integer
start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        p$(i) = peteCode$(w$)
    Wend
    Close
Next
petetime = Timer(.01) - start

start = Timer(.01)
For i = 1 To 25
    Open "WORDS.txt" For Input As #1
    While Not EOF(1)
        Input #1, w$
        a$(i) = AnaCode$(w$)
    Wend
    Close
Next
anatime = Timer(.01) - start

Print "PeteTime ="; petetime, "AnaTime ="; anatime
For i = 1 To 25000
    If a$(i) <> p$(i) Then Print a$(i), p$(i)
Next
Print "END OF DIFF CHECK"



' return sorted ancagram code string for any word, call ucase$(wrd$) for all caps
Function AnaCode$ (wrd$) ' anaCode$ converts word to an Anagram pattern
    ' wrd$ is assumed to be in all capitals!!!
    ' number of A's in first, number of B's in 2nd, number of C's in third
    Dim As Integer L(26), i, p
    Dim rtn$
    For i = 1 To Len(wrd$)
        p = Asc(wrd$, i) - 64 ' A=1, B=2...
        L(p) = L(p) + 1
    Next
    For i = 1 To 26
        rtn$ = rtn$ + String$(L(i), Chr$(i + 64)) ' thanks steve for string$ idea
    Next
    AnaCode$ = rtn$
End Function

Function peteCode$ (a$) 'converts word to an Anagram pattern
    ' a$ is assumed to be all caps call ucase$(a$) if not
    Dim i%, seed%, rtn$
    For i% = 1 To 26
        seed% = InStr(a$, Chr$(64 + i%))
        While seed%
            rtn$ = rtn$ + Chr$(64 + i%)
            seed% = InStr(seed% + 1, a$, Chr$(64 + i%))
        Wend
    Next
    peteCode$ = rtn$
End Function

   
best beat time for anacode running 2nd was .3 secs whereas best beat time petecode ran was consistely around .6 secs

btw here is WORD.txt file if someone else wants to try this, < 25,000 words

(04-25-2024, 05:42 PM)SMcNeill Wrote: 2.5 secs (modified ana) vs 2.9 secs (pete).

So it goes from a little slower than pete's to about 20% faster than it, on my machine.  I dunno how large a difference you consider that to be, though I'd call it worth noting.  Smile

ok i will try your optimization with my test code and system, 65 to 90 stuff

it is wierd that which ever goes first is slower on my tests.


Attached Files
.txt   WORDS.txt (Size: 225.2 KB / Downloads: 7)
b = b + ...
Reply
#30
btw Z is 90 not 91
b = b + ...
Reply




Users browsing this thread: 6 Guest(s)