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? :/
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.
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++
[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() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1176) is another option; ArrayMinMax() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1177) yields the smallest (in eax) and highest (in edx) element:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
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 (http://vb.knowcoding.com/view/42335-sorting-variants-using-ntdll-qsort.html)
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