- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Do you think your stack will overflow and only then you will return 42, or is this the invention of the eat-all-my-stack-and-memory recursion function?
Admin
i would have loved to see their faces !
Admin
It's totally possible. I've interviewed people with 10 years experience who basically write this code during the interview. In fact, interview WTFs are so common that I've never even though of submitting them here. We need to get better at phone screens or something...
Admin
I was wondering how long it was going to take for someone to post the TCO-friendly solution. Of course, you also want to have another entry point that just takes n as a param, and calls the tail recursive one.
Admin
I am amazed at how many people here assumed that "n=0" is an assignment, when "factorial n" is not legal in C, C++, C#, Java, Javascript, or any other C-like language. It looks more like Ocaml to me, but there's no "return" in Ocaml. It may be pseudocode.
On a forum like this where many languages are mixed freely, the number of assumptions that a certain snippet must be in some language it plainly cannot be in, or the failure to identify the language it is in when it is painfully obvious (like, say, "TryParse" giving away C#), has always astonished me.
Admin
Admin
Personally, if I were going to do it in Java, it'd be a little something like this.
Admin
I'm going to around compiling comments with incorrect code or people who point flaws in code incorrectly, and submit it all as a WTF.
Admin
Admin
Admin
Actually, this isn't tail recursion at all, since
doesn't directly return the result of a recursive call.Admin
I want to know how many people, who also post on this forum, are actually programmers. I see worse WTFs repeatedly in the comments than article was!
WTF @ Binet's formula to calculate the nth Fib on a computer. WTF @ The several "fixed" factorial algorithms that don't work at all!
Admin
I think it's funny how many of you goobers thought it returned 12 and not 42
Lord help us all
Admin
But factorial is undefined for negative numbers. Wouldn't it be better to generate a compile-time error?
#include <iostream>
template<unsigned long N> class Factorial { public: static unsigned long const result = N * Factorial<N-1>::result; };
template<> class Factorial<0> { public: static unsigned long const result = 1; };
int main(void) { std::cout << "Factorial(1): " << Factorial<1>::result << std::endl;
std::cout << "Factorial(2): " << Factorial<2>::result << std::endl;
std::cout << "Factorial(3): " << Factorial<3>::result << std::endl;
std::cout << "Factorial(4): " << Factorial<4>::result << std::endl;
std::cout << "Factorial(5): " << Factorial<5>::result << std::endl;
return 0; }
Admin
Admin
Java, assuming it's a method in a program so I don't have to type out everything including the input reader and import lines and whatnot:
private int factorial(int n) { if (n < 0) { throw new negativNumException(); } else if (n == 0) { return 1; } else { return (n * factorial(n-1)); } }
Factorials are used to teach recursion in high school. And while I rarely see much use for recursion, this is a text book example that I think is used to teach recursion pretty much everywhere. It's really sad that anyone can get through freshman CS (let alone graduate) in Uni without knowing recursion.
Admin
Perl 6:
Admin
What you have described is nothing to do with "strong" typing. You are describing languages that use a nominal subclassing relationship, as distinct from the structural subclassing relationship found, as you say, in Ruby -- but also found in some statically typed languages like OCaml.
Admin
The real WTF for me is that this guy is so heavily indoctrinated into OOP that he can't even think of writing a simple factorial function without making it a class member.
Admin
That's not a WTF, just a simple misnomer. The function should be called twelve. Since the parameter is never used, we just leave it away and optimize the function's body and obtain:
Now whenever someone needs a twelve, he doesn't have to use magic numbers (evil!), and he can even pass &twelve as a function pointer. Brillant!
Admin
For good measure, here's the recursive version with arbitrary precision in Java, including the necessary checks (which take more space than the actual recursive function):
The main drawback is that this version bails out at circa 63800!, courtesy of a stack overflow.
While it would be possible to increase the VM's stack size at startup (flag -oss), it is definitely better to use an iterative approach for larger factorials, because this is significantly faster (e.g. 40000! takes ~20 secs iteratively, ~60 secs recursively) and only limited by heap size, i.e. when the size of the BigInteger(s) exceeds the available memory.
I tried for instance 500000!, no problem basically, but it took 2 hours 40 mins to complete ;o) (on a 1,7GHz Notebook)
Admin
there's so few values valid for an int input/output.. so just use a lookup table :P
private static int[] factorials = {1,1,2,6,24,120,720,5040,40320,362880,3628800};
public int Factorial(int n) { if (n < 0) throw new ArgumentOutOfRangeException(); else if (n > 10) throw new OverflowException(); else return factorials[n]; }
Admin
Now you lot go and fill in the implementations.
Admin
The simple iterative and recursive algorithms generally taught at University are equally bad in terms of performance. When multiplying large amounts of big integers, it's a big performance no-no to perform many multiplications of factors with great difference in bit length. Performing thousands of multiplications with one very large and one comparatively puny number (which the simple algorithms do) worst-cases the multiplication performance. For much better performance that actually allows big number libraries to make efficient use of Karatsuba's algorithm for large numbers and Schönhage-Strassen multiplication for very large numbers, it is important that as many multiplications as possible use factors of similar bit length, ideally almost equal bit length. There are excellent "true" (i.e. with a branching factor > 1) recursive algorithms that accomplish that, and of course there are also iterative algorithms that work in a similar way. Those tend to use intermediate storage arrays where recursive functions can just use the program stack.
The simple recursive algorithm however combines the worst of both worlds: The multiplication inefficiency of the iterative solution, and a great recursion overhead. Its only advantage is unbeatable simplicity.
For the curious: To compute large factorials it is best to first compute the prime factorizations of the individual factors, or even better to obtain them by table lookup, then add their mulitplicities and compute the final product using a fast split multiplication algorithm.
If approximate precision is acceptable, a formula like Stirling's approximation will do even better, of course.
Admin
Bullshit!
Not defining 0! leads to tons of pointless special cases for binomial coefficients, one of the most important applications of the factorial. 0 is not just one integral number out of infinitely many - whether it's included in a function's domain often makes a huge difference in the number of special cases required later on. The factorial is no exemption from that.
By the way, the factorial of n (where n is an integer >= 0) is defined as the product of all integers i with 1 <= i <= n. But as all true mathematicians know, if n = 0, then this is the empty product, and the value of the empty product is 1 (another 100% sensible and useful definition). Therefore, the definition of 0! does not even require a special case.
That the empty product equals one is logical since one is the neutral element of multiplication. Just as the empty sum equals zero, which is the neutral element of addition, the empty logical and equals true which is the neutral element of logical and, and the empty or equals false which is the neutral element of logical or (likewise for exclusive or).
Admin
What ... is this Language, and who actually uses it .. sober.
http://upload.wikimedia.org/wikipedia/en/f/ff/LifeInApl.gif
poff
Admin
Okay, either I am missing some sarcasm tags (entirely possible) or we are using completely different maths to go through that code.
Can somebody PLEASE explain to me where the 42 as answer to this factorial is coming from?
Admin
I think you did miss the sarcasm tags.
Admin
That's the answer. The function is as follows:
Admin
can someone write code that looks up the answer from google?
Admin
You mean 42
Admin
This guy has revolutioned computing demonstrating that O(n!) can be solved in constant time 12
Admin
Not to worry. He's in High School. By the time he graduates from college, computers will be so fast this will return in, like, 3 seconds.
Captcha: smile. Because irony feels good.
Admin
Hah! You think factorial is the worst situation for recursion?? I had a professor that taught recursion in a program that had like 6 functions you had to use recursion to solve. One of these functions was to initialize an array with a given number... seriously!?!? I had to help students on that program... and then in the higher classes I had to teach them recursion because they learned nothing from his class!
Admin
Psh, I've seen recursive constructors
Admin
is this a nerd joke?
Admin
for i=0; i<10; i++ i = i * (i+1) a = i
return a
first iteration is trivial, i++ second iteration: i=1 before loop starts loop starts i = 1 * (1+1) = 1*2 = 2 i++ i = 3
third iteration i=3 when loop begins 3<10?, YES i = 3 * (3+1) = 3*4 = 12 i++ --> i = 13!
fourth iteration i=13 BEFORE LOOP STARTS 13<10? NO return a=13
287 replies on this post and not one with the right answer. incredible
Admin
HILARIOUS :)))))))))))
Admin
int factorial(int n) { return n *= (n - 1 > 0) ? factorial(n - 1) : 1; }
in one messy line! :P nobody would hire me either :'(
Admin
^heh i mean n > 1 of course! i fail.
Admin
I know this is like 2 months after the fact, but the college I am currently going to does a really good job with computer science graduates. You learn what recursion and how to do a factorial the 2nd week of class... So, just to let you guys know, not all recently graduated computer science graduates have no business or computer sense.
Admin
I just have to say it....
The never ending loop of f(n){ n*f(n) }. Awesome
Even better.... Any of you kids know what n*0 is?
Admin
sub Factorial($) { my ($i, $a) = (1, int(shift)); return -1 if not defined $a or $a<=0; $i *= $a-- while($a); return $i; }
Admin
Ladieeeees and Genn'lemen, for yoooooooooor en-tah-tainment, a Blazing Guitarpocalypse of Recursion and Iteration.
My own effort, in Java: public static double recfactorize(double tofactor){ if(tofactor<=1){return 1;} return tofactor*factorize(tofactor-1); }
public static double iterfactorize(double tofactor){ double returned = 1; for(double ii=tofactor; ii>0; ii--){ returned = returned*ii; } return returned; }
I found that for even small values of tofactor (less than 20), you get int issues. You can use a double (BigInteger made my runtime/eyeballs cry), but that won't prevent recursive stack issues with the recursive method. And even below that, beyond 171 you get "Infinity" as a result.
Mind you, if anything you're doing requires you to use the actual value of 200!, you're probably doing it wrong.
Admin
And I've just remembered how to do tail-recursion, thanks to Wikipedia (feeling very dim)
Addendum (2007-11-25 13:58): And I've just remembered how to do tail-recursion, thanks to Wikipedia (feeling very dim)
Edit: And this won't work, and I'm not sure why. Feeling even dimmer!
Admin
actually, that can be simplified:
def factorial(n): return reduce(n.mul, range(1, n + 1), 1)
i admit that mul isn't as straightforward as a lambda, but it's a lot cooler, and reduce has a third optional element to use as a default value
know your builtins, people!
Admin
public int factorial(int n) { int a = 0; for (int i = 1; i < 10; ) a = i = i * (i + 1); return a; }
Actually, this DOESN'T call down to factorial(0)... So your point is moot! (fwiw, the fact that 0! != 0 was already mentioned, more than a couple of times)Admin
let's try this:
Admin
We need to optimize the way we calculate factorials recursively! It takes to loooong!
Test it in the browser and see for yourself!