Stories
Slash Boxes
Comments
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

use Perl Log In

Log In

[ Create a new account ]

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
More | Login | Reply
Loading... please wait.
  • 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? :)

  • 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--)
                    {
                       

  • 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

  • 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.

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