'Python - obtaining the sum of digits of cube numbers
I want to write a code in python to print The sum of the digits of all whole cube numbers in a range that received from the user. for example if he chose [1,100], 1,8,9,10 are displayed that are related to (1,8,27,64).
Solution 1:[1]
Generally, it would be good practice to show what you've tried to solve the problem...and, if you allow me to give a personal opinion, you'll learn much faster if you at least try something.
EDIT: thanks to @Python learner, I misinterpreted the question. This should go:
def main():
low, up = 1, 100
# list of all cubes in selected range
cubes = []
# go through numbers in selected range, check if they are cubes, append them to list if they are
for i in range(low, up):
if is_cube(i):
cubes.append(i)
# alternative way, using list comprehension
#cubes = [n for n in range(low, up) if is_cube(n)]
# once cubes have been found, go through list
for cube in cubes:
# convert each cube to a str, so you can iterate over the single digits, convert them back to int, and append them to a list
cube_str = str(cube)
digits_list = []
for digit in cube_str:
digits_list.append(int(digit))
print(f'{cube} -> {sum(digits_list)}')
def is_cube(n):
n = abs(n) # if n is negative
return round(n ** (1 / 3)) ** 3 == n
if __name__ == '__main__':
main()
Solution 2:[2]
Use a generator and list comprehension:
import numpy as np
from math import ceil
from typing import Generator
def cubes(start: int, stop: int) -> Generator[int]:
for i in range(start, stop+1):
cbrti = np.cbrt(i)
if cbrti == ceil(cbrti):
yield i
def sum_digits(n: int) -> int:
s = 0
while n:
s += n % 10
n //= 10
return s
result = [sum_digits(i) for i in cubes(1, 100)]
print(result)
Output:
[1, 8, 9, 10]
Solution 3:[3]
Instead of checking one by one that each number in the range is a cube or not, Which is quite a waste of time, you can rather modify the bounds to know all the numbers such as raising them to the power of 3 will create numbers in the range.
The advantage of this method is that you don't have to compute the cube root of each number, after changing the bounds, you know directly which numbers are valid.
Explanation
- If we calculate the cubic root of the start and the end of the range, the new range will contain all numbers with a cube between
start
andend
. - If
start
andend
are not perfect cubes, we take either the integer above if we are at the beginning, or the integer below if we are at the end.
Example: the range is [1,100]
, By calculating the cube root, we get [1, 4]
. Thus 1
, 2
, 3
and 4
cubed are in the range.
Note: This is only possible because f(x) = x^3
is strictly increasing.
import math
start = 1
stop = 100
cubes = []
for i in range(math.ceil(start**(1/3)), math.floor(stop**(1/3)) + 1):
cubes.append(i**3)
print(cubes) # [1, 8, 27, 64]
math.ceil()
is used to round upward to the nearest integermath.floor()
is used to round a downward to the nearest integer.**(1/3)
is used to compute the cubic root of the number (raised to the power 1/3).
Once we have calculated all the cubes, we have to sum them up. There are many ways to do this, either by converting the number to a string and then looking at each character, or by successively dividing the number by 10.
We can for example use a recursive function, which adds each remainder of the division by 10 recursively, until the quotient is zero.
import math
def sum_digits(num):
q, r = divmod(num, 10)
if not q:
return r
return sum_digits(q) + r
start = 1
stop = 100
cubes = []
for i in range(math.ceil(start**(1/3)), math.floor(stop**(1/3)) + 1):
cubes.append(sum_digits(i**3))
print(cubes) # [1, 8, 9, 10]
Note:
If the bounds can be negative:
- The cube root must be calculated in a different way (using
numpy
or multiplying by-1
the cube if it is negative). - The absolute value of the cube must be used to calculate the sum of the digits.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 |