You have finally reached a point in your study of programming where you can make interesting choices. You have seen
  1. several structural programming recipes
  2. abstraction (creation and use)
  3. generative recursion
You also know that programs are compositions of smaller programs. It is up to you to make good and bad choices.

When you are finished with a program, you should not only ask "does it work?" but also "did I review and edit it propery", "if I want X, how much do I have to change?", and "if I find a mistake in here, where else do I have to fix the same mistake?" etc. Good programming is an organizational task because a program evolves. It is modified to compute more outputs. It is modified to fix bugs. It is modified to consider a broader range of inputs. Unless it is organized properly, these tasks are difficult and costly.

Because a program evolves, a program requires editing---just like a plain old English paper. You must check whether you chose the proper design recipe for each function. You must compare and see whether you have used abstraction properly. If a language offers abstractions, use them. If you see strong similarities, abstract. If you see weak similarities, make a note that one could abstract and why you decided against it.

In short, there is now more flexiblity and, with flexibility, you have more responsibility. Use it well.
Back to the assignment