Digits Cubes Limit

f ( n ) f(n) gives the sum of the cubed digits of some positive integer n . n. For example, f ( 123 ) = 1 3 + 2 3 + 3 3 = 36. f(123)=1^3+2^3+3^3=36.

If we repeatedly apply this process on each previous result, the following two different behaviors may arise:

  • Arrive at a fixed point : For example, beginning with 3, we eventually arrive at 153, and f ( 153 ) = 153. f(153)=153. We say that 153 is a fixed point.

  • Arrive at a limit cycle : For example, beginning with 4, we eventually arrive at 133, and f ( 133 ) = 55 f ( 55 ) = 250 f ( 250 ) = 133. f(133) = 55 \implies f(55) = 250 \implies f(250)=133. We say that { 55 , 133 , 250 } \{55,133,250\} is a limit cycle.

Let the limit set be the set of all fixed points and limit cycles in the range of f ( n ) . f(n).

Find the sum of all the numbers in the limit set (including the four in pink found above). Note : A coding environment is provided below:


            
You need to be connected to run code


Bonus: Prove that the limit set actually contains finitely many numbers.


The answer is 5227.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

17 solutions

Alex Li
May 27, 2018
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#Le fantastic cubing function
def f(x):
    sum = 0
    while(x!=0):
        sum += (x%10)**3
        x //= 10
    return sum

limit_set = set()    
# The highest digit possible is 9. 9999 decreases to 2916, so we can say with certainity that
# the largest fixed point is at most 4 digits, and further that it is at most 2916 since any 4-digit number
# greater than that will decrease. Also, of course, any value must be at least 0.
for i in range(2917):
    path = set()
    next = i
    while not (next in path):
        path.add(next)
        next = f(next)
    # at this line, next is part of the limit set, since it was seen twice on the path.
    # Add the cycle to the limit set (it's a set, so we can add it several times)
    cycle_pos = f(next)
    limit_set.add(next) # this line needed to add fixed points
    while(cycle_pos !=next):
        limit_set.add(next)
        cycle_pos = f(cycle_pos) 
sum = 0
for i in limit_set:
    sum+=i
print(sum)

My c code.Successfully run on xcode.However, I miss the point of this problem.I thought the answer is the number of all these numbers, and tried 15,16,17 o(╯□╰)o。

include <stdio.h>

int c[100] = { 0 };

int count = 0;

bool isprintf = false;

void function(int n)

{

int a[100] = { 0 }, b[100] = { 0 };

a[1] = n;

int i;

for (i = 2; i <= 99; i++)

{

    while (a[i - 1] != 0)

    {

        a[i] = a[i] + (a[i - 1] % 10) * (a[i - 1] % 10) * (a[i - 1] % 10);

        a[i - 1] = a[i - 1] / 10;

    }

    b[i] = a[i];

}

int j, k;

for (i = 2; i <= 99; i++)

{

    for (j = 1; j < i; j++)

    {

        if (b[j] == b[i] && (b[j] != 0))

        {

            for (k = j; k<i; k++)

            {

                int x;

                for(x = 0; x < count; x++)

                {

                    if(c[x] == b[k])
                    {

                        isprintf = true;

                        break;
                    }

                }
                if(isprintf == false)

                {

                    printf("%d\n", b[k]);

                    c[count++] = b[k];

                }

                isprintf = false;

            }

            for (k = i; k <= 99; k++) 

                b[k] = 0;

        }

    }

}

}

int main()

{ int n;

for (n = 0; n <= 200; n++)

{

    function(n);

}

return 0;

}

the output is

1

371

153

133

55

250

370

217

352

160

407

1459

919

244

136

Xu Liangjun - 3 years ago

Another observation can help you go for a number smaller than 2916.With the range of 2916, the largest output is given by 1999 which is 2188.

Aatman Supkar - 3 years ago

limit of 10000?

Abhijit Phatak - 3 years ago
Patrick Corn
May 22, 2018

