Hi,

To give you a hint without actually solving the original problem, which is your task, and perhaps confuse you a little bit more, here's a definition of tail-recursive Factorial that given an non-negative integer N returns the list of successive factorials from in increasing order from 0! to N!, i.e., [0! 1! ... N!]:

declare
Factorial =
local
    fun {Factorial N I Head Tail Last}
        if I>N
        then Tail=nil Head
        else NewLast=I*Last NewTail in
            Tail=NewLast|NewTail
            {Factorial N I+1 Head NewTail NewLast} end end
    Tail in
    fun {$ N}
        if N==0
        then [1]
        else {Factorial N 1 1|Tail Tail 1} end end end

{Browse {Factorial 5}}
% [1 1 2 6 24 120]

(pardon me the idiosyncratic formatting).

vQ



On 09/29/2010 06:57 PM, Peter Breitsprecher wrote:
Raphael, Lyle,
Thank you for the responses, and Lyle, I did play with it for quite a while before I looked at your code.... My code didn't give me the right result, it didn't create a list, or it didn't run. However when I looked at Lyle's code, it was similar to mine, only he had an extra value that I wasn't using(which could have been why it wasn't working for me. Then I looked at lyles code put in in Oz, and it doesn't give me the desired result either. When it runs(and when I stepped through it it seemed logical), it gave me the result [6 2 1 1].

So then instead of if I==N then Acc, I tried every other combination I thought would work, I started Acc at nil, but that obviously didn't work, then I tried I==N+1 which gives me the proper end result in 24, but the list looks like [24 6 2 1 1].

I'm a little confused as to where the extra value comes from. I can only assume that it is from when we initalize the list in the {Fact N} Function because it starts Acc as [1]. So I assume it takes that 1 puts it in there then multiplies it by one and then puts the second one in after the first pass. I must be able to initialize Acc to nil and make if I==N then 1, but it doesn't seem to work.

I thought this should be way easier than it has been... and then we go from this assignment to creating a French Parser, and out Project is a Scheme Interpreter.... My head was spinning as it is before this....


    Dear Peter,

    It is indeed possible to turn the factorial list function into a tail
    recursive one.

    Think about how to build the list with an accumulator, such that
    the final
    result is the last value of the accumulator.  Each element of the list
    depends on the element that comes next, therefore you should build
    the list
    from right to left.  Successive values of the accumulator should be:

      [1]
      [2 1] = 2|[1]
      [6 2 1] = 6|[2 1]
      [24 6 2 1] = 24|[6 2 1]

    Consider you loop over an index going from 1 to N, and you should
    be able to
    write a tail recursive function that uses the accumulator as I
    described
    above, and returns the expected list at the end.

    Good luck :-)
    Raphael

    On Wed, Sep 29, 2010 at 6:44 PM, Peter Breitsprecher
    <[email protected] <mailto:[email protected]>>wrote:

    > Ok I admit It I am stumped.  I know I'm new to this Language,
    but I'm
    > trying and want to learn.  We were given this code.
    >
    > fun {Fact N}
    >      if N==1 then [N]
    >      else
    >           Out={Fact N-1}
    >      in
    >           N*Out.1|Out
    >      end
    > end
    >
    > Example of execution:  {Fact 4} -> [24 6 2 1]
    >
    > He asked if this program is tail recursive, which it is not,
    because the
    > recursion needs to be the last operation, and in this case the last
    > operation is the N*Out.1.
    >
    > So I wrote these two pieces of code.
    >
    > This one you need to pass the Accumulator to in the function call
    >
    > fun {Fact N Acc}
    >    if N==1 then Acc
    >    else
    >       {Fact N-1 N*Acc}
    >    end
    > end
    >
    > And this one that uses another function to loop.
    >
    > fun {Fact N}
    >    fun {FactLoop N Acc}
    >       if N == 0 then Acc
    >       else
    >      {FactLoop N-1 N*Acc}
    >       end
    >    end
    > in
    >    {FactLoop N 1}
    > end
    >
    > Now my problem is that I get the end result of 24 with these
    programs, but
    > I can't get them to display a list like in the example the
    professor gave
    > us.
    >
    > How do I change my code, or make the Professor code so that it
    is tail
    > recursive and still produce a list.  In Part B of the question
    it is to
    > order the list of factorials from smallest to largest, which I
    have finished
    > using his code, but not tail recursive.
    >
    > Also, can someone please tell me how to reply to these threads? I am
    > submitting my responses Via Email, but they don't seem to end up
    here.
    >
    > Thank you for your help.
    >
    >
    >
    > --
    > Kurt Breitsprecher
    > (807) 474-9601
    > [email protected] <mailto:[email protected]>
    >
    >
    >
    >
    
_________________________________________________________________________________
    > mozart-users mailing list
    > [email protected] <mailto:[email protected]>
    > http://www.mozart-oz.org/mailman/listinfo/mozart-users
    >
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL:
    
http://lists.gforge.info.ucl.ac.be/pipermail/mozart-users/attachments/20100929/a73653b9/attachment-0001.html

    ------------------------------

    Message: 4
    Date: Wed, 29 Sep 2010 14:26:22 -0700
    From: Lyle Kopnicky <[email protected] <mailto:[email protected]>>
    Subject: Re: Recursive Tail Factorial
    To: Mozart users <[email protected] <mailto:[email protected]>>
    Message-ID:
    <[email protected]
    <mailto:[email protected]>>
    Content-Type: text/plain; charset="iso-8859-1"

    Hi Peter,

    When accumulating you will still have to do the multiplications in
    the same
    order. If you want to accumulate a list of the intermediate steps, you
    cannot start with the bigger numbers and multiply down to the smaller
    numbers. The recursion is masking the fact that the smaller
    numbers are
    really getting multiplied first.

    So, you should count up in your accumulator rather than down. Here's a
    solution:

    fun {FactLoop I N Acc}
       if I==N
       then Acc
       else {FactLoop I+1 N I*Acc.1|Acc}
    end

    fun {Fact N}
       {FactLoop 1 N [1]}
    end

    Your accumulator starts with the smallest value of 1, and you
    count up until
    you reach the biggest value.

    - Lyle
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL:
    
http://lists.gforge.info.ucl.ac.be/pipermail/mozart-users/attachments/20100929/ec22af21/attachment.html

    ------------------------------

    _______________________________________________
    mozart-users mailing list
    [email protected] <mailto:[email protected]>
    http://lists.gforge.info.ucl.ac.be/mailman/listinfo/mozart-users

    End of mozart-users Digest, Vol 46, Issue 26
    ********************************************




--
Kurt Breitsprecher
(807) 474-9601
[email protected] <mailto:[email protected]>


_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

Reply via email to