hp41programs

Sort

Sorting Numbers for the HP-41


Overview
 

 1°) A Focal Program
 2°) Micro-Code Routine  ( Contiguous Registers only )
 
 

1°) A Focal Program
 

Data Registers:   Only those of the block of registers.
Flags: /
Subroutines: /

-If you don't have an HP-41CX, replace lines 08 to 13 by

     RCL IND Y
     X>Y?               (  or  X<=Y?  to sort in decreasing order  )
     GTO 03
     X<>Y
     LASTX
     +
     LBL 03
     RDN
 
 

01  LBL "SORT"
02  SIGN
03  LBL 01
04  LASTX
05  LASTX
06  RCL IND L 
07  LBL 02
08  X<=NN?
09  GTO 03  
10  X<>Y     
11  STO Y        
12  RCL IND X 
13  LBL 03       
14  ISG Y 
15  GTO 02  
16  X<> IND L 
17  STO IND Z 
18  ISG L
19  GTO 01
20  END

 
  ( 40 bytes )
 
 

      STACK        INPUT      OUTPUT
           X        bbb.eeeii             /

      where  bbb.eeeii  is the control number of the array.

-For example, to sort numbers in registers R01  R03  R05  R07 , key in

  1.00702  XEQ "SORT"

-Execution time is of the order of 47 seconds for an array of  20 numbers
-Execution time is of the order of 17 minutes for an array of  100 numbers

-This program uses a selection sort.
-The numbers are sorted in increasing order.
-If you want to sort in decreasing order, replace line 08 by  X>=NN?

-It also works to sort alpha strings.
 

2°) Micro-Code Routine  ( Contiguous Registers only )
 

-The following routine uses the "Bubble Sort" which is probably the worst sorting-algorithm...
-However, it is approximately 40 times as fast as the program above !
 

Code    Mnemonics

094     "T"
012     "R"
00F    "O"
013     "S"
0F8     READ 3(X)                       The first executable word
361     ?NCXQ                             This execute instruction
050      14D8                                 checks for alpha data
284      CLRF 7
2FE     ?C#0 MS                          These 4 blue lines ( and the 3 other blue lines below )
013      JNC +02                           allow to sort in decreasing order if the input is negative.
288      SETF 7
05E      C=0 MS
084      CLRF 5
0ED     ?NCXQ
064      193B
226      C=C+1 S&X
226      C=C+1 S&X
226      C=C+1 S&X
088      SETF 5
0ED     ?NCXQ
064      193B
070      N=C ALL
0F8      READ 3(X)
05E      C=0 MS
0ED     ?NCXQ
064      193B
260      SETHEX
38D     ?NCXQ
008      02E3
0F0      C<>N ALL
38D     ?NCXQ
008      02E3
10E      A=C ALL
378      READ 13(c)
03C     RCR 3
146      A=A+C S&X
066      A<>B S&X
10E      A=C ALL
0B0      C=N ALL
206      C=C+A S&X
066      A<>B S&X
306      ?A<C S&X
013      JNC + 02
0A6     A<>C S&X
070      N=C ALL
130      LDI S&X                  200 hexadecimal = 512 decimal is the correct value if you have an HP-41CV/CX or an HP-41C with a quad memory module.
200      CON: 512                 Replace this line by 100h = 256d if you have an HP-41C without any memory module.
306      ?A<C S&X
381      ?NCGO                   -If register Rbb or Ree don't exist,
00A      02E0                         you'll get a "NON EXISTENT" message
0B0      C=N ALL
1BC     RCR 11
11A      A=C M
0AE     A<>C ALL
033      JNC +06
270      RAMSLCT
0EE     C<>B ALL
2F0      WRIT DATA
198      C=M ALL
266      C=C-1 S&X
158      M=C ALL
106      A=C S&X
03C     RCR 3
070      N=C ALL
366      ?A#C S&X
3A0     ?NC RTN
270      RAMSLCT
038      READ DATA
0EE     C<>B ALL
198      C=M ALL
106      A=C S&X
0B0      C=N ALL
366      ?A#C S&X
373      JNC -12
226      C=C+1 S&X
070      N=C ALL
270      RAMSLCT
038      READ DATA
06E      A<>B ALL
37E      ?A#C MS
023       JNC +04
35E      ?A#0 MS
0B7       JC +16
0A3      JNC +14
21C      PT=2
362       ?A#C @PT                     these 25 green lines compare the numbers in the CPU registers A and C,
03B      JNC +07                          place the lowest one in A and the highest one in C.
342       ?A#0 @PT
017       JC +02
0AE      A<>C ALL
2EE      ?C#0 ALL
057       JC +0A
05B      JNC +0B
366       ?A#C S&X
023       JNC +04
306       ?A<C S&X
02F       JC +05
01B       JNC +03
31A      ?A<C M
017       JC +02
0AE      A<>C ALL
35E       ?A#0 MS
013       JNC +02
0AE      A<>C ALL
28C      ?FSET 7
013       JNC +02
0AE      A<>C ALL
0EE       C<>B ALL
0B0       C=N ALL
266       C=C-1 S&X
270       RAMSLCT
0AE      A<>C ALL
2F0       WRIT DATA
2A3       JNC -2C
 
 
 

      STACK        INPUT      OUTPUT
           X     +/- bbb.eee     +/- bbb.eee

      Where  bbb.eee  is the control number of the array.
      The stack is actually unchanged.

-A positive input will sort the numbers in increasing order
-A negative input will sort the numbers in decreasing order

Notes:

-Execution time is of the order of  25 seconds for an array of 100 numbers
-Execution time is of the order of 100 seconds for an array of 200 numbers
-It is proportional to the square of the number of elements.

-In fact, the 4th , 5th , .... decimals of the input are not taken into account

-You can also key in  eee.bbb  instead of  bbb.eee
-For instance, if you have to sort the numbers in registers  R00  R01  ............  R99
 simply press  99  XEQ "SORT"  instead of  0.099  XEQ "SORT"  ( both work )

-If you do not need to sort in decreasing order, delete the 7 lines written in blue ( especially the last 3 ones:  28C  013  0AE )
 and  replace the last line ( written in red )  by

2BB      JNC -29             the routine will run 6% faster.

-There is no risk of "crash" if the registers contain alpha data, but the sorting may be quite fanciful !
-For example, if registers R01 thru R05 contain  "A"  "B"  "Z"  "AB"  "ABC"
  1.005  XEQ "SORT"  will produce "Z"  "B"  "A"  "ABC"  "AB"  in these registers...
-It is due to the way alpha strings are coded in a register.