I'm Stuck: Factorials and Recursive Methods
March 4th, 2007
Disclaimer and Preamble: Whenever I get stuck as I go through the books I’m using to learn Ruby on Rails and some other stuff, I’m going to write about it. All of the snags I hit and write about here may be excruciatingly elementary to you. Think of this as a public workbook. I’m writing up the roadblocks as a strategy to help myself stick with the process of learning. If I don’t figure it out in the act of writing it out here, I’m hoping someone else might come along and help me learn by catching the error in my approach or explaining something in different words. I’ll be delighted if you speak up and offer some help when you can, especially if you have an idea of what might get me to the understanding I need to continue.
My one big rule is: Please don’t just tell me the answer outright without trying to help me learn it for myself. That won’t do me any good.
My first snag in Beginning Ruby on Rails was in one of the exercises at the end of Chapter 2. Yes, I’m doing all the exercises.
”Create a method that calls itself – a technique called recursion – to calculate factorials. A factorial is the product of the number times all the other whole numbers down to one – for example, the factorial of 6, written as 6!, is 6 x 5 x 4 x 3 x 2 x 1 = 720.”
I’ve been scared of factorials ever since a gang of them made me quit math olympiad in middle school. And I hate how they’re always yelling. But conceptually I get them, and conceptually I get the idea of recursion. Nevertheless, I’m having trouble writing a recursive method to calculate them and have it work properly. Right here and now, I’m going to give it a fresh try and explain as I go, and if I get stuck you’ll see exactly where. So here we go.
In words, I figure I need to count down to one(or up from one, if it’s easier) from the variable I want to factorialize, multiplying by the counting number as I go, and keeping track of that growing number. Right? As far as the recursive part, it seems like I’d create one method to multiply a number by it’s next lowest neighbor, as long as the number is a whole number greater than one. I could then call that method on itself as many times as needed to get to the victim of the factorializing. So if that’s all right, first thing I need is a method that takes N and turns it into N x (N-1).
Here’s what I’m trying out for the first part:
def factorial_step(value)
value = value * (value - 1) unless value <=2
puts value
end
factorial_step(6)
Wow. Success! It returned “30”. This is already farther than I got the first time through. I may not need you after all. OK, so now I need to write a method that calls that method as many times as I need to get to N factorial. More after I think a minute and write my next small chunk.
I think I need an iterator.
Forgetting the recursive part for now and just trying to get it to work for a complete factorial, I tried:
1 2 3 4 5 6 |
def factorial_step(value) value.downto(2) do new_value = value * (value - 1) puts new_value end end factorial_step(6) |
I got five 30’s back. So it’s looping the right number of times, at least. Now I need to get it to change the value of “value” each time through, and multiply it by the previous.
And tweaking a little, now I’ve got
1 2 3 4 5 6 7 |
def factorial_step(value) value.downto(2) do |new_value| new_value *= new_value - 1 puts new_value end end factorial_step(6) |
Which gives me 30, 20, 12, 6, 2….Or in other words…(6 x 5), (5 x 4), (4 x 3), (3 x 2), (2 x 1). I’m flashing back to middle school. Feels like the factorials are getting me again.
I think I have an extra step in here somewhere. I seem to be doing the multiplication twice and not serially. So let me rearrange here.
1 2 3 4 5 6 7 8 |
def factorial_step(value) total = 1 value.downto(2) do |new_value| total = new_value * total puts total end end factorial_step(6) |
Now I’m multiplying each new value in the loop by whatever came before it. I think. And I get: 6, 30, 120, 360, 720. Oh hell yeah. it’s working. Moving the “puts” line to where it needs to be to only show the final result is easy enough. My only question is, it works, but does it “call itself” like the assignment wanted? Not sure if it does.
1 Response to “I'm Stuck: Factorials and Recursive Methods”
Sorry, comments are closed for this article.
March 5th, 2007 at 04:59 PM Remember a recursive function calls itself. Ideally, there is some test (or threshold) that will stop the recursion, as well: function recurse() recurse() end Of course, this function will end by eating up all the memory :)