• Welcome to the new Internet Infidels Discussion Board, formerly Talk Freethought.

Software Projects for Beginners

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.


void main() {
int i;
for (i = 1; i <= 100; i++){
if (!(i % 3) && !(i % 5)) printf("FUZBUZ\n");
else if(!(i % 5)) printf("FUZ\n ");
else if(!(i % 3)) printf("BUZ\n ");
.else printf("%3d \n ", i); }
}

Do I get the job?
 
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.


void main() {
int i;
for (i = 1; i <= 100; i++){
if (!(i % 3) && !(i % 5)) printf("FUZBUZ\n");
else if(!(i % 5)) printf("FUZ\n ");
else if(!(i % 3)) printf("BUZ\n ");
.else printf("%3d \n ", i); }
}

Do I get the job?

Your programming may be ok but you fail at reading requirements.

It's supposed to be Fizz/Buzz/Fizzbuzz, not BUZ/FUZ/FUZBUZ.

Also, your algorithm has to do 3-4 division for each number where 2 should suffice if you remember the result.
 
Also, your algorithm has to do 3-4 division for each number where 2 should suffice if you remember the result.

I personally might code it as Jokodo implies (if only for brevity), but with today's smart optimizers that might not be any faster.

I inspected the output of 'gcc -O' and verified that, yes, it does only TWO multiplications, not four. (The code does appear bizarrely complicated, but I was insufficiently motivated to try variations on Steve's code.)

Yes, I wrote 'multiplication,' not 'division.' For the '%3' gcc starts by multiplying by 1431655766; and for '%5', 1717986919. :)
 
Hilarious.


By all means, post an optimized code. But to prove it is optimized and worth the time spent you would have to look at the assembly code generated by the compiler, count the number of bytes or words, and time the execution with a debugger.

Debuggers will typically give you execution time in number of clock cycles.

There is always a tradeoff between time, optimization, and being clever. One can be too clever in making things compact.
 
#define s a + b;
int f(int a, int b) { return(a + b); }
void main() {
int k,a =1, b=2,c;
c = f(a, b);
k = s;
printf("c %d k %d\n",c,k);

}For the beginner, what if any are the differences betwen using s and f()?
 
I am not familiar with the current assmebly language for Intel processors, but the flow can be sn.

High level code generates assembly language. MOV is between processor and phyasical memory.

Hex numbers on the left are memory offsets from main()

https://www.cs.virginia.edu/~evans/cs216/guides/x86.html

void main() {
int x, y, z;
x = 2;
y = 3;
z = x + y;
}


int x, y, z;
x = 2;
00981828 mov dword ptr [x],2
y = 3;
0098182F mov dword ptr [y],3
z = x + y;
00981836 mov eax,dword ptr [x]
00981839 add eax,dword ptr [y]
0098183C mov dword ptr [z],eax
 
A simple loop.

for (i = 0; i < 4; i++) x = 2 * i;
00CF4468 mov dword ptr ,0
00CF446F jmp main+3Ah (0CF447Ah)
00CF4471 mov eax,dword ptr
00CF4474 add eax,1
00CF4477 mov dword ptr ,eax
00CF447A cmp dword ptr ,4
00CF447E jge main+54h (0CF4494h)
00CF4480 mov eax,dword ptr
00CF4483 shl eax,1
00CF4485 cvtsi2ss xmm0,eax
00CF4489 mov ecx,dword ptr
00CF448C movss dword ptr x[ecx*4],xmm0
00CF4492 jmp main+31h (0CF4471h)
 
The code I wrote.

void main() {
int i,flag;
for (i = 0; i < 4; i++) {
if (!(i % 3) && !(i % 5))flag = 2;
if (!(i % 3) && !(i % 5))flag = 2;
else if (!(i % 5))flag = 0;
}

}
for (i = 0; i < 4; i++) {
00BF4468 mov dword ptr ,0
00BF446F jmp main+3Ah (0BF447Ah)
00BF4471 mov eax,dword ptr
00BF4474 add eax,1
00BF4477 mov dword ptr ,eax
00BF447A cmp dword ptr ,4
00BF447E jge main+97h (0BF44D7h)
if (!(i % 3) && !(i % 5))flag = 2;
00BF4480 mov eax,dword ptr
00BF4483 cdq
00BF4484 mov ecx,3
00BF4489 idiv eax,ecx
00BF448B test edx,edx
00BF448D jne main+67h (0BF44A7h)
00BF448F mov eax,dword ptr
00BF4492 cdq
00BF4493 mov ecx,5
00BF4498 idiv eax,ecx
00BF449A test edx,edx
00BF449C jne main+67h (0BF44A7h)
00BF449E mov dword ptr [flag],2
00BF44A5 jmp main+95h (0BF44D5h)
else if (!(i % 3))flag = 1;
00BF44A7 mov eax,dword ptr
00BF44AA cdq
00BF44AB mov ecx,3
00BF44B0 idiv eax,ecx
00BF44B2 test edx,edx
00BF44B4 jne main+7Fh (0BF44BFh)
00BF44B6 mov dword ptr [flag],1
00BF44BD jmp main+95h (0BF44D5h)
else if (!(i % 5))flag = 0;
00BF44BF mov eax,dword ptr
00BF44C2 cdq
00BF44C3 mov ecx,5
00BF44C8 idiv eax,ecx
00BF44CA test edx,edx
00BF44CC jne main+95h (0BF44D5h)
00BF44CE mov dword ptr [flag],0
}
00BF44D5 jmp main+31h (0BF4471h)

}
 
And a version minimizing the divisions. I haven't figured out how ro use the VS debugger to do timing and memory analysis.


void main() {
int i,_3,_5,flag;
for (i = 0; i < 4; i++) {
_3 = i % 3;
_5 = i % 5;
if (!_3 && !_5)flag = 2;
else if(!_3)flag = 1;
else if(!_5)flag = 0;
}

}

int i,_3,_5,flag;
for (i = 0; i < 4; i++) {
00B74468 mov dword ptr ,0
00B7446F jmp main+3Ah (0B7447Ah)
00B74471 mov eax,dword ptr
00B74474 add eax,1
00B74477 mov dword ptr ,eax
00B7447A cmp dword ptr ,4
00B7447E jge main+8Fh (0B744CFh)
_3 = i % 3;
00B74480 mov eax,dword ptr
00B74483 cdq
00B74484 mov ecx,3
00B74489 idiv eax,ecx
00B7448B mov dword ptr [_3],edx
_5 = i % 5;
00B7448E mov eax,dword ptr
00B74491 cdq
00B74492 mov ecx,5
00B74497 idiv eax,ecx
00B74499 mov dword ptr [_5],edx
if (!_3 && !_5)flag = 2;
00B7449C cmp dword ptr [_3],0
00B744A0 jne main+71h (0B744B1h)
00B744A2 cmp dword ptr [_5],0
00B744A6 jne main+71h (0B744B1h)
00B744A8 mov dword ptr [flag],2
00B744AF jmp main+8Dh (0B744CDh)
else if(!_3)flag = 1;
00B744B1 cmp dword ptr [_3],0
00B744B5 jne main+80h (0B744C0h)
00B744B7 mov dword ptr [flag],1
00B744BE jmp main+8Dh (0B744CDh)
else if(!_5)flag = 0;
00B744C0 cmp dword ptr [_5],0
00B744C4 jne main+8Dh (0B744CDh)
00B744C6 mov dword ptr [flag],0
}
00B744CD jmp main+31h (0B74471h)

}
 
Back
Top Bottom