Shop OBEX P1 Docs P2 Docs Learn Events
Simple Array Sort — Parallax Forums

Simple Array Sort

SailerManSailerMan Posts: 337
edited 2007-02-28 12:06 in General Discussion
How can I do this In SX/B for the· SX28. It's just a quick sorting routine.

Sort:
  Do
   Flip=0   
   For Index = 0 to 7
     If Sensor(Index)<Sensor(Index+1) Then 
        Flip=1
        Temp=Sensor(Index)
        Sensor(Index)=Sensor(Index+1)
        Sensor(Index+1)=Temp
     Endif
   Next
  Loop Until Flip=0
RETURN 

Apparently I can't index an array this way.

What alternatives are there?

Thanks,
Eric

Comments

  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2007-02-27 02:06
    Eric,

    I think that if you create another variable that is one number higher than Index, say Index_Plus_1, you can implement this function almost as written. Here is what I am thinking should work. I have not tested it!

    Sort:
      Do
       Flip = 0  
       For Index = 0 to 7
        [b]Index_Plus_1 = Index + 1[/b]
         If Sensor(Index) < Sensor(Index_Plus_1) Then
            Flip = 1
            Temp = Sensor(Index)
            Sensor(Index) = Sensor(Index_Plus_1)
            Sensor(Index_Plus_1) = Temp
         Endif
       Next
      Loop Until Flip = 0
    RETURN
    



    - Sparks
  • SailerManSailerMan Posts: 337
    edited 2007-02-27 02:25
    I was thinking along those lines, I just didn't want to use another variable. I will go with this for now until I come up with a better algorithm.

    Thanks for your help,
    Eric
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-27 02:43
    Without using Temp

    Sort:
    ··Do
    ···Flip·=·0
    ···For·Index·=·0·to·7
    ····Index_Plus_1·=·Index·+·1
    ·····If·Sensor(Index)·<·Sensor(Index_Plus_1)·Then
    ········Flip·=·1
    ········Sensor(Index) = Sensor(Index) ^ Sensor(Index_Plus_1)
    ········Sensor(Index_Plus_1)·=·Sensor(Index_Plus_1) ^ Sensor(Index)
    ········Sensor(Index) = Sensor(Index) ^ Sensor(Index_Plus_1)
    ·····Endif
    ···Next
    ··Loop·Until·Flip·=·0
    RETURN

    The ^ operator is the XOR operator

    regards peter
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2007-02-27 04:06
    Ok, Eric...

    If you do not want to use another variable (and it could be a temporary variable you reuse later), will you consider using an assembly block?

    If so, this may work for you.

    Sort:
      Do
       Flip = 0  
       For Index = 0 to 7
    
            ASM                  ;' Should be equivelant to "[i]If Sensor(Index) < Sensor(Index + 1) Then[/i]"
              MOV W,#Sensor                 
              ADD W,Index                   
              MOV FSR,W                     
              MOV __PARAM1,IND              
              BANK $00                      
              MOV W,#Sensor               ;' Move the location of Sensor into the W (working) register.
              ADD W,Index                  ;' Add the value of Index to the value in W.
              [b]INC W[/b]                       ;' Increment the value in W.
              MOV FSR,W                     
              MOV __PARAM2,IND              
              BANK $00                      
              CJAE __PARAM1,__PARAM2,[b]@Sort_ENDIF[/b]      ;' Point to where the ENDIF should be...
            ENDASM
    
    
            Flip = 1
            Temp = Sensor(Index)
            Sensor(Index) = Sensor(Index_Plus_1)
            Sensor(Index_Plus_1) = Temp
    
    [b]'     Endif
    Sort_ENDIF:[/b]                 ;' Replace the now unpaired ENDIF with our own address.
    
       Next
      Loop Until Flip = 0
    RETURN
    


    This should be functionally the same as the SX/B statement “If Sensor(Index) < Sensor(Index + 1) Then” if such a statement were valid. I derived it by looking at the assembly source produced by SX/B for my previous suggested statement of “If Sensor(Index) < Sensor(Index_Plus_1) Then.” I noted where it referenced Index_Plus_1 and modified it to address Index and then added the “INC W” statement to increment that value by one. (My changes are in bold.)

    Note that by replacing the If…Then statement with assembly code I confused the SX/B compiler when it encountered the unpaired ENDIF statement near the end of the function. To remedy this I commented out the ENDIF statement, replaced it with a “Sort_ENDIF” label and modified the CJAE statement to jump to that label instead. (All of this to save a variable... and yes, I would have done it myself if I had the need!)

    I hope this helps. It seems to compile though I have done no other testing.


    Peter… I was pondering your XOR suggestion for quite a while. Who comes up with this stuff?! shocked.gif


    - Sparks
  • SailerManSailerMan Posts: 337
    edited 2007-02-27 12:04
    Thank guys, This is helpful, but I just thought of something... Each sensor as a specific slot... So after I sort the readings which is what the above algorithm does I am still going to need to know where the reading came from. So I am now going to have to sort two arrays.. One to keep track of the Senor reading and the other to remember it's location.

    Back to the drawing board.
  • BeanBean Posts: 8,129
    edited 2007-02-27 12:16
    Here is how I would do it, with a bit of creative aliasing...

    DEVICE SX28, OSCXT2, TURBO, STACKX, OPTIONX
    FREQ 20_000_000
     
    flip         VAR Bit
    index        VAR Byte
    temp         VAR Byte
     
    sensor       VAR Byte (9)
    sensorPlus1  VAR Sensor(1)
     
    PROGRAM Start NOSTARTUP
     
    Start:
      PUT Sensor, 5, 3, 7, 8, 2, 1, 6, 4, 9
     
    Sort:
      DO
       flip = 0   
       FOR index = 0 TO 7
         IF sensor(index) < SensorPlus1(index) THEN
            flip = 1
            temp = Sensor(index)
            sensor(index) = sensorPlus1(index)
            sensorPlus1(index) = temp
         ENDIF
       NEXT
     
      WATCH sensor
      BREAK
     
      LOOP UNTIL flip = 0
    END.
    


    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com


    Post Edited (Bean (Hitt Consulting)) : 2/27/2007 12:55:41 PM GMT
  • SailerManSailerMan Posts: 337
    edited 2007-02-27 12:40
    Ok, now since I'm still fairly new, that bit of code confuses me. I mean I think I'm understanding that SensorPlus1 is an Alias of the Sensor Array starting at element 1... Is this correct?

    Can you explain how the Aliasing is working. (For the Laymen)
  • BeanBean Posts: 8,129
    edited 2007-02-27 12:52
    Yep,
    That is exactly right.

    sensorPlus1(0) is the same variable as sensor(1)
    sensorPlus1(1) is the same variable as sensor(2)
    and so on...

    If you want to keep your "where from" array in step with the sensor array, just swap the elements in your swap routine.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    ·
  • SailerManSailerMan Posts: 337
    edited 2007-02-27 13:30
    So this doesn't cost any more Variable space??

    Looks like I can move ahead a little futher tonight. [noparse]:)[/noparse] thanks for the help...Again, Like aways you pull through... Are you think of adding the Ability to Add
    Array(Index+1)
    

    to SX/B?

    Also Bean I sent you a PM on another topic.

    Post Edited (SailerMan) : 2/27/2007 1:48:27 PM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-27 15:47
    Here is a variant on Bean's code, does not use temp variable

    DEVICE SX28, OSCXT2, TURBO, STACKX, OPTIONX
    FREQ 20_000_000

    flip········ VAR Bit
    index······· VAR Byte

    sensor······ VAR Byte (9)
    sensorPlus1· VAR Sensor(1)

    PROGRAM Start NOSTARTUP

    Start:
    · PUT Sensor, 5, 3, 7, 8, 2, 1, 6, 4, 9

    Sort:
    · DO
    ·· flip = 0··
    ·· FOR index = 0 TO 7
    ···· __PARAM3 = Sensor(index)
    ···· __PARAM4 = SensorPlus1(index)
    ···· IF __PARAM3 < __PARAM4 THEN
    ······· flip = 1
    ······· swap __WPARAM34
    ······· Sensor(index) = __PARAM3
    ······· SensorPlus1(index) = __PARAM4
    ···· ENDIF
    ·· NEXT

    · WATCH sensor
    · BREAK

    · LOOP UNTIL flip = 0

    END

    regards peter
  • SailerManSailerMan Posts: 337
    edited 2007-02-28 02:57
    I've looked at this code too many times...I have 8 sensors only 4 are used so far in the code below, The reading are working properly... The Highest Reading Sensor is sorted to the lowest member of the Sensor array. ,however the "Number" Array is not following along.
    Each sensor has a number and even though the Sensors get sorted by their value I still need to know the sensor number.

    Can anyone see the problem.

    Thanks,
    Eric



    DEVICE          SX28, OSCHS1, TURBO, STACKX, OPTIONX, BOR42
    FREQ            50_000_000
    

    ID  "Sensor"
     
    Baud Con "T19200"
     
    Sensor Var Byte(9)
    SensorPlus1 Var Sensor(1)
    Number Var Byte(9)
    NumberPlus1 Var Number(1)
    

    Index Var Byte
    

    Flip Var Bit  
    Temp Var Byte
    Temp2 Var Byte
    Send Sub 1
    

    Sort Sub 0 
    PROGRAM Start NOSTARTUP 
     
    Start:
    

    Main:
    Tris_A=%00000000
    Tris_C=%00000000
    Tris_B=%00000000
    RA=%00000000
    RC=%00000000
    RB=%00000000
     Put Number,0,1,2,3,4,5,6,7,8   
    Do
     Put Sensor,$00,$00,$00,$00,$00,$00,$00,$00,$00
       
     'Read Sensors
     pause 25
       Pulsout RC.3,10
       Pulsin RB.4,1,Sensor(0),14
     pause 25
        Pulsout RB.3,10
       Pulsin RB.4,1,Sensor(4),14
      pause 25
       Pulsout RC.1,10
       Pulsin RB.4,1,Sensor(2),14
     pause 25
        Pulsout RB.1,10
       Pulsin RB.4,1,Sensor(6),14 
        'Flash LED Indicator
    

     If Sensor(0)< Sensor(4) Then
        Pulsout RC.7,100,5
     Else
        Pulsout RC.6,100,5
     Endif
      
     Sort
    

     ' Transmit Data 
     Send "!"
     Send "S"
     For Index=0 to 7
      Send Number(Index) 
      Send Sensor(Index)
     NExt
    

    Loop
    

    Send:
     Serout RB.5,Baud,__Param1
    Return 
    

     
    Sort:
      DO
       flip = 0   
       FOR index = 0 TO 7
         IF sensor(index) < SensorPlus1(index) THEN
            flip = 1
            temp = Sensor(index)
      Temp2 = Number(Index)
            Number(Index) = NumberPlus1(Index)
            sensor(index) = sensorPlus1(index)
      NumberPlus1(Index) = Temp2
            sensorPlus1(index) = temp
         ENDIF
       NEXT
     
      LOOP UNTIL flip = 0
    

    RETURN
    
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-02-28 06:34
    I think you need to change

    ·Put Number,0,1,2,3,4,5,6,7,8··
    Do
    ·Put Sensor,$00,$00,$00,$00,$00,$00,$00,$00,$00

    to

    Do
    ·Put Number,0,1,2,3,4,5,6,7,8
    ·Put Sensor,$00,$00,$00,$00,$00,$00,$00,$00,$00

    otherwise, the 2nd time through the loop the sensor numbers have switched places,
    which of course is not the case, since you didn't connect the sensors in a different order.

    regards peter
  • SailerManSailerMan Posts: 337
    edited 2007-02-28 12:06
    Peter,

    Thanks for your response... I'm not at home to try this right now... But Darn I think this will do it. It's amazing how simple it is to miss the obvious.

    Eric
Sign In or Register to comment.