4
$\begingroup$

This may be a simple problem, but the goal is to process the list recursively. I want to call a function that splits a list in half recursively. My function is shown below. Could I get help to call it recursively so as to get {{ { {1}, {2} }, {3} }, { {4},{5} } }? (I have read Nest and Fold functions usage in doc, though.)

myF[l_List] := Partition[l, [Ceiling[Length[l]/2]]]
myF[{1,2,3,4,5}] (*{{1,2,3},{4,5}}*)

How can I call the myF function recursively and get {{ { {1}, {2} }, {3} }, { {4},{5} } }?

$\endgroup$

2 Answers 2

8
$\begingroup$

First, we need to slightly correct myF, so that it doesn't try to partition singletons. Then, we can use FixedPoint together with Map.

myF[l_List] := Partition[l, UpTo[Ceiling[Length[l]/2]]]
myF[{x_}] := {x}

FixedPoint[Map[myF, #, {-2}] &, {1, 2, 3, 4, 5}, 4]
(* {{{{1}, {2}}, {3}}, {{4}, {5}}} *)

FixedPoint[Map[myF, #, {-2}] &, Range[20]]
(* {{{{{{1}, {2}}, {3}}, {{4}, {5}}}, {{{{6}, {7}}, {8}}, {{9}, {10}}}}, 
    {{{{{11}, {12}}, {13}}, {{14}, {15}}}, {{{{16}, {17}}, {18}}, {{19}, {20}}}}} *)

Alternatively, you can use ReplaceRepeated:

{1, 2, 3, 4, 5} //. lst : {Except[_?ListQ] ..} :> myF[lst]
(* {{{{1}, {2}}, {3}}, {{4}, {5}}} *)

Note that Nest and Fold are not appropriate in this case, because you do not know in advance the number of times you will have to apply your myF. That is why FixedPoint and ReplaceRepeated are more suitable, because they apply the function as many times as needed to get to the final result.

$\endgroup$
1
  • 1
    $\begingroup$ I have learned that there is a usage of Map[f,expr,levelspec] and f can be mapped to the nodes right above leafs of expression by specifying the level spec {-2}, and also how to define recursive function in this case.Thank you for your answer. $\endgroup$ Commented Mar 7 at 4:28
4
$\begingroup$

Just a variation:

myF[a : {_, __}] := myF /@ TakeList[a, {Ceiling[Length[a]/2], All}];
myF[a_] := a;

myF[{1, 2, 3, 4, 5}]
(* {{{{1}, {2}}, {3}}, {{4}, {5}}} *)

myF[Range[15]]
(* {{{{{1}, {2}}, {{3}, {4}}}, {{{5}, {6}}, {{7}, {8}}}}, 
    {{{{9}, {10}}, {{11}, {12}}}, {{{13}, {14}}, {15}}}} *)
$\endgroup$
1
  • $\begingroup$ Thank you for your another answer(Using Pattern and Pattern name efffectively, if argument of function is list and splittable like {,_},the Map/@TakeList can be applied and If only one object is given, the function return the same object) $\endgroup$ Commented Mar 10 at 0:51

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.