简体   繁体   中英

take a number and sum its digits

I'm working through this Kata and although I've looked through the solutions none are quite similar enough to mine to answer my question.

Problem Text: The number 89 is the first integer with more than one digit that fulfills the property partially introduced in the title of this kata. What's the use of saying "Eureka"? Because this sum gives the same number.

In effect: 89 = 8^1 + 9^2

The next number in having this property is 135.

See this property again: 135 = 1^1 + 3^2 + 5^3

We need a function to collect these numbers, that may receive two integers a, b that defines the range [a, b] (inclusive) and outputs a list of the sorted numbers in the range that fulfills the property described above.

def sum_dig_pow(a, b): # range(a, b + 1) will be studied by the function
    # your code here
    lst = []
    n = 1
    tot = 0
    for i in range(a,b):
        if i > 9:
            spl = str(i).split()
            for item in spl:
                tot += int(item) ** n
                n += 1
                if tot == i:
                    lst.append(i)
        else:
            lst.append(i)
    return lst

Tests are returning "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] should equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 89]". I cannot figure out why it's passing 10 and not appending 89. I'm sure there's a more efficient way to do this as well but I'm still learning so want to be working in basics of loops, conditionals,etc.

This line is incorrect:

spl = str(i).split()

The split method will split a string on spaces by default and return a list. So passing i=10 gives back spl = ['10'] , a list with one element. Instead, just iterate over each of the digits in the string.

for item in str(i):
    ...

Follow up: you can shorten your code by using enumerate to count the index of each digit.

def sum_dig_pow(a,b):
    return [sum(int(y)**(i+1) for i,y in enumerate(str(x))) for x in range(a,b)]

Rather than spending a lot of time converting things from numbers to strings and back, try using arithmetic. To iterate over the digits of a number n , take n modulo ten (to get the least-significant digit) and then divide by ten (to peel off that least-significant digit). For example, the digits of 123 (in reverse order) are [(123 % 10), (12 % 10), (1 % 10)]

Thinking of it in terms of functions, first get the digits:

def digits_of_n(n):
  result = []
  while n > 0:
    result.append(n % 10)
    n = n / 10  # in python 3, use 3 // 10 for integer division
  return reversed(result) # reverse list to preserve original order

then get the sum of the powers:

def sum_of_ith_powers(numbers):
  result = 0
  for i, n in enumerate(numbers):  # the digits are ordered most-significant to least, as we would expect
    result += n ** 1
  return result

now you can just call sum_of_ith_powers(digits_of_n(n)) and you have an answer. If you like, you can give that operation a name:

def sum_of_digit_powers(n):
  return sum_of_ith_powers(digits_of_n(n))

and you can then name the function that solves the kata:

def solve_kata(a, b):
  return [sum_of_digit_powers(n) for n in range (a, b)]

You can use a generator , sum and enumerate in order to simplify your code like this example:

def sum_dig_pow(a,b):
    for k in range(a,b+1):
        if k > 9:
            number_sum = sum(int(j)**i for i,j in enumerate(str(k), 1))
            if k is number_sum:
                yield k
        else:
            yield k

print(list(sum_dig_pow(1,10)))
print(list(sum_dig_pow(1,90)))
print(list(sum_dig_pow(1,10000)))
print(list(sum_dig_pow(10,1000)))
print(list(sum_dig_pow(1,900000)))

Output:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 89]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 89, 135, 175]
[89, 135, 175]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 89, 135, 175]
li = []
def sum_dig_pow(a, b):
    for i in range(a, b+1):
        sum1 = 0
        for ind, val in enumerate(str(i), 1):
            sum1 += pow(int(val), int(ind))
        if i == sum1:
            li.append(i)
    return li
print(sum_dig_pow(1, 11))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM