3
$\begingroup$

I have an exercise where I need to input a multi-digit number and evaluate the square of the sum of its digits. I am new to Mathematica and I can't figure out why I'm getting an infinite loop. This is my code:

n = Input["Enter a multi-digit number"];
sum = 0;
While[n > 0, sum = sum + Mod[n, 10]; n = n/10];
Print["The square of the sum of the digits is: ", sum * sum];

Any ideas what I'm doing wrong?

$\endgroup$
  • 3
    $\begingroup$ Do you need to use a While loop? $\endgroup$ – That Gravity Guy Sep 25 '18 at 0:49
  • 6
    $\begingroup$ If you keep dividing n by 10, it gets smaller, but it can't ever get below 0. Maybe try While[n>1... $\endgroup$ – bill s Sep 25 '18 at 0:52
  • 1
    $\begingroup$ @ThatGravityGuy It isn't specified in the exercise, but considering that the lecture covers while and for loops, I'm guessing that it should be done using one of them. $\endgroup$ – D. D. Sep 25 '18 at 0:52
  • $\begingroup$ It looks like you are assuming n is an integer and at some point when dividing by 10 it will truncate to 0. It is not so try While [ Floor[n]>0,... $\endgroup$ – jmm Sep 25 '18 at 0:58
  • $\begingroup$ @bills that does fix the infinite loop, thanks! Now I've run in another problem where Mod doesn't give me the correct result. For example when I input 32 Mod[n, 10] gives me 16/5 in the first iteration, but it should be 2. $\endgroup$ – D. D. Sep 25 '18 at 1:00
6
$\begingroup$

The crux of the matter is how n is changed on each iteration.

Math

Consider a multi-digit integer $n = a_1 a_2 a_3 \ldots a_N$, where $a_k$ is the $k$-th digit of $n$ in base $10$, and $a_1 \neq 0$.

Then, since $a_1 a_2 \ldots a_N = \left( a_1 a_2 \ldots a_{N-1} \right)10 + a_N$,

\begin{equation} \text{ mod}(n, 10) = \text{ mod}(a_1 a_2 \ldots a_N, 10) = a_N \end{equation}

Therefore $n - \mathrm{mod}(n,10) = \left( a_1 a_2 \ldots a_{N-1} \right)10 \ $ and thus

\begin{equation} \dfrac{n - \mathrm{mod}(n,10)}{10} = \dfrac{\left( a_1 a_2 \ldots a_{N-1} \right)10}{10} = a_1 a_2 \ldots a_{N-1} \end{equation}

Then nest $N-1$ more times.

Then, since $\mathrm{mod}(j,10) = j$ for $j \in \{\mathbb{Z} : 0 \leq j < 10\}$ and $a_1 \in \{\mathbb{Z} : 0 < a_1 < 10\}$ by the definition of a digit in decimal expansion and our restriction, the last re-assignment of $n$ is just

\begin{equation} n = \dfrac{a_1 - \mathrm{mod}(a_1,10)}{10} = \dfrac{a_1 - a_1}{10} = 0 \end{equation}

which breaks on next test of $n > 0$.

So, the appropriate change of $n$ on each iteration is $\boxed{n = \dfrac{n - \mathrm{mod}(n,10)}{10}}$.


Code

Block[
 {n = Input["Enter a multi-digit number"], sum = 0},
 While[n > 0, sum = sum + Mod[n, 10]; n = (n - Mod[n, 10])/10];
 StringForm["The square of the sum of the digits is: ``", (sum)^2]
 ]

Block[
 {n = #, sum = 0},
 While[n > 0, sum = sum + Mod[n, 10]; n = (n - Mod[n, 10])/10];
 StringForm["The square of the sum of the digits is: ``", (sum)^2]
] & /@ {11, 12, 21, 111}//Column

The square of the sum of the digits is: 4

The square of the sum of the digits is: 9

The square of the sum of the digits is: 9

The square of the sum of the digits is: 9

Another Method

If, in the case that you don't need to use a While loop, you can use the built in RealDigits (or IntegerDigits if n is always an integer) to get a list of the digits of any real number.

Total[First@RealDigits@Input["Enter a multi-digit number"]]^2

Total[First@RealDigits@#]^2 & /@ {11, 11., 11.1}

{4, 4, 9}

$\endgroup$
3
$\begingroup$

Alternatively, you can use Quotient instead of /10 to remove the "rest; of the division by 10.

n = Input["Enter a multi-digit number"];
sum = 0;
While[n > 0, 
 sum += Mod[n, 10]; 
 n = Quotient[n, 10]
 ];
Print["The square of the sum of the digits is: ", sum^2];
$\endgroup$
1
$\begingroup$

Just to make it clear, the source of the error you get is in n=n/10.

Unlike, say, C, Mathematica does not do type coercion. An integer divided by an integer in Mathematica can be a non-integer rational number (as we are taught in math class, not CS). Likewise, modular division will give then a rational (not integer) remainder.

@bills that does fix the infinite loop, thanks! Now I've run in another problem where Mod doesn't give me the correct result. For example when I input 32 Mod[n, 10] gives me 16/5 in the first iteration, but it should be 2.

n = 32
Mod[32, 10]   (* 2    *)
n=32/10       (* 16/5 *)
Mod[16/5, 10] (* 16/5 *)
n=(16/5)/10   (* 8/25 *)

Floor[n] == 0 now, so the loop stops.

If you want C-like integer division, refer to Henrik's answer with Quotient.

$\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.