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

Monday September 22, 2008

03:16 PM

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;

}

Full

Abbreviated

Hidden

Stories, comments, journals, and other submissions on use Perl; are Copyright 1998-2006, their respective owners.

## 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? :)

## Re: (Score:2)

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

How about

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)

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)

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)

## Re: (Score:2)

I would write it in a similar way too.