0
$\begingroup$

I would like a code that works for doing loops as in the toy example below. This would help me to understand how to work with loops in more general contexts as I am still a beginner in Mathematica. The example is:

Consider list1={A,B,C,D}, f1[A]=f1[B]=0, f1[f2[C]]=0 and f1[f2[f2[D]]]=0, where the constraints on the functions f1 and f2 is that they only need to satisfy the previous properties.

(i) In the first stage of the code, we apply f1 to each of the elements in list1. Given that f1[A]=f1[B]=0, the code should save (to print later) A and B and keep C and D, because f1[C] and f1[D] do not vanish.

(ii) In the second stage, we apply f2 to the elements that were not zero when we applied f1 in the first stage. So that we should have a list {f2[C],f2[D]}, and then apply f1 to the elements of the latter. Given that f1[f2[C]]=0, the code should save f2[C] and keep f2[D] to return to the loop.

(iii) Finally, going back to stage (ii), we apply f2 to f2[D] so we would be left with the list {f2[f2[D]]} and after applying f1 to this list it gives zero, because f1[f2[f2[D]]]=0, so that we save f2[f2[D]] and the process would be finished in this example.

(iv) In the end, I want the code to print as a list all the elements generated in the process that when acted with f1 give zero. The answer, in this case, would be {A,B,f2[C],f2[f2[D]]}. This list shouldn't count repeated elements twice.

$\endgroup$
3
  • $\begingroup$ What have you tried? Note that loops are not really idiomatic in Mathematica. See eg Alternatives to procedural loops and iterating over lists in Mathematica. Also avoid uppercase single-character variables, as many of those have built in meaning (e.g. C, D, E, I, K, N, O ...); use lowercase variable names instead. $\endgroup$
    – MarcoB
    Dec 29, 2021 at 4:52
  • $\begingroup$ Consider Select as an example of a tool that might be helpful in your selection of elements from a list that give rise to a certain function output. $\endgroup$
    – MarcoB
    Dec 29, 2021 at 5:02
  • $\begingroup$ You can check out the introductory book written by the inventor to help you get started. $\endgroup$
    – Syed
    Dec 29, 2021 at 6:49

1 Answer 1

3
$\begingroup$

First we define the conditions:

Clear["Global`*"];
list = {a, b, c, d};
f1[a] = 0;
f1[b] = 0;
f1[f2[c]] = 0;
f1[f2[f2[d]]] = 0;

Then we apply the 3 steps. The result is accumulated by Sow/Reap in the variable res:

res = Reap[
    t = If[f1[#] === 0, Sow[#]; Nothing, #] & /@ list ;
    t = If[t = f2[#]; f1[t] === 0, Sow[t]; Nothing, t] & /@ t;
    If[t = f2[#]; f1[t] === 0, Sow[t]; Nothing, t] & /@ t;
    ][[2]];
res


   (*  {{a, b, f2[c], f2[f2[d]]}} *)
$\endgroup$
4
  • $\begingroup$ Is there a way to change your solution such that the code works also if instead of only applying f2 two times until we found 'f1[f2[f2[d]]] = 0' it would apply any number of times? In this case it would also work if 'f1f[f2[f2[f2[d]]] ]= 0', etc $\endgroup$
    – Slayer147
    Dec 29, 2021 at 18:20
  • $\begingroup$ "Any number of times", that is an infinite number of times, does not seem feasible. However, for three, you would have to duplicate the second case (t= If[...) $\endgroup$ Dec 29, 2021 at 19:19
  • $\begingroup$ For any finite number of times, is there another way to do this without having replicate the second case? $\endgroup$
    – Slayer147
    Dec 29, 2021 at 19:37
  • $\begingroup$ You could repeat the second case in a While loop until nothing is left over.. $\endgroup$ Dec 29, 2021 at 19:40

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