Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
digitaljams
Newbie


Joined: 02 Nov 2007
Posts: 9

PostPosted: Sun Jan 03, 2010 6:09 pm   

How to sort intergers ASC or DESC
 
Looking for a way to sort a listing of numbers in ASC or DESC fashion.

31
20620
594
14785

Currently the only way I am aware of to sort things is via the sort command.. but it doesnt work for comparing numbers.

List = {31|20620|594|14785}
#SORT list
#SHOW @list

This yields 14785|20620|31|594

Works great for strings.. not so well for intergers/numbers....

Suggestions? Thus far I have started working a very messy Switch statement that will do it.. but I would assume that there is a better simpler way.
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Sun Jan 03, 2010 8:55 pm   
 
It's probably just as good to chop your list up into separate variables based on length, then apply the %sort() function to those variables, and finally connect them all together based on sort direction:
Code:

#function @SortNumbers($list,$direction) {
  #switch (%isnumber(%replace($list,"|","")) {
      //numerical list
      //19 digits is the maximum length of the 64-bit integers CMud can mathematically handle
      #local $lengths $newlist
      //initialize $lengths so we can tell what's used and not used after the sort
      #loop 1,19 {
        #addkey $lengths %i "NA"
      }
      //divide $list into $lengths
      #forall $list {
        #if ($lengths.%len(%i) = "") {#addkey $lengths %len(%i) %i} {#addkey $lengths %len(%i) %concat($lengths.%len(%i),"|",%i)}
      }
      //apply sort and construct the new list
      #if ($direction) {
        //descending order
        #loop 19,1 {
          #if ($lengths.%i != "NA") {
            #if ($newlist = "") {$newlist = %sort($length.%i)} {$newlist = %concat($newlist,"|",%sort($length.%i))}
          }
        }
        #return $newlist
      } {
        //ascending order
        #loop 19,1 {
          #if ($lengths.%i != "NA") {
            #if ($newlist = "") {$newlist = %sort($length.%i)} {$newlist = %concat($newlist,"|",%sort($length.%i))}
          }
        }
        #return $newlist
      }
    }
    ($list = "") {//no list}
    (1) {//list is not numeric}
}
_________________
EDIT: I didn't like my old signature
Reply with quote
gamma_ray
Magician


Joined: 17 Apr 2005
Posts: 496

PostPosted: Mon Jan 04, 2010 3:11 pm   
 
Code:
<func name="quicksort" id="116">
  <value>#local left,right,pivot,length
$length = %numitems($list)
#if ($length = 0) {
  #return %null
} {
  #if ($length = 1) {
    #return {$list|}
  } {
    $length = $length/2
    $pivot = $list.$length
    $list = %delnitem($list, $length)
    #if %begins($order,dec) {
      #for $list {
        #if (%i >= $pivot) {
          $left = %additem(%i,$left)
        } {
          $right = %additem(%i,$right)
        }
      }
    } {
      #for $list {
        #if (%i <= $pivot) {
          $left = %additem(%i,$left)
        } {
          $right = %additem(%i,$right)
        }
      }
    }
    #return %concat(@quicksort($left,$order),$pivot,"|",@quicksort($right,$order))
  }
}</value>
  <arglist>list,order</arglist>
</func>


This is a quick implementation of a recursive quicksort (pretty much following the algorithm from Wikipedia). I couldn't come up with an elegant way of concating the pieces without getting extra pipe characters, so there's one extra (empty) item on the end of the list after the sort finishes. You can use delnitem to get rid of it. Usage would be something like
Code:
var = @quicksort(@var,dec)
var = %delnitem(@var,%numitems(@var))
"dec" is optional, anything that does not start with "dec" will sort in increasing order. Oh, and it works on numbers ONLY. Attempting to sort non-numeric items will probably fail in amusing ways.

(I really wanted to do an in place quicksort, but CMud was having none of it.)
Reply with quote
ReedN
Wizard


Joined: 04 Jan 2006
Posts: 1279
Location: Portland, Oregon

PostPosted: Mon Jan 04, 2010 6:00 pm   
 
This really should be implemented as a built in function. Something this basic shouldn't need to be reinvented by the end user.
Reply with quote
Taz
GURU


Joined: 28 Sep 2000
Posts: 1395
Location: United Kingdom

PostPosted: Mon Jan 04, 2010 7:56 pm   
 
Yes and Zugg has already put it on his to do list.
_________________
Taz :)
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net