Advertisement
Guest User

Untitled

a guest
Oct 6th, 2015
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.70 KB | None | 0 0
  1. BeginPackage["Unflatten`"]
  2.  
  3. Unflatten::usage = "Unflatten[h[elems], posints, heads] creates a nested structure by wrapping
  4. the elements in positions intervals posints in heads heads";
  5.  
  6. UnflattenNested::usage = "UnflattenNested[expr, {startposlist, endposlist}, head] wraps elements
  7. of expr at positions starting at startposlist_i and ending at endposlist_i in head head";
  8.  
  9. Begin["`Private`"]
  10.  
  11. ClearAll[listSplit,reconstructIntervals,groupElements,groupPositions,processPosList,groupElementsNested];
  12.  
  13. listSplit[x_List, lengthlist_List,headlist_List]:=
  14. MapThread[
  15. #1@@Take[x,#2]&,
  16. {headlist,Transpose[{Most[#]+1,Rest[#]}&[FoldList[Plus,0,lengthlist]]]}
  17. ];
  18.  
  19. reconstructIntervals[listlen_Integer,ints_List]:=
  20. Module[{missed,startint,lastint},
  21. startint = If[ints[[1,1]]==1,{},{1,ints[[1,1]]-1}];
  22. lastint = If[ints[[-1,-1]]==listlen, {},{ints[[-1,-1]]+1,listlen}];
  23. missed =
  24. Map[
  25. If[#[[2,1]]-#[[1,2]]>1,{#[[1,2]]+1,#[[2,1]]-1},{}]&,
  26. Partition[ints,2,1]
  27. ];
  28. missed = Join[missed,{lastint}];
  29. Prepend[Flatten[Transpose[{ints,missed}],1],startint]
  30. ];
  31.  
  32. groupElements[
  33. lst_List,poslist_List,headlist_List
  34. ] /; And[OrderedQ[Flatten[Sort[poslist]]],Length[headlist]==Length[poslist]]:=
  35. Module[{totalheadlist,allints,llist},
  36. totalheadlist =
  37. Append[
  38. Flatten[Transpose[{Array[Sequence&,{Length[headlist]}],headlist}],1],
  39. Sequence
  40. ];
  41. allints = reconstructIntervals[Length[lst],poslist];
  42. llist = Map[If[#==={},0,1-Subtract@@#]&,allints];
  43. listSplit[lst, llist,totalheadlist]
  44. ];
  45.  
  46. (* To work on general heads, we need this *)
  47.  
  48. groupElements[h_[x__],poslist_List,headlist_List]:=
  49. h[Sequence@@groupElements[{x},poslist,headlist]];
  50.  
  51. (* If we have a single head *)
  52. groupElements[expr_,poslist_List,head_]:=
  53. groupElements[expr,poslist,Table[head,{Length[poslist]}]];
  54.  
  55.  
  56. groupPositions[plist_List]:=
  57. Reap[Sow[Last[#],{Most[#]}]&/@plist,_,List][[2]];
  58.  
  59. processPosList::unmtch = "The starting and ending position lists `1` and `2` don't match";
  60. processPosList[{openlist_List,closelist_List}]:=
  61. Module[{opengroup,closegroup,poslist},
  62. {opengroup,closegroup} = groupPositions/@{openlist,closelist};
  63. poslist = Transpose[Transpose[Sort[#]]&/@{opengroup,closegroup}];
  64. If[UnsameQ @@ poslist[[1]],
  65. Message[processPosList::unmtch,openlist,closelist];
  66. {},
  67. (* else *)
  68. Transpose[{poslist[[1,1]],Transpose/@ Transpose[poslist[[2]]]}]
  69. ]
  70. ];
  71.  
  72. groupElementsNested[nested_,{openposlist_List,closeposlist_List},head_]/;Head[head]=!=List:=
  73. Fold[
  74. Function[{x,y},MapAt[groupElements[#,y[[2]],head]&,x,{y[[1]]}]],
  75. nested,
  76. Sort[processPosList[{openposlist,closeposlist}],Length[#2[[1]]] < Length[#1[[1]]]&]
  77. ];
  78.  
  79. Unflatten[args___]:= groupElements[args];
  80.  
  81. UnflattenNested[args___]:=groupElementsNested[args]
  82.  
  83. End[]
  84.  
  85. EndPackage[]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement