News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Sort Integer Algorithm

Started by yq8, May 27, 2015, 10:53:12 AM

Previous topic - Next topic

yq8

Hello Community,

I am trying to sort an Integer.
I want to order the digits of the integer so they will result in the biggest possible number.
Here is an example :

2927466  -> 9766422
12492771 -> 97742211


I have no idea how to realize this with asm to be honest.
As once recommended by the users dedndave and jj2007 I should
try to do the same thing by using another (higher) language first.
I was able to do that with C#.
This is the algorithm I have written:

  public static int ReorderInt32Digits(int v)
        {
            int n = Math.Abs(v);
            int l = ((int)Math.Log10(n > 0 ? n : 1)) + 1;
            int[] d = new int[l];
            for (int i = 0; i < l; i++)
            {
                d[(l - i) - 1] = n % 10;
                n /= 10;
            }
            if (v < 0)
                d[0] *= -1;
            Array.Sort(d);
            Array.Reverse(d);
            int h = 0;

            for (int i = 0; i < d.Length; i++)
            {
                int index = d.Length - i - 1;
                h += ((int)Math.Pow(10, index)) * d[i];
            }
            return h;
        }


Still I have no clue how I can do this with masm, so my function would require on integer as input
and returns the order integer as output like my C# algorithm.
Can someone help me out? :/

rrr314159

well u have to do same as this C algo. First isolate each digit and line them up in an array. Then sort the array. There have been earlier threads showing how to get each digit, didn't u yourself start one of them? Basic idea, loop dividing by 10. As for the sorting, just use the simplest possible, not even bubble sort, since time is unimportant. Just go thru them find the biggest, output that, find next one, output that, etc.
I am NaN ;)

Mikl__

Hi, yq8!
there is nothing new to invent not need. The NTDLL.DLL has built-in api-function QSORT. Parameters are passed as well as a similar function QSORT in C/C++

jj2007

#3
[EDIT:] Just realised you want to sort by digits, not by numbers. Sorry, the code below won't do that. If you are allowed to use a dword to text algo, you could
- parse the string, e.g. 12879135
- pick the 9 and put it at the beginning of the destination number
- replace the 9 in the source with 0
- do that repeatedly.

If you just need the highest number, try this (plain Masm32):
include \masm32\include\masm32rt.inc

.code
Numbers dd 99, 77, 123, 1, 777, 0, 20

start: mov esi, offset Numbers
mov ebx, [esi] ; any member of the Numbers array will be OK
xor ecx, ecx
.Repeat
mov eax, [esi+ecx]
.if eax>ebx
xchg eax, ebx
.endif
add ecx, 4
.Until ecx>=sizeof Numbers
print str$(ebx)
exit

end start


ArraySort() is another option; ArrayMinMax() yields the smallest (in eax) and highest (in edx) element:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  Dim Numbers(6) As DWORD
  ArraySet Numbers()=99, 77, 123, 1, 777, 33, 20
  ArrayMinMax Numbers()
  deb 1, "Min, Max:", eax, edx
  Exit
end start


But of course, if you prefer complicated stuff, don't hesitate: Sorting variants using ntdll!qsort

FORTRANS

COMMENT *
I am trying to sort [the digits in] an Integer.
I want to order the digits of the integer so they will result in
the biggest possible number.

Here is an example :

2927466 -> 9766422
12492771 -> 97742211
*
;    This example is for a byte integer with three digits.  The
; range is 0 to 255.  A word would have five digits, and a double
; word would have ten.  No real attempt was made to make a good
; program.  However, the result can be as large as 991.

Ten     DB      10
Number  DB      123     ; Input.
Result  DW      ?       ; This will have the final result.
                        ; (Which can be GT 255.)
Digits  DB      0, 0, 0 ; This will be the working array.  It
                        ; will be in "little endian" format with the
                        ; smallest (units) digit in the first place.

Ex_0:
; - - - Divide AH:AL by ten to get the digits.

        XOR     AH,AH   ; Zero AH to make divide work correctly.
        MOV     AL,[Number]
        DIV     [Ten]
        MOV     [Digits],AH     ; First digit is the remainder in AH.
        XOR     AH,AH
        DIV     [Ten]
        MOV     [Digits+1],AH   ; Second digit.
        XOR     AH,AH
        DIV     [Ten]
        MOV     [Digits+2],AH   ; Third digit.
; With something larger than a byte, put the above into a loop format.

; - - - Sort the digits.

        MOV     AL,[Digits]
        CMP     AL,[Digits+1]
        JBE     Ex_1    ; Is the second digit smaller?
        XCHG    AL,[Digits+1]   ; If yes, swap.
Ex_1:
        CMP     AL,[Digits+2]
        JBE     Ex_2    ; Is the third digit smaller?
        XCHG    AL,[Digits+2]   ; If yes, swap.
Ex_2:
        MOV     [Digits],AL     ; First digit is smallest.

        MOV     AL,[Digits+1]
        CMP     AL,[Digits+2]
        JBE     Ex_3    ; Is the third digit smaller than the second?
        XCHG    AL,[Digits+2]   ; If yes, swap.
Ex_3:
        MOV     [Digits+1],AL   ; Digits are ordered.

; - - - Make the result.

        MOV     AL,[Digits+2]
        MUL     [Ten]
        ADD     AL,[Digits+1]
        MUL     [Ten]
        ADD     AL,[Digits]
        MOV     [Result],AX