NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

## All the Perl that's Practical to Extract and Report

### Journal of ambs (3914)

Monday September 22, 2008
03:16 PM

### How would you write factorial?

[ #37511 ]

There are a lot of ways to write a factorial function in Perl, from the more recursive functional approach, to the standard iterative solution.

I prepared a bunch (well, four for now). If you have any other creative way of coding this function, please let me know (by email or commenting here). Note that I am more interested in the algorithm than in the golfing or obsfuscation.

Solution 1: Recursive is beautiful

sub factorial {
my \$v = shift;
if (\$v > 1) {
return \$v * factorial(\$v-1);
} else {
return \$v;
}
}

Solution 2: Iterative is fast

sub factorial {
my \$v = shift;
my \$res = 1;
while (\$v > 1) {
\$res *= \$v;
\$v--;
}
return \$res;
}

Solution 3: Perl is a dynamic language

sub factorial {
my \$v = shift;
return eval (join "*", (1..\$v));
}

Solution 4: There are other ways of iteration

sub factorial {
my \$v = shift;
my \$res = 1;
grep {\$res*=\$_} (1..\$v);
return \$res;
}

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.

Full
Abbreviated
Hidden
• #### Memoize and bignum(Score:2)

In my Mastering Perl class, I also show Memoize for the recursive solution, and bignum for all the solutions.

So, are you working on this as an article for TPR? :)

• #### shouldn't this be optional(Score:1)

sub fact
{
my ( \$n ) = @_;

my @s = ();
\$s[0] = 1;

foreach my \$m ( 1 .. \$n )
{
\$s[\$m] = 0;
for( my \$k = \$m;\$k>=1;\$k--)
{

• #### re: How would you write factorial?(Score:1)

Note that I am more interested in the algorithm than in the golfing or obsfuscation.

I wouldn't call this golfing or obfuscation. It's another take on the classic recursive algorithm, and might not be interesting. Anyway, here's how I'd write the recursive version:

``` sub factorial {     my \$v = shift;     return 1 if \$v == 1;     return \$v * factorial( \$v - 1 );} ```

I like to get the terminating case out of the way early on, and then read the meat of the algorithm (or soy of the al

• #### reduce(Score:2)

use List::Util qw(reduce);
sub factorial {
my \$v = shift;
return reduce { \$a * \$b } 1 .. \$v;
}

Too bad it produces spurious warnings:

``` Name "main::a" used only once: possible typo at test.pl line 5. Name "main::b" used only once: possible typo at test.pl line 5. ```

• #### Iterative, but not C-ish, but straightforward(Score:1)

sub factorial {
my \$f = 1;
\$f *= \$_ for 2 .. shift;
\$f;
}

• #### Re:(Score:2)

I would write it in a similar way too.