Besides @SolitudeSF's important suggestion, an algorithmic improvement you can 
use is to replace `algorithm.sorted(lower, system.cmp)` with a hand-written 
"counting sort". For ASCII (i.e. 1 byte textual characters) this is (very?) 
easy and should be quite a bit faster than `algorithm.sorted`. Something like 
this:
    
    
    proc sortByLetter(word: string): string =
        var cnt: array[26, int8]
        for ch in word:           #simple counting sort
          cnt[ord(ch) - ord('A')].inc
        for i, c in cnt:
          for n in 0 ..< c:
            result.add chr(ord('A') + i)
    
    
    Run

You probably need some `toUpper` in there if your dictionary is stored in 
lowercase (although that could also be done prior to entry to the above `proc` 
or you could also just change `A` to `a`). That `int8` type covers words up to 
255 characters long, but I think the longest real word in any spoken language 
with dictionaries is less than that. You could always count and print a warning 
or switch that to `int16` or `int32` which could help if chemical elements or 
really crazy stuff is possibly in play.

The same idea could be adapted to unicode but then you would probably want a 
`Table`, not an `array` which would slow it down more than the above minor 
modifications.

I actually think this is a good problem context in which to introduce the oft 
neglected counting sort which can also be used with (unlike here) non-empty 
satellite data (at some slightly increased code baggage).

Reply via email to