The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ~Paul~ on September 03, 2007, 07:37:32 AM

Title: Loop problem
Post by: ~Paul~ on September 03, 2007, 07:37:32 AM
hi i have been trying to list all numbers that are well ordered and have four digits. I have completed it in all high level languages and was bored and trying to port it to ASM but it looks like it was a little harder than i anticipated. Could anyone show me what they can come up with.
Title: Re: Loop problem
Post by: dsouza123 on September 03, 2007, 08:22:56 AM
Could you attach some working VB6 or C code.

Also an explanation of well ordered numbers.
Title: Re: Loop problem
Post by: ~Paul~ on September 03, 2007, 08:32:04 AM
Here is an example in C++

What i mean by Well ordered numbers is a number like 1234 or 1467 not 1657 see how 6 is bigger than 5 they need to be in ascending order.

#include <iostream.h>

int main() {
int countPrinted = 0;
int tempNumber;
bool wellOrdered;

for(int i=1000;  i<9999; i++) {
tempNumber = i;
wellOrdered = true;
while(wellOrdered && tempNumber > 9) {
wellOrdered = tempNumber%10 > tempNumber%1000/10;
tempNumber /= 10;
}

if(wellOrdered) {
cout << i;
countPrinted++;
if(countPrinted == 8) {
cout << endl;
countPrinted = 0;
}
else {
cout << '\t';
}
}
}
}
Title: Re: Loop problem
Post by: hutch-- on September 03, 2007, 09:21:33 AM
Paul,

What you seem to be after is sorted results at an integer level. If the integer count is low use a sort type dedicated to small volume like a bubble sort or an insertion sort.
Title: Re: Loop problem
Post by: dsouza123 on September 03, 2007, 09:30:58 AM
OK, now it is clear.

Here it is :

.data
  done       dd 0               
  szNumber   db "0000",13,10,0,0

.code
start:
  mov done, 0
  mov szNumber+0, "1"
  mov szNumber+1, "0"
  mov szNumber+2, "0"
  mov szNumber+3, "0"

  .while done == 0
    mov eax, dword ptr szNumber
    .if ah > al
       mov edx, eax
       shr edx, 8
      .if dh > dl
         bswap eax
        .if al > ah
           print offset szNumber
           invoke Sleep, 1
        .endif
      .endif
    .endif

    inc szNumber+3
    .if szNumber+3 > "9"
       mov szNumber+3, "0"
       inc szNumber+2
    .endif
    .if szNumber+2 > "9"
       mov szNumber+2, "0"
       inc szNumber+1
    .endif
    .if szNumber+1 > "9"
       mov szNumber+1, "0"
       inc szNumber+0
    .endif
    .if szNumber+0 > "9"
       mov szNumber+0, "0"
       mov done, 1
    .endif
  .endw

  invoke ExitProcess, 0
end start

[attachment deleted by admin]
Title: Re: Loop problem
Post by: ~Paul~ on September 03, 2007, 09:39:57 AM
Thanks guys, ill have a look through your code dsouza and try gather an understanding from it. And ill look into the bubble sorting method thanks hutch.
Title: Re: Loop problem
Post by: dsouza123 on September 03, 2007, 09:48:14 AM
Just saw in your code that you count the well ordered numbers.
This slightly revised code includes the count.


.data
  done       dd 0
  count      dd 0
  szNumber   db "0000",13,10,0,0

.code
start:
  mov done, 0
  mov count, 0
  mov szNumber+0, "1"
  mov szNumber+1, "0"
  mov szNumber+2, "0"
  mov szNumber+3, "0"

  .while done == 0
    mov eax, dword ptr szNumber
    .if ah > al
       mov edx, eax
       shr edx, 8
      .if dh > dl
         bswap eax
        .if al > ah
           print offset szNumber
           invoke Sleep, 1
           inc count
        .endif
      .endif
    .endif

    inc szNumber+3
    .if szNumber+3 > "9"
       mov szNumber+3, "0"
       inc szNumber+2
    .endif
    .if szNumber+2 > "9"
       mov szNumber+2, "0"
       inc szNumber+1
    .endif
    .if szNumber+1 > "9"
       mov szNumber+1, "0"
       inc szNumber+0
    .endif
    .if szNumber+0 > "9"
       mov szNumber+0, "0"
       mov done, 1
    .endif
  .endw

  print chr$(" "),13,10
  print ustr$(count),13,10
 
  invoke ExitProcess, 0
end start
Title: Re: Loop problem
Post by: MichaelW on September 03, 2007, 09:53:01 AM
I think a more accurate description of the problem would be something more like "list all well-ordered sets of 4 numbers with the well-order relation <".

http://en.wikipedia.org/wiki/Well-order

It seems to me that if you are dealing with single-digit decimal numbers, then 0 qualifies, and the total number of sets is 210 (instead of 126).

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      cnt1 dd 0
      cnt2 dd 0
      cnt3 dd 0
      cnt4 dd 0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    ; Instead of testing all possible sets, generate only the valid sets.
    ; The first digit must be in the range 1 to 6.
    ; The second digit must be in the range first digit+1 to 7
    ; The third digit must be in the range second digit+1 to 8
    ; The fourth digit must be in the range third digit+1 to 9

    mov ebx, 1
    .WHILE ebx < 7            ; first digit loop ebx = 1 to 6
      mov esi, ebx
      inc esi
      .WHILE esi < 8          ; second digit loop esi = ebx+1 to 7
        mov edi, esi
        inc edi
        .WHILE edi < 9        ; third digit loop edi = esi+1 to 8
          mov ebp, edi
          inc ebp
          .WHILE ebp < 10     ; fourth digit loop ebp = edi+1 to 9
            print ustr$(ebx)
            print ustr$(esi)
            print ustr$(edi)
            print ustr$(ebp),9
            inc ebp
            inc cnt4
          .ENDW
          inc edi
          inc cnt3
        .ENDW
        inc esi
        inc cnt2
      .ENDW
      inc ebx
      inc cnt1
    .ENDW
    print chr$(13,10)
    print ustr$(cnt1),13,10
    print ustr$(cnt2),13,10
    print ustr$(cnt3),13,10
    print ustr$(cnt4),13,10

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


1234    1235    1236    1237    1238    1239    1245    1246    1247    1248
1249    1256    1257    1258    1259    1267    1268    1269    1278    1279
1289    1345    1346    1347    1348    1349    1356    1357    1358    1359
1367    1368    1369    1378    1379    1389    1456    1457    1458    1459
1467    1468    1469    1478    1479    1489    1567    1568    1569    1578
1579    1589    1678    1679    1689    1789    2345    2346    2347    2348
2349    2356    2357    2358    2359    2367    2368    2369    2378    2379
2389    2456    2457    2458    2459    2467    2468    2469    2478    2479
2489    2567    2568    2569    2578    2579    2589    2678    2679    2689
2789    3456    3457    3458    3459    3467    3468    3469    3478    3479
3489    3567    3568    3569    3578    3579    3589    3678    3679    3689
3789    4567    4568    4569    4578    4579    4589    4678    4679    4689
4789    5678    5679    5689    5789    6789
6
21
56
126



Title: Re: Loop problem
Post by: Ian_B on September 03, 2007, 11:45:51 PM
Michael, I so like your style.  :U
Title: Re: Loop problem
Post by: hutch-- on September 04, 2007, 12:37:24 AM
I wonder if you could shove the 210 results into a table and make it fast as well ?
Title: Re: Loop problem
Post by: ~Paul~ on September 04, 2007, 05:37:00 AM
Looks very good Michael except they must be between 1000 and 9999. Very nice job though ill have a look at it and see if i can get an idea of how to fix mine ;)
Title: Re: Loop problem
Post by: ~Paul~ on September 04, 2007, 06:36:07 AM
Sorry Michael do you think you could comment your code a little, i am not understanding the while loops, probably because they are to organised  :P

Edit: What i mean by comment is what does each while loop do. Not that i need to know what inc and mov :P
Title: Re: Loop problem
Post by: MichaelW on September 04, 2007, 07:38:53 AM
Done. A maximum of 126 loops on the inner loop is much better than ~9000 on the outer loop and many more on the inner loop.
Title: Re: Loop problem
Post by: ~Paul~ on September 04, 2007, 07:43:12 AM
How would i make that code print 8 well ordered numbers on each it is printing 10. I had a problem even printing 2 on my one >.<
Title: Re: Loop problem
Post by: MichaelW on September 04, 2007, 08:06:25 AM
I think you would need to maintain an extra counter in the inner loop to keep track of the number of numbers on the line, and when the counter after incrementing reached 8 print a CRLF and reset the counter to zero.
Title: Re: Loop problem
Post by: ~Paul~ on September 04, 2007, 11:19:01 AM
Alright i think i have it now :U Thanks everyone for all the help.
Title: Re: Loop problem
Post by: Mirno on September 04, 2007, 03:16:31 PM
If 1111 is considered "well ordered" you can do:

.data
  szNumber db "1111", 13, 10

.code
  mov ecx, offset szNumber
  xor edx, edx

while_loop:
  mov eax, "9999"
  sub eax, [ecx]
  jz the_end

  test eax, 000FFFFFFh
  jnz @F
  mov al, BYTE PTR [ecx + 0]
  add al, 1

  mov BYTE PTR [ecx + 0], al
  mov BYTE PTR [ecx + 1], al
  mov BYTE PTR [ecx + 2], al
  mov BYTE PTR [ecx + 3], al
  jmp while_loop

@@:
  test eax, 00000FFFFh
  jnz @F
  mov al, BYTE PTR [ecx + 1]
  add al, 1

  mov BYTE PTR [ecx + 1], al
  mov BYTE PTR [ecx + 2], al
  mov BYTE PTR [ecx + 3], al
  jmp while_loop

@@:
  test eax, 0000000FFh
  jnz @F
  mov al, BYTE PTR [ecx + 2]
  add al, 1

  mov BYTE PTR [ecx + 2], al
  mov BYTE PTR [ecx + 3], al
  jmp while_loop

@@:
  add BYTE PTR [ecx + 3], 1
  jmp while_loop

the_end:


No point looping back to zero after all.