Monday, September 03, 2007

Factorial of n

Have a look at speed algorithm with shorter coding. I know good programming code is maintainable, readable, speedy. Recently I had a chance to think about good coding becase I need to improve my skill.

Let's think about factorial of n. n!.

Sample Input
3
4
5
6

Sample Output
6
24
120
720

Here is "good" and accepted code. Yes, it works right. This program looks fine and works well. This will be outputing answers.


main(){
int i, a=1, num;
while(EOF != scanf("%d",&num)) {
for(i=1;i<=num;i++){
a*=i;
}
printf("%d\n", a);
a=1;
}
}

Input : Output
3 : 6
4 : 24
5 : 120
6 : 720


You're never satisfied if you are not good coder but code of excellence.

Where/How can I make this program slim? Is there anything I can help it skinny??
Yes, at first, see EOF macro value. This can be replaced with -1. This means ;


while(-1 != scanf("%d",&num))


This means while not -1, read number.... Whatever evaluating, whether breaking this while loop or not is the return value of operator is 0(false) not. scanf returns -1 if it fails to read, which means 0 (false!(-1 != -1)). Break this while loop.

Thinking about covenient co-worker now, two's complement. Well, two's complement of -1 is, you know, 0!! False value!!
So this while loop is coming...


while( ~scanf("%d", &num) )


And then next, we're gonna focus on while loop itself. Do we need it actually? Let's think again loop operator.


while(statement1)...

for(statement1;statement2;statement3)...


They have been told that "same function" (when I was at university! How terrible!). But actually it is not. At first glace, the differences are perfectly clear. # of statement are different.


main(){
int i, a=1, num;
for(;~scanf("%d",&num);) {
for(i=1;i<=num;i++){
a*=i;
}
printf("%d\n", a);
a=1;
}
}


This looks sort of ugly. It seems better that I did not change.... But, the order of evaluation in for loop is statement1, statement2, process in loop and then statement3. What does this mean? Let's change this main function with using "()" and "," co-workers!


main(){
int i, a=1, num;
for(;~scanf("%d",&num);(printf("%d\n", a),a=1))
for(i=1;i<=num;i++)
a*=i;
}


What do you think of it? The great hack points are, omitting brace {} and move printf() and initialization a=1 to for loop operator.

Huumm, that's tough work. The factorial of n gets really smarter from the original one. Yes, you know. lots of your friends say "You did it! Well done!" to you.

Finished??

No. You can do it more and more.

Let's see 2 for loops. Let's squeeze two for for one for b/c all for one, you know.
Plus, do squeeze three valuables for 2 valuables! Yes, we're gonna use this, ? ternary operation.

In the algorithm, program caluculates while scanning number...We can also say, program scans number if the calculation has been finished. Yes, "if" comes up, "if" can go to ternary operation. Calucrate up to 1 readings!

Besides, here comes ~ NOT operation, and two's complement again!! Two's complement of -1 is 0. Two's complement of 0 is -1. Two's complement of 1 is -2. Can you guess what?? This really help it do more smart!!


The shortest code I came up with now is this.


int a;
main(i){
for(i=1;a<1?scanf("%d",&a):--a;a-1||(printf("%d\n",i),i=1,a=0))
i*=-~a-1;
}


That's all(like said, "The devil wears Prada").

1 Comments:

Anonymous Anonymous said...

People should read this.

10:49 PM  

Post a Comment

<< Home