The bonus isn't too hard: let f ( x ) f(x) be the number obtained by summing the cubes of the digits of x . x. Now here are two facts:

(1) If x < 10000 , x < 10000, then f ( x ) < 10000 f(x) < 10000 (in fact, it's less than 4 9 3 = 2916 4 \cdot 9^3 = 2916 ).

(2) If x 10000 , x \ge 10000, f ( x ) < x . f(x) < x. (Proof: let g = log 10 ( x ) . g = \log_{10}(x). Then x x has g \lceil g \rceil digits, so f ( x ) 9 3 g , f(x) \le 9^3 \lceil g \rceil, which is less than x = 1 0 g x = 10^g for g 4 , g \ge 4, because e.g. 729 g < 729 ( g + 1 ) , 729 \lceil g \rceil < 729(g+1), and for g = 4 g=4 729 ( g + 1 ) < 1 0 g 729(g+1) < 10^g and the derivative of the left side is a constant 729 729 and the derivative of the right side is 1 0 g ln ( 10 ) 10000 ln ( 10 ) , 10^g \ln(10) \ge 10000 \ln(10), so the right side increases faster than the left side.)

This implies that for any x , x, iterating f f enough times will leave a result < 10000 , < 10000, and iterating f f after that will keep us in the range [ 1 , 10000 ] . [1,10000]. By the Pigeonhole Principle , the sequence of iterates will eventually repeat, at which point we are in the limit set.

This shows that everything eventually leads to a point in the limit set, and that the limit set is finite, because no number > 10000 > 10000 can ever appear in the limit set.

To generate the limit set, I wrote some code to check the integers < 10000. < 10000. I got the cycles 1 55 , 250 , 133 136 , 244 153 160 , 217 , 352 370 371 407 919 , 1459 1 \\ 55, 250, 133 \\ 136, 244 \\ 153 \\ 160, 217, 352 \\ 370 \\ 371 \\ 407 \\ 919, 1459 The sum is 5227 . \fbox{5227}.

I don't get it im in 6th grade

Graham Hart - 3 years ago

Log in to reply

Hey you are 14 years old how can you be in at 6

TANMAY GOYAL - 3 years ago

i Don't agree. f(1459) is 918. so the last set isn't correct. then the overall set sum must be 2849

Awesama Sevenck - 3 years ago

Log in to reply

No, 1 + 64 + 125 + 729 = 919. 1+64+125+729 = 919.

Patrick Corn - 3 years ago

I don't know how used you are to dealing with such iteration problems, but one thing that I find helpful is to plot the function beforehand to get some intuition. Other than that, your solution is clearly the best one available.

Lowe K - 1 year, 6 months ago
Albert Yiyi
May 28, 2018
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
def foo(x): #sum of cube of digits
    y=0;
    while(x>0):
        y+=(x%10)**3;
        x//=10;
    return(y);

Df=set(range(1,4*9**3));    # Df = domain of foo
Rf=set();
while(True):
    for i in Df:
        Rf.add(foo(i));     # Rf = range of foo
    if(len(Df)>len(Rf)): # if range != domain
        Df=Rf;              # range = new domain, reiterate
        Rf=set();
    else:                   # if range == domain
        break;              # limit set found

print(sum(Rf));

Lucas Viana Reis
May 28, 2018

Let's call a number made of k 9's a ninber . A ninber has clearly the highest possible output of f ( n ) f(n) for a number with k digits. Also, it's easy to check that its output is equal to k × 9 3 k\times 9^3 . So the output increases linearly with k, as the ninber itself (which consists of k 9's) grows exponentially. So, if we find the least k for which the ninber is bigger than its output, we are guaranteed that greater numbers will always be greater than their outputs, so we don't need to check them as it's impossible for them to form fixed points or limit cycles.

f ( 9999 ) = 2916 < 9999 f(9999)=2916<9999

Bonus : This also proves that the limit set contains finitely many numbers, as numbers greater 2916 can't be part of the set and there are finitely many positive integers smaller or equal to 2916.

