Saturday, March 1, 2014

Week 7 on recursion

As the saying goes practice makes perfect, I feel like I am currently exercising this idiom on recursion. Though perfect is well ahead of me, I can a great leap I took in understanding and applying of recursion. I still remember the day when the prof introduced recursion with nested list. I was so frustrated, confused and lost and recursion became what my friend and I were discussing on a friday night dinner.

Till now, each week's material is closely related to recursion. I think I cover partially in each week's post, just for your information. Since this week we had a term test, I think everybody did a systematic review over the past 7 weeks' material. Undoubtedly, my understanding of recursion is enhanced through this practice, particularly by looking back to all the slides and labs.

In my way of solving the recursive problem, it is necessary to start from the simplest. For example, given a problem with nested list, we can start with a 0 nested list(just a simple list) to see what's the question is asking for. A little sketching or drawing never hurts.
Speaking of the essence of recursion, the next step is what the professor call the recursion insight, which is how we build up recursion on the previous case. In this section, there are generally two ways of writing the codes. Most of the examples given in class is written in the form of list comprehension.    I find this a little difficult to understand at first, but after a long time training, sometimes this is the only solution I can think of. List comprehension requires one to be familiarized with the many methods list has, namely, sum, any, all...Nevertheless, it has its constraint when the problem become more complicated all the scenario can't be covered in one or two lines. This is when we should adopt the block method. I remembered I was stuck the third question in lab 4 for so long. It made me realize the the importance of flexibility in choosing which method to use in writing code. Notably, in a block from, it is importance to have a return statement when you call the function itself or whenever you wan the result in this step to be used in the nest. I made a lot of mistakes here and just to remind everyone.
Finally, I finish up recursion with the base case. I know I am kind of doing the second and third steps backwards and ocaasionally, I even forget about the base case. Interestingly, sometimes the base case is latently wired in the code that doesn't require significant efforts to write it. E.g. when we want to sum up all the items in a nested list. The base case is automatically sum(a certain list).

Below is a interesting example (kind of tricky) I found in the tree structure codes:
counting the leaves in a tree: return sum(count(i) for i in t.children) + (0 if t.children else 1)
The simplest case is where the height of the tree is 0. This t.children == False, return 1
Whereas the recursion insight is more mathematically—count the leaves of each of its children.
The trickiest part i find is who the data is accumulated. When I was thinking about this question myself, I didn't think of the second part of the return statement. This elaborate design accumulates nothing if a tree has any children, but when it reaches the leaves, return 1. Then sum it up, thereby competing the code.

Recursion is indeed an artistic design and a product of wisdom.

No comments:

Post a Comment