Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

factorial through recursion

by hnd (Scribe)
on Jul 23, 2009 at 19:38 UTC ( [id://782769]=perlquestion: print w/replies, xml ) Need Help??

hnd has asked for the wisdom of the Perl Monks concerning the following question:

why is this piece of code not working?
it shows a syntax error at line 10 and 13

#factorial through recursion use strict; use warnings; print "enter number\n"; my $num=<>; &fact($num,1); print "factorial: \n"; ################## sub fact { my($num1,$flag)=shift; if($num1==0) print "$flag" and die "brrrrrrrreeeeeee :D\n"; else {fact($num1-1,$num1*$flag);} }
=====================================================
i'am worst at what do best and for this gift i fell blessed...
i found it hard it's hard to find well whatever
NEVERMIND

Replies are listed 'Best First'.
Re: factorial through recursion
by blokhead (Monsignor) on Jul 23, 2009 at 19:48 UTC
    In addition to missing braces in the if-statement, you have a problem with this line:
    my($num1,$flag)=shift;
    shift only returns one element from @_. You probably mean:
    my($num1,$flag)=@_;

    blokhead

Re: factorial through recursion
by ikegami (Patriarch) on Jul 23, 2009 at 19:55 UTC

    In addition to the previously mentioned missing curlies,

    • my($num1,$flag)=shift; takes one value from @_ and assigns to the first of two. $flag never gets a value. You want

      my $num1 = shift; my $flag = shift;

      or

      my ($num1, $flag) = @_;
    • Then there's the issue that your program always dies. Return the value you find instead of dying. This will also allow you to remove the print from fact, which is appropriate since finding the factorial of a number has nothing to do with I/O.

    • Finally, it's very weird that your factorial function takes two inputs. That's inconsistent with the mathematical function.

    Solution:

    use strict; use warnings; sub fact { my ($n) = @_; return 1 if $n == 0; return $n * fact($n-1); } die "usage\n" if !@ARGV; print(fact($ARGV[0]), "\n");
      Finally, it's very weird that your factorial function takes two inputs. That's inconsistent with the mathematical function.
      Yes, but I note that his function looks similar to what a helper function would look like in a language with tail recursion optimization. It should still return a value instead of printing it though.
        I have no problem with a helper function having more arguments.
        sub fact { my ($n) = @_; local *_fact = sub { my ($n, $prod) = @_; return $prod if $n == 0; return _fact($n-1, $n*$prod); }; return _fact($n, 1); } fact($n);

        In this case, you could even fake it as follows:

        sub fact { my ($n, $prod) = @_; $prod ||= 1; return $prod if $n == 0; return _fact($n-1, $n*$prod); } fact($n);

        But since Perl doesn't do tail recursion optimisation, and since sub calls are relatively slow, you're better off with:

        sub fact { my ($n) = @_; my $prod = 1; $prod *= $n-- while $n > 0; return $prod; } fact($n);
Re: factorial through recursion
by SuicideJunkie (Vicar) on Jul 23, 2009 at 19:45 UTC
    Specifically, it says near the ") \n\t print"
    You seem to be lacking a curly bracket right there between the ) and the print.
Re: factorial through recursion (diagnostics)
by toolic (Bishop) on Jul 23, 2009 at 20:13 UTC
    You can also use diagnostics; to help debug errors (emphasis is mine).
    (F) Probably means you had a syntax error. Common reasons include +: A keyword is misspelled. A semicolon is missing. A comma is missing. An opening or closing parenthesis is missing.
    An opening or closing brace is missing.
    A closing quote is missing. Often there will be another error message associated with the synt +ax error giving more information. (Sometimes it helps to turn on -w. +) The error message itself often tells you where it was in the line +when it decided to give up. Sometimes the actual error is several toke +ns before this, because Perl is good at understanding random input. Occasionally the line number may be misleading, and once in a blue + moon the only way to figure out what's triggering the error is to call perl -c repeatedly, chopping away half the program each time to se +e if the error went away. Sort of the cybernetic version of S<20 questions>.
Re: factorial through recursion
by imrags (Monk) on Jul 24, 2009 at 06:56 UTC
    Here's something that might work:
    #factorial through recursion use strict; use warnings; print "enter number\n"; my $num=<>; my $fac = &fact($num,1); print "factorial: $fac\n"; ################## sub fact { my($num1,$flag)=@_; if($num1==0) { return $flag; # print "$flag" and die "brrrrrrrreeeeeee :D\n"; } else {fact($num1-1,$num1*$flag);} }
    It's good (better/best) to use return statement in recursive code!
    Also, instead of shift, use @_
    Raghu
Re: factorial through recursion
by Anonymous Monk on Jul 23, 2009 at 19:53 UTC
    brrrrrrrreeeeeee :D

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://782769]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2024-04-24 10:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found