Here is a concise example that computes the limit set:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
found = []
for n in range(1, 2917):
    previous = []
    k = n
    while k not in previous:
        n = k
        k = sum([int(a)**3 for a in str(n)])
        previous.append(n)
    if k not in found:
        for i in range(previous.index(k), len(previous)):
            if previous[i] not in found:
                found.append(previous[i])
print(sum(found))

Why turn str(n) into a list in line 7? You can iterate over the string directly.

Jakob Wege - 3 years ago

Log in to reply

Well, I didn't know about that. Thanks

Lucas Viana Reis - 3 years ago
Elizandro Max
May 28, 2018
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def f(n): # sum cubes of digits
    ss=0
    s=str(n)
    for i in range(len(s)):
        ss+=int(s[i])**3
    return ss

def g(n): # find cycles
    cycle=set([f(n)])
    n=f(n)
    while n not in cycle:
        cycle.add(n)
        n=f(n)
    cycle=set([n])
    n=f(n)
    while n not in cycle:
        cycle.add(n)
        n=f(n)
    return(cycle)    

u=set()
for i in range(1,10000):
    u=u.union(g(i))
    print(u)

Xu Liangjun
May 31, 2018

My C code.

include <stdio.h>

int c[100] = { 0 };

int count = 0;

bool isprintf = false;

void function(int n)

{

int a[100] = { 0 }, b[100] = { 0 };

a[1] = n;

int i;

for (i = 2; i <= 99; i++)

{

    while (a[i - 1] != 0)

    {

        a[i] = a[i] + (a[i - 1] % 10) * (a[i - 1] % 10) * (a[i - 1] % 10);

        a[i - 1] = a[i - 1] / 10;

    }

    b[i] = a[i];

}

int j, k;

for (i = 2; i <= 99; i++)

{

    for (j = 1; j < i; j++)

    {

        if (b[j] == b[i] && (b[j] != 0))

        {

            for (k = j; k<i; k++)

            {

                int x;

                for(x = 0; x < count; x++)

                {

                    if(c[x] == b[k])
                    {

                        isprintf = true;

                        break;
                    }

                }
                if(isprintf == false)

                {

                    printf("%d\n", b[k]);

                    c[count++] = b[k];

                }

                isprintf = false;

            }

            for (k = i; k <= 99; k++) 

                b[k] = 0;

        }

    }

}

}

int main()

{ int n;

for (n = 0; n <= 200; n++)

{

    function(n);

}

return 0;

}

the output is

1

371

153

133

55

250

370

217

352

160

407

1459

919

244

136

the sum is 5227.

I don't get it: f(352) = 160,* so 352 shouldn't be in the set, right? Likewise f(1459) = 919, already in the set. What am I missing here?

*3^3 + 5^3 + 2^3 = 27 + 125 + 8 = 160, which is already in the set.

Joe Horton - 3 years ago

Log in to reply

The code print numbers in a limit cycle to several lines.

Ex. 217->352->160->217->......

saku usa - 2 years, 10 months ago
Johanan Paul
May 29, 2018
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
limit_set = []
n  = 1

def sum_cubed_digits(n):
    d = n % 10
    c = (n-d)//10 % 10
    b = (n-d-10*c)//100 % 10
    a = (n-d-10*c-100*b)//1000 % 10
    return a**3 + b**3 + c**3 + d**3

while(n < 10000):
    check_list = []
    s = n
    while(True):
        if not s in check_list:
            check_list.append(s)
            s = sum_cubed_digits(s)
        else:
            cut = check_list.index(s)
            for x in check_list[cut:]:
                if not x in limit_set:
                    limit_set.append(x)
            break
    n += 1

limit_set.sort()
answer = sum(limit_set)
print(limit_set)
print("Answer:" + str(answer))

############ OUTPUT ###########                                                                                                         
#  [1, 55, 133, 136, 153, 160, 217, 244, 250, 352, 370, 371, 407, 919, 1459]   
#  Answer:5227                                                                                                  

