I am working through the course Programming Paradigms via Mathematica. One of the homework exercises for the section Recursion I: Passing the Buck is as follows:
Use recursion to partition a list: "recurPartition[L_List,k_Integer]" should return the same thing as "Partition[L,k]". Of course, don't use "Partition[]".
The following additional limitations are also applied:
First, use of a repetition function ("Map[]", "MapThread[]", "Nest[]", "NestList[]", "Fold[]", "FoldList[]", "Table[]", "Apply[]", and so on, being our "adverbs") will generally disqualify a method as purely recursive, for the repetition is accomplished externally from the nested function calls. Also, repetition accomplished with a loop structure, such as a "While[]", a "Do[]", or some other repetition command, is explicitly forbidden.
Here was my code, following many edits:
Clear[recurPartition]
recurPartition[{}, k_] := {}
recurPartition[L_List, k_Integer] :=
If[Length[L] >= k, {Take[L, k], recurPartition[Drop[L, k], k]}]
recurPartition[{1, 2, 3, 4, 5, 6}, 2]
Which produced the following output:
{{1, 2}, {{3, 4}, {{5, 6}, {}}}}
By contrast Partition[{1, 2, 3, 4, 5, 6}, 2] would produce:
{{1, 2}, {3, 4}, {5, 6}}
I can't figure out what I should have done differently and would appreciate some guidance.
recurPartition[L_List, k_Integer?Positive] /; Mod[Length[L], k] == 0 := If[Length[L] >= k, Join[{Take[L, k]}, recurPartition[Drop[L, k], k]], {}]– J. M.'s missing motivation Jun 07 '13 at 02:25Unevaluated[Sequence[]]might be a bit too advanced for this application, tho. – J. M.'s missing motivation Jun 07 '13 at 02:50Unevaluated[Sequence[]]as opposed to{}, I ran the code both ways and got the same results. – Clif Jun 07 '13 at 13:15recurPartition[{}, k_] := {}is never used because of the condition in theIfstatement. In your example, you don't seem to be interested in "remainder" elements (when the length of the list isn't a multiple of the partition size), so theIfstatement works fine. (see edit). – kale Jun 07 '13 at 13:26Ifstatement and they do seem to work the same until you get to "remainder" elements, which I don't think were accounted for in the exercise, asPartitionseems to just drop them itself. – Clif Jun 07 '13 at 14:45Partitionstatement as of version 9.0.1 – Clif Jun 07 '13 at 14:53Fold&Map:) ). As far as your comment on Leonid's solution, the last version I gave you has the option to keep the "remainder" items, although it still won't outperform on a speed basis. – kale Jun 07 '13 at 15:13Partitionwill be much faster than any top-level code we might come up with, particularly on numerical (packed) arrays. So, in this case, this is just an instructive exercise. But there are cases where top-level code can be quite fast even compared to built-ins, although they are admittedly less common. – Leonid Shifrin Jun 07 '13 at 15:17recurPartitionfunction. – Leonid Shifrin Jun 07 '13 at 15:20remainderQ? – Clif Jun 07 '13 at 16:02