Search code examples
lispautocadautolisp

i did not factorial in this autolisp


I try to factorial for in this code but, I did not get the answer.

  (defun fact(n)

  (if (= n 0)

    (setq n 1)

    (setq pr (* n ( fact (- n 1))))
        
    (print pr)

    )

Solution

  • The issue is that you are supplying too many arguments to the if expression in your code. An if statement will accept at most 3 arguments:

    1. A test expression
    2. A 'then' expression
    3. An optional 'else' expression

    In your code, you are supplying 4 arguments:

    1. (= n 0)

    2. (setq n 1)

    3. (setq pr (* n ( fact (- n 1))))

    4. (print pr)

    You are also missing a closing parenthesis.

    To correct your code, the final print expression can be moved outside of the if expression, and the pr variable should be declared as a local variable i.e.:

    (defun fact ( n / pr )
        (if (= n 0)
            (setq n 1)
            (setq pr (* n (fact (- n 1))))
        )
        (print pr)
    )
    

    However, whilst the code is syntactically correct, you will now receive the error:

    ; error: bad argument type: numberp: nil

    This is because, when n is 0, the variable pr is not defined and so the print expression will return nil, causing the multiplication with the return of the recursive call to fail.

    However, whilst the code could be modified to define pr when n=0, this variable is not actually required, and the code may become:

    (defun fact ( n )
        (if (< 0 n) (* n (fact (1- n))) 1)
    )
    

    The function will now return the value of the calculated factorial:

    _$ (fact 5)
    120