Volodymyr Lomako
May 29, 2018

Python 3

MAXRANGE = 2195 # 2^3 + 3 * 9**3 
UNCHECKED, NOT_IN_LS, TESTING_NOW, BELONGS_LS = 0, 1, 2, 3 # LS - limit set

# Every cell winth index 'i' in the list 'state' represents state of number i
state = [UNCHECKED] * MAXRANGE

def chain_replace(number, source, destination):
    """This function runs throuhg chain which begins with 'number'
       and replaces every number state in the chain to 'destination'
       while the state is 'source'"""
    while state[number] == source:
        state[number] = destination
        number = sum([int(i)**3 for i in str(number)]) # Sums up cubes of digits
    return number

for number in range(MAXRANGE):
    cycle_start = chain_replace(number, UNCHECKED, TESTING_NOW)
    chain_replace(cycle_start, TESTING_NOW, BELONGS_LS)
    chain_replace(number, TESTING_NOW, NOT_IN_LS)

print(sum([i for i, n in enumerate(state) if n==BELONGS_LS]))
Sean L.
May 28, 2018

Python 3 code:

nums = {}    # dictionary of all numbers and what they iterate to
ends = []    # limit set
def f(num):    # this is the iterative function, which works in a creative way
    sum = 0
    for digit in str(num):
        sum += int(digit)**3
    return(sum)
for num in range(1, 100000):    # adds each number up to 99,999 and what it iterates to to the nums dictionary
    path = []
    iter = num
    nums[iter] = f(iter)
    while iter not in path:
        path.append(iter)
        nums[iter] = f(iter)
        iter = f(iter)
for maybe in nums:    # checks for numbers in the limit set
    iter = maybe
    cycle = 0
    uncompleted = True
    while cycle < 20 and uncompleted:
        iter = f(iter)
        if iter == maybe:
            ends.append(maybe)
            uncompleted = False
        a += 1
sum = 0
for num in ends:     # sums all the numbers in the limit set to get to the final sum
    sum += num
print(sum)    # final sum
Abir Hasan
Apr 9, 2021
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def f(n):
    """Return the sum of the cubes
     of the digits of the input n."""
    return sum([int(i)**3 for i in str(n)]) 

def graph(n):
    """Return all the digit-cubes of a cycle upto
    the repeating value as a list."""
    lst = [n]
    next = f(n)
    lst.append(next)
    while lst.count(next) != 2:
        next = f(next)
        lst.append(next)
    return lst

def limit_set(lst):
    """Return the list of limit cycle."""
    for i in lst:
        if lst.count(i) == 2:
            return lst[lst.index(i):]
def main(m):
    set_lst = []
    # Find all the limit sets
    for i in range(m):
        set_lst.extend(
               list(set(limit_set(graph(i)))))

    # Print the sum of all limit set items
    print(sum(list(set(set_lst ))))

# Maximum sum of digits cubes of 4-digit
#number is 9999
main(9999)

Misael Cureño
May 15, 2019
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
domain = 2000
number_of_iterations = 100
limit_set = []
limit_set_sum = 0

# Structure of the function
def f(n):
    sum = 0
    digits = list(str(n))

    for digit in digits:
       sum += int(digit)**3

    return(sum)

# We define a function to iterate n times the result of f, so
def limitCycle(initial_number, n):
    results_obtained = []
    limit_cycle = set({})

    for time in range(n):
        if f(initial_number) in results_obtained:
            limit_cycle.add(initial_number)
        results_obtained.append(f(initial_number))
        initial_number = results_obtained[-1]

    return limit_cycle

# Now we define a function to run over a domain and obtain all lifecycles
def limitSet(n, number_of_iterations):
    limit_set = set({})

    for number in range(n):
        limit_set = limit_set | (limitCycle(number, number_of_iterations))

    return limit_set

