To Start ACM(Volume1 Problem 100): 3n+1

This isn't optimized but it should give you the answer they are looking for.



.586
.MODEL FLAT, STDCALL

INCLUDE \masm32\include\kernel32.inc
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDE \masm32\include\user32.inc
INCLUDELIB \masm32\lib\user32.lib
INCLUDE \masm32\include\masm32.inc
INCLUDELIB \masm32\lib\masm32.lib

.data

bfr DB 100 DUP(0)
comma DB ",", 0
dwtoaBfr DB 10 DUP(0)
n DD 22

.code

Start:

invoke dwtoa, 22, OFFSET dwtoaBfr
invoke lstrcat, OFFSET bfr, OFFSET dwtoaBfr
invoke lstrcat, OFFSET bfr, OFFSET comma
mov ebx, 3
mov ecx, 2

@@LoopAgain:
xor edx, edx
mov eax, n
cmp eax, 1
jbe @@Exit
div ecx
or edx, edx
jz @@EvenNumber
mov eax, n
mul ebx
inc eax
mov n, eax
push ebx
push ecx
invoke dwtoa, eax, OFFSET dwtoaBfr
invoke lstrcat, OFFSET bfr, OFFSET dwtoaBfr
invoke lstrcat, OFFSET bfr, OFFSET comma
pop ecx
pop ebx
jmp @@LoopAgain
@@EvenNumber:
mov n, eax
push ebx
push ecx
invoke dwtoa, eax, OFFSET dwtoaBfr
invoke lstrcat, OFFSET bfr, OFFSET dwtoaBfr
invoke lstrcat, OFFSET bfr, OFFSET comma
pop ecx
pop ebx
jmp @@LoopAgain

@@Exit:

invoke MessageBox, 0, OFFSET bfr, 0, 0
invoke ExitProcess, 0

END Start


Output: 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1


I forgot, it's would be better to increase the buffer or do a dynamic memory allocation since we don't know the size of the output. :) We could be in trouble if the buffer is full and we aren't finish yet. And I still don't know how to use vkim's debug :) I'll experiment soon.
Posted on 2002-03-05 16:57:15 by stryker
That is part of the problem - read further down the page...
The Input
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 10,000 and greater than 0.

You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.
Posted on 2002-03-05 17:15:31 by bitRAKE
Oh Ok, caught me skimming :)
Posted on 2002-03-05 17:16:42 by stryker
It's nice to see you start! Please, don't take all the easy
ones - I need some to work on. :tongue:
Posted on 2002-03-05 17:18:04 by bitRAKE
Here's an update.



.586
.MODEL FLAT, STDCALL

INCLUDE \masm32\include\kernel32.inc
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDE \masm32\include\user32.inc
INCLUDELIB \masm32\lib\user32.lib
INCLUDE \masm32\include\masm32.inc
INCLUDELIB \masm32\lib\masm32.lib

.data

space DB " ", 0
newline DB 0Dh, 0Ah, 0
n DD 22

.data

Bfr DB 10 DUP(?)

Heaphandle DD ?
HeapPointer DD ?

.code

Start:

mov eax, n
cmp eax, 10000
ja @@Exit
or eax, eax
jl @@Exit

mov ebx, 3
mov edx, 1
xor ecx, ecx
push eax
push ecx

@@LoopAgain:
pop ecx
inc ecx
push ecx
mov ecx, 2
xor edx, edx
mov eax, n
cmp eax, 1
jbe @@Exit
div ecx
or edx, edx
jz @@EvenNumber
mov eax, n
mul ebx
inc eax
mov n, eax
pop ecx
push eax
push ecx
jmp @@LoopAgain
@@EvenNumber:
mov n, eax
pop ecx
push eax
push ecx
jmp @@LoopAgain
@@Exit:

pop ecx
;Allocate here

@@:
or ecx, ecx
je @f
pop eax
push ecx
invoke dwtoa, eax, OFFSET Bfr
invoke MessageBox, 0, OFFSET Bfr, 0, 0
pop ecx
dec ecx
jmp @b

@@:

invoke ExitProcess, 0



END Start


When you pop ecx, it will give the number of cycle lengths. This value can be used to determine the size of bytes to allocate (ecx*4 will create an array of dwords). Then after successfully allocating memory, start at the end of the array going to the first array, while popping the values to eax and placing them on the array as you go along. The result will be the same as the one above. I can't finish this one because my next class is up next, GTG. :) If you compile this program it will start in reverse order:
1 2 3 4 16 5 10 20 40 13 26 52 17 34 11 22. I have to go now. I was just doing this for fun. :)

edit()
instead of pushing the value eax to the stack, maybe you can print it directly to vkims debug, after that, pop ecx and print the cycle length...that way, you'll be saved from dynamic memory allocation and reduce instrutions. :)
Posted on 2002-03-05 18:12:09 by stryker

instead of pushing the value eax to the stack, maybe you can print it directly to vkims debug, after that, pop ecx and print the cycle length...that way, you'll be saved from dynamic memory allocation and reduce instrutions. :)
That's what I had in mind. Or, maybe make a console application template for the problems that work with file redirection - this will ease testing for correctness.
Posted on 2002-03-05 18:57:10 by bitRAKE
I'll use my own GUI :) ... This GUI will be the one I'll use throughout the examples. This program is the same as the first one but has a nicer interface. I also added a new feature that will show you the number of cycle lengths.

Controls: Right click on the title bar to popup a menu.

If you want to experiment more values. Read the ACM100.README file for instructions.


