2
$\begingroup$

Suppose I have a function cyclePart which has a definition for the case

cyclePart[list_->{},n_,Δn_,cycle_:True]:=...

But for example in the algorithm, if it encounters a case like

cyclePart[{a,b,c,d,e,f,g,h,i,j}->{b,d,i,j},5,2,True]

I want it to transform it into the previous form so its base definition can be applied. In this case, the number 5 is referring to the position in the original list and the list to the right of the arrow tells it to drop these elements.

cyclePart[list_->drop_,n_,Δn_,cycle_:True]:=
    cyclePart[Complement[list,drop]->{},...updated n...,Δn,cycle]

But how to transform n here? Is there a builtin function that can get an updated position after element drops? Note in the example, the updated list's position 3 refers to position 5 since two elements {b,d} to the left of position 5 are being removed so position 5 moves down to position 3.


As seen in the comment of @kglr Complement[list, drop] should be changed to DeleteCases[list, Alternatives @@ drop] since the former is a set drop which means it removes duplicates and sorts the list in addition to the drop. I incorrectly used Complement[list, drop] but meant the actions of DeleteCases[list, Alternatives @@ drop].

$\endgroup$
5
  • $\begingroup$ cyclePart[list_ -> drop_, n_, \[CapitalDelta]n_, cycle_: True] := Module[{newlist = DeleteCases[list, Alternatives @@ drop]}, cyclePart[newlist -> {}, Position[newlist, list[[n]]], \[CapitalDelta]n, cycle]]? $\endgroup$ – kglr Feb 28 '20 at 18:47
  • 1
    $\begingroup$ ...or cyclePart[list_ -> drop_, n_, \[CapitalDelta]n_, cycle_: True] := Module[{newlist = DeleteCases[list, Alternatives @@ drop]}, cyclePart[newlist -> {}, PositionIndex[newlist][list[[n]]], \[CapitalDelta]n, cycle]]? $\endgroup$ – kglr Feb 28 '20 at 18:49
  • $\begingroup$ @kglr incorrect behaviour for cyclePart[{e,b,c,d,e,f,g,h,i,e}->{b,d,i,j},5,2,True] $\endgroup$ – user13892 Feb 28 '20 at 18:59
  • $\begingroup$ Is there a way to look at the positions directly rather than looking at positions through the values of elements. Which is causing extra matching to occur. $\endgroup$ – user13892 Feb 28 '20 at 19:04
  • $\begingroup$ One dirty trick might be to do a ReplacePart on the original list to differentiate the element first then use this trick but that doesn't seem like a professional way of doing it. Is there a function that can target positions directly? $\endgroup$ – user13892 Feb 28 '20 at 19:15
2
$\begingroup$

You may use Position.

With the partial definition for cyclePart.

ClearAll[cyclePart]
cyclePart[list_ -> {}, n_, Δn_, cycle_ : True] := {list, {}, n, Δn, cycle}

cyclePart[list_ -> drop_, n_, Δn_, cycle_ : True] :=
 With[{c = Complement[list, drop]},
  cyclePart[
   c -> {},
   Position[c, list[[n]]][[1, 1]],
   Δn, 
   cycle
  ]
 ]

Then

cyclePart[{a, b, c, d, e, f, g, h, i, j} -> {b, d, i, j}, 5, 2, True]
{{a, c, e, f, g, h}, {}, 3, 2, True}
cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 5, 2, True]
{{c, e, f, g, h}, {}, 2, 2, True}
cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 8, 2, True]
{{c, e, f, g, h}, {}, 5, 2, True}

Hope this helps.

$\endgroup$
2
$\begingroup$
ClearAll[cyclePart]
cyclePart[list_ -> {}, n_, Δn_, cycle_: True] := foo[list -> {}, n, Δn, cycle]

cyclePart[list_ -> drop_, n_, Δn_, cycle_: True] := Module[{newlist = 
     DeleteCases[list, Alternatives @@ drop]}, 
  cyclePart[newlist -> {}, n - Count[list[[;; n]], Alternatives @@ drop], Δn, cycle]]

Examples:

cyclePart[{a, b, c, d, e, f, g, h, i, j} -> {b, d, i, j}, 5, 2, True]

foo[{a, c, e, f, g, h} -> {}, 3, 2, True]

cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 5, 2, True]

foo[{e, c, e, f, g, h, e} -> {}, 3, 2, True]

cyclePart[{e, b, c, d, e, f, g, h, i, e} -> {b, d, i, j}, 6, 2, True]

foo[{e, c, e, f, g, h, e} -> {}, 4, 2, True]

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.