# Create a function to sum the elements of a set
def sumSet(set):
    sum = 0
    for element in set:
        sum += element
    return sum

print(sumSet(limitSet(domain, number_of_iterations)))

f = Plus@@Table [ i 3 , { i , IntegerDigits [ $#$1 ] } ] & ; f=\text{Plus}\text{@@}\text{Table}\left[i^3,\{i,\text{IntegerDigits}[\text{\$\#\$1}]\}\right]\&;

limitSet = { } ; Do [ limitSet = limitSet With [ { result = NestWhileList [ f , i , UnsameQ , All ] } , result [ [ Position [ result , Last [ result ] ] [ [ 1 , 1 ] ] + 1 ;; 1 ] ] ] , { i , 0 , 9999 } ] , i ] \text{limitSet}=\{\}; \\ \text{Do}[ \\ \text{limitSet}=\text{limitSet}\cup \text{With}[\{\text{result}=\text{NestWhileList}[f,i,\text{UnsameQ},\text{All}]\}, \\ \text{result}[[\text{Position}[\text{result},\text{Last}[\text{result}]][[1,1]]+1\text{;;}-1]]], \\ \{i,0,9999\}],i]

Plus@@limitSet 5227 \text{Plus}\text{@@}\text{limitSet} \Longrightarrow 5227

Nimita Kulkarni
Jun 3, 2018

I noticed that, we need to iterate only from 1 to 137 to cover all the numbers in limit set. Trying to figure out what is it about '137'...

From 1 to 136 is enough

Ar Li - 2 years, 12 months ago
Ken Haley
Jun 2, 2018

Python solution:

def sumOfDigitsCubed(n):
    result = 0;
    while n > 0:
        d = n % 10
        result += d*d*d
        n = n // 10
    return result

def findLimitCycle(parm):
    tempList = [];
    n = parm
    while n not in tempList:
        tempList.append(n)
        n = sumOfDigitsCubed(n)
    indx = tempList.index(n)
    return tempList[indx:]

result = []
for i in range(1,1000):
      thisCycle =  findLimitCycle(i)
      if thisCycle[0] not in result:
          result.extend(thisCycle)
result.sort()
print (result)
print(sum(result))

By the way, how do you format code with line numbers, like I see in other solutions posted here?

You start a line with P y t h o n ```Python break line, write your code and end in a new line with ```

Jakob Wege
Jun 2, 2018

The maximum value of f f for an n n -digit number is 9 3 n 9^3 \cdot n . Since this is equal to 2916 2916 , which has 4 digits, for 4-digit numbers and stays smaller than the numbers as they get larger, only numbers up to 2916 2916 need to be considered.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def f(n):
    return sum(int(x) ** 3 for x in str(n))

table = {n: f(n) for n in range(1, 2917)}
limit = set()
while table:
    cur = next(iter(table))
    seq = [cur]
    while True:
        try:
            cur = table[cur]
        except KeyError:
            for x in seq[:-1]:
                del table[x]
            break
        if cur in seq:
            limit |= set(seq[seq.index(cur):])
            for x in seq:
                del table[x]
            break
        else:
            seq.append(cur)
print(sum(limit))

Yes, proper Python coders will probably stone me for breaking every principle of the Zen of Python, but it works, so...

Lamer Zhang
Jun 1, 2018

I used c++

Maxence Seymat
May 31, 2018

Here's a compact solution using dictionaries in Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def f(n): # function f
    s = 0
    while n > 0:
        s += (n % 10)**3
        n //= 10
    return s

Dict = {}
for i in range(10000):
    seq = [i]
    j = f(i)
    while True:
        if j in Dict:
            Dict[i] = Dict[j] # could be also [] since it won't count
            break
        elif j in list:
            Dict[i] = seq[seq.index(j):] # limit set starting from first repeated number
            break
        else:
            seq.append(j)
            j = f(j)

print(sum(i for i in range(10000) if i in Dict[i])) # a number is in the limit set iff it appears in its own limit set

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...