[Posted on 2002-03-06 20:03:07 by stryker
stryker, very nice work! I played with it for a while.
Works very well. Only thing that would make it better is
to have random input from a file, or dialog.
Posted on 2002-03-06 22:46:09 by bitRAKE
I updated the one above. I remove some redundant codes. You can now go and click options, a new dialog box will popup. You are limited to 5 characters only (10000 == 5 characters). Limit range is still 0 to 10000. You can't enter negative on the edit box cause I added an ES_NUMBER attribute to the edit box. :) This is to ensure the input is not less than 0. But if you take a look at my code, there is still error checking if the value of N < 0 and > 10000. If the value is not in range, nothing will show up.
Posted on 2002-03-06 22:48:30 by stryker
I thought from the question that you were supposed to be able to go from some "i" to some "j"

in otherwords... If you picked

20 10
it would find the values beween those numbers

maybe I read it wrong...

Sliver

Good job though... The question just confused me a little

I think I'll do the Roman Roulette :-) Sounds fun
Posted on 2002-03-06 23:45:20 by Sliver
Me too, I didn't understand what the i and j is for. I just converted the pseudo code(algorithm) they have. :). I think I need to read further, i think it has to have 2 user inputs ooops. he he he :) I'll release another fix if I have the time. I hate reading problems. Anyway, enjoy the translated pseudo code as of this time. :) And this too will teach you on how to handle multiple dialog boxes, centering it, right click menus...(this is suppose to hit 2 birds on one stone but the other bird had a back up wings, so it could fly and escape the wrath :) )
Posted on 2002-03-06 23:47:26 by stryker
It's their own fault for describing it one way and giving example outputs another :)

There are so many damn examples i want to do :)

Thanks BitRAKE...

ps. too bad it's 1 am :(
Posted on 2002-03-06 23:52:51 by Sliver
I think I'm getting into something, my mistake.

- i and j must have a value of 1 - 9999 only. Not 0 - 10000
- First line of input corresponds to the first two numbers of output and the last number of the output is the maximum cycle length...
- each number on the printed line must be separated by a space



Sample Input
1 10
100 200
201 210
900 1000


Sample Output
(Same as the first 2 numbers of the input but
I don't undertand the 20 why 20? )
1 10 20
100 200 125
201 210 89
900 1000 174



the thing that stumped me is this description of the problem ...and the maximum cycle length for integers between and including i and j. What do they mean about between and including i and j? The summation of the center values of i and j plus i and j?:confused:

I'm not sure but the center value of 10 is 8. If i is 1 and j is 10
so centerof(i) + centerof(j) + i + j = 20, which is equal to 1 + 8 + 1 + 10 = 20 ???

I also tried 100 and 200, still no luck :confused: :mad: There are a lot of values in "between"



;This is i = 1
[color=blue]1[/color]
Number of Cycle Lengths: 1

;This is j = 10
[color=blue]10 5 16 8 4 2 1 [/color]
Number of Cycle Lengths: 7

;This is i = 100
[color=blue]100 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1[/color]
Number of Cycle Lengths: 26

;This is j = 200
[color=blue]200 100 50 25 76 38 19 58 29 88 44 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1[/color]
Number of Cycle Lengths: 27
Posted on 2002-03-07 00:12:37 by stryker
They mean to execute the algo for each number between 1 and 10, then output the greatest cycle length as the third digit. The problem is harder than first thought. :)
Posted on 2002-03-07 10:10:59 by bitRAKE
Ahh! stupid me, I was thinking of numbers 1 and 10 and the number of the cycle outputs between both numbers. Not 1 to 10....Ok I'll fix this one. It sure is a lot of fun isn't it. :)
Posted on 2002-03-07 10:25:25 by stryker

It sure is a lot of fun isn't it. :)
I enjoy problem solving a great deal. :grin:
Posted on 2002-03-07 10:35:24 by bitRAKE
Yay, I've done it!!! :) It's already in full working condition. The only problem is if you choose a test case of 900 - 1000 it can't finish doing it's job, I think this is a windows problem :( Maybe the "buffer" that windows used is full, I don't know. But the 3 test cases 1 - 10, 100 - 200 and 201 - 210 are fine. I also attached a text file of the output. Does anyone know why it stops working at the last line of processing when using a test case of 900 - 1000? I mean, it just stops after processing the n value of 4 at the last cycle? any ideas...maybe this would work fine on a console, I don't know?


[Posted on 2002-03-07 12:29:26 by stryker
I believe you have to use RichEdit. :)
Well done - I'll play with it after work...
Posted on 2002-03-07 14:24:40 by bitRAKE
Anyway, I created 2 versions to it. In the first version, you'll see the whole calculations throughout the routine but you'll have problems if you reach the maximum allowed number of characters in an edit control. The second one will just show you only the output, this is what they are looking for but no problems on this one. Would be cool though if we don't have problems with the edit control(we could see how it processes the n value). Anyway, ACM 100 - 3n+1 is solved. :)

I changed the .zip file above.

I'll change it to rich edit If I'm bored. Thanks for the tip. I'll move on with the next.
Posted on 2002-03-07 14:28:35 by stryker
Oh and don't mind the file ACM100Rvsd.zip, I forgot to remove it from the directory I zipped up.

Controls: Right click on title bar to show menu

If you want to see the ACM100 code(ACM3NPLUS1), it's on the first procedure listed on file ACMP100.asm and other code associated with it is after the label @@OPTIONBOX: Line 158 on file ACM100.asm.

:)
Posted on 2002-03-07 16:47:25 by stryker