7

Given an arbitrarily nested empty matrix like for example

mat =
  {
   {},
   {{}, {}},
   {{}, {{}}, {}},
   {{}, {{}}, {}, {{{}}}}
   };

and knowing that

Depth /@ mat

{2, 3, 4, 5}

Question 1

how can I produce the following result?

res =
  {
   {2},
   {{3}, {3}},
   {{3}, {{4}}, {3}},
   {{3}, {{4}}, {3}, {{{5}}}}
   };

Question 2

Given

{{2}, {3, 3}, {3, 4, 3}, {3, 4, 3, 5}};

how can I produce the above empty matrix mat ?

rhermans
  • 36,518
  • 4
  • 57
  • 149
eldo
  • 67,911
  • 5
  • 60
  • 168

4 Answers4

7

Q1

My original answer

Using ReplacePart, Length and Position

res === ReplacePart[
    mat, 
    # -> {1+Length[#]}& /@ Position[mat, {} ]
]
(* True *)

My MapIndexedattempt

I liked the solutions by @kglr and @lericr, so my version of it (*) is:

res === (
     MapIndexed[ {1 + Length[#2]}&, mat, {-2} ]
)
(* True *)

* (In the spirit of the saying that plagiarism is the best form of flattery.)

Q2

Using Nest, List, Nothing and ReplaceAll (/.)

mat === (
    {
        {2}, 
        {3, 3}, 
        {3, 4, 3}, 
        {3, 4, 3, 5}
    } /. x_Integer :> Nest[List, Nothing, x-2 ]
)
(* True *)
rhermans
  • 36,518
  • 4
  • 57
  • 149
  • 3
    Nest[List, Nothing, x-2 ] - so simple and yet: Probably I would never have found it – eldo Nov 13 '23 at 11:01
6

Q1:

MapIndexed

MapIndexed[# /. {} -> 1 + {Length @ #2} &, mat, All]
 {{2}, {{3}, {3}}, {{3}, {{4}}, {3}}, {{3}, {{4}}, {3}, {{{5}}}}}

Position + ReplaceAll

$i = 0;
mat2 = mat /. {} :> {++$i};

mat2 /. i_Integer :> Length @ First @ Position[mat2, i]

 {{2}, {{3}, {3}}, {{3}, {{4}}, {3}}, {{3}, {{4}}, {3}, {{{5}}}}}

Internal`CopyListStructure + Position

Internal`CopyListStructure[mat /. {}->{1}, 1 + Map[Length] @ Position[mat, {}]]
  {{2}, {{3}, {3}}, {{3}, {{4}}, {3}}, {{3}, {{4}}, {3}, {{{5}}}}}

Q2:

FixedPoint + ReplaceAll

depths = {{2}, {3, 3}, {3, 4, 3}, {3, 4, 3, 5}};

FixedPoint[ReplaceAll[{0 -> Nothing, i_Integer :> {i - 1}}], depths - 2]

{{}, {{}, {}}, {{}, {{}}, {}}, {{}, {{}}, {}, {{{}}}}}
 % == mat
True
kglr
  • 394,356
  • 18
  • 477
  • 896
5

Using ReplaceAll(/.) & Depth

Q1:

res === Map[# /. {} -> Depth@# &, mat /. {} -> {{}}, {2}]
(*True*)

Using ReplaceRepeated

Q2

input = {
    {2}, 
    {3, 3}, 
    {3, 4, 3}, 
    {3, 4, 3, 5}
};
mat === Map[
    {e} |-> {e} //. {e_?Positive -> List[e - 1], {{{0}}} -> Nothing}, input, {2}]
(*True*)
vindobona
  • 3,241
  • 1
  • 11
  • 19
5

Q1

1 + MapIndexed[List@*Length@*Last, mat, {-2}]

Q2

Map[Nest[List, Nothing, # - 2] &, input, {-1}]
lericr
  • 27,668
  • 1
  • 18
  • 64