# Print out how many times to calculate the sum of the squares of its digits until answer is 1 or 4

I am trying to write a recursive function, toscare1[], that takes as parameter a positive natural number. Then calculate the sum of the squares of its digits, thus creating a new number; then, we repeat the procedure on this new number, etc., until one of the following cases happens: the sum becomes 1 or becomes 4. Then, the function should return the number of times we performed the procedure. This is what I have tried so far

toscare1[n_] := {
For[i = 0,
NestWhile[ne = Total[IntegerDigits[#]^2] &, n, ne == 1 || ne == 4],
i++, Print[i]]
}

• You are quite close. f[n_] := {Length@# - 1, #} &@ NestWhileList[Plus @@ (IntegerDigits[#]^2) &, n, # != 1 && # != 4 &] Usage: e.g., f[2331]
– Syed
Commented Dec 2, 2022 at 18:28
• Maybe closer to your original but similar to Syed: toscare1[n_] := Length[NestWhileList[(Total[IntegerDigits[#]^2]) &, n, (! (# == 1 || # == 4)) &]] - 1 Commented Dec 2, 2022 at 18:58

Syed's comment has priority, but I thought it would be useful to provide a bit of flavor. Before jumping to a one-liner, it's often useful (and easier) to break the problem up into smaller functions. You know how to do a single step in your calculation, so start by turning that into a function:

toscareStep[int_Integer] := Total[IntegerDigits[int]^2]


toscareStep[2331] gives 23.

At this point, you could build your own recursion, but Mathematica has several nice functions for repeated application: Nest, NestList, NestWhile, NestWhileList, FixedPoint, FixedPointList.

For example, NestList[toscareStep, 2331, 10] gives {2331, 23, 13, 10, 1, 1, 1, 1, 1, 1, 1}. This looks promising, because you can count the members of the list.

You want to terminate on a condition, so use the While version.

NestWhileList[toscareStep, 2331, (# != 4 && # != 1) &]


gives {2331, 23, 13, 10, 1}

To get the "number of times we performed the procedure", we need to take Length - 1, because the first element of NestWhileList was the input (i.e. no steps performed yet at that point). So,

toscareStepCount[int_Integer] :=
-1 + Length[NestWhileList[toscareStep, int, (# != 4 && # != 1) &]]


For example, toscareStepCount[2331] gives 4. This approach "throws away" the record of each step, and that record is often useful. So, you might want something more like this:

toscareStepList[int_Integer] := NestWhileList[toscareStep, int, (# != 4 && # != 1) &];
toscareStepCount[int_Integer] := -1 + toscareStepList[int]


If you wanted to build your own recursive implementation, the typical way to do something like this is to use an accumulator (in this case a simple counter):

toscareStepCount[val_Integer] := toscareStepCount[val, 0];
toscareStepCount[1, count_Integer] := count;
toscareStepCount[4, count_Integer] := count;
toscareStepCount[current_Integer, count_Integer] :=
toscareStepCount[toscareStep[current], 1 + count]