4
$\begingroup$

For the sake of practicing writing code, I've given myself an exercise in writing a script that checks whether a given positive integer is happy, i.e. take the digits of a number, square them, and add them together. If the sum is 1, then the integer is happy; otherwise, continue this process with the new sum.

While checking to make sure the first step is carried out correctly, I run into a problem. Clearly, n = 1 is happy, yet determining this with a defined function gives the wrong conclusion:

 In[1]:= ssd[x_] = Total[IntegerDigits[x]^2];
         (* ssd = Sum of Squared Digits *)
         ssd[1]
         Total[IntegerDigits[1]^2]

Out[2]:= {3}

Out[3]:= 1

This also happens for other integers larger than 1.

 In[4]:= Table[ssd[x], {x, 1, 9}] // Flatten
         Table[Total[IntegerDigits[x]^2], {x, 1, 9}]

Out[4]:= {3, 4, 5, 6, 7, 8, 9, 10, 11}

Out[5]:= {1, 4, 9, 16, 25, 36, 49, 64, 81}

Is there a bug here, or am I doing something wrong? (I'm using 10.4.1 for Windows, if that makes any difference.)

$\endgroup$
  • 2
    $\begingroup$ use := (SetDelayed) instead of = (Set) when you define ssd; i.e., try ssd[x_] := Total[IntegerDigits[x]^2] $\endgroup$ – kglr Jan 12 '17 at 19:57
  • $\begingroup$ to see why you are getting {3} inspect the output of Trace[Total[IntegerDigits[x]^2] /. x -> 1 ] $\endgroup$ – kglr Jan 12 '17 at 20:00
  • $\begingroup$ Huh, any idea where that 2 is coming from? $\endgroup$ – user170231 Jan 12 '17 at 20:06
  • 2
    $\begingroup$ using FullForm[IntegerDigits[x]^2] we see that FullForm of IntegerDigits[x]^2 is Power[IntegerDigits[x], 2]. Then, since Total works with any head:, ie,.Total[foo[a, b, c]] is a+b+c, Total[Power[IntegerDigits[x], 2]] gives 2+IntegerDigits[x] $\endgroup$ – kglr Jan 12 '17 at 20:22
5
$\begingroup$

The fix: use SetDelayed instead of Set when defining ssd:

 ssd2[x_] := Total[IntegerDigits[x]^2]
 ssd2[1]

1

Why does ssd[1] give{3}?

For

ssd[x_] = Total[IntegerDigits[x]^2];

To see how {3} is obtained use Trace

ssd[1] // Trace

{ssd[1], 2 + IntegerDigits[1], {IntegerDigits[1], {1}}, 2+{1}, {3}}

As you see ssd[1] is stored as 2 + IntegerDigits[1], More generally, with a symbolic input:

ssd[z]

2 + IntegerDigits[z]

This is because (see SetDelayed >> Properties and Relations )

The right side of an immediate definition is evaluated when the definition is made

How does Total[IntegerDigits[x]^2] become 2 + IntegerDigits[x]?

Inspecting the FullForms of subexpressions on the rhs of your definition:

IntegerDigits[x]^2 // FullForm

Power[IntegerDigits[x], 2]

and

Total[IntegerDigits[x]^2] // FullForm

Plus[2, IntegerDigits[x]]

The reason for this is because (see Total >> Properties and Relations):

Total[list] is equivalent to Apply[Plus,list]

That is, Total[expr] replaces the head of expr with Plus. Hence

Total[foo[a, b, c]]

a + b + c

and

Total[Power[a, b]]

a + b

Thus,

Total[Power[IntegerDigits[x], 2]]

2 + IntegerDigits[x]

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