Рекурсивная сумма всех цифр в числе - PullRequest
1 голос
/ 15 апреля 2020

Я застрял в этом упражнении.

Задача:

Цифра root - это рекурсивная сумма всех цифр в числе. Учитывая n, возьмите сумму цифр n. Если это значение имеет более одного di git, продолжайте уменьшать таким образом, пока не будет получено одно число di git. Это применимо только к натуральным числам.

Вот как это работает:

digital_ root (16)
1 + 6 = 7

digital_ root (942)
9 + 4 + 2 = 15 ... 1 + 5 = 6

Мой подход здесь. Любые советы о том, как правильно вернуть правильное значение? Буду признателен за любую помощь.

def digital_root(n):
    answ = 0
    s = 0
    x = str(n)

    for i in range(0, len(x)):
        s = s + int(x[i])
    if len(str(s)) > 1:
        digital_root(s)
    elif len(str(s)) == 1:
        answ = s # here is an answer
        return answ # answer is 2 but this one is not returning 2, why?

    return answ # here it returns answ=0, I want to return 2...

print(digital_root(493193))

Ответы [ 5 ]

3 голосов
/ 15 апреля 2020

Что вы скажете по этому поводу:

def digital_root(n):
    if n<10 :
         return n
    return digital_root( n%10 + digital_root( n//10 ) )
2 голосов
/ 15 апреля 2020

Вот мой взгляд на это. Я чувствовал желание использовать sum, но это почти похоже на мошенничество, так как вы можете просто использовать sum([int(i) for i in str(n)]).

def digital_root(n):
    # convert to a string
    as_str = str(n)

    # get the value of the current first digit
    value = int(as_str[0])

    if len(as_str) > 1:
        # add the recursive return plus the value
        # for anything other than our base case.
        # pass the rest of the digits into our recursive call
        return digital_root(int(as_str[1:])) + value

    # our base case
    return value

print(digital_root(493193))
2 голосов
/ 15 апреля 2020

Основная проблема заключается в том, что при выполнении рекурсивных вызовов вы не присваиваете возвращаемое значение чему-либо, поэтому вы всегда получите 0 для любого значения, требующего более одного прохода.

Также после рекурсивного вызова длина должна быть 1, поэтому следующий elif не требуется и приведет к неправильным возвращаемым значениям, поскольку он не будет присваивать s answ

Фиксированная версия:

def digital_root(n):
    answ = 0
    s = 0
    x = str(n)
    for i in range(0, len(x)):
        s = s + int(x[i])
    if len(str(s)) > 1:
       s = digital_root(s)
    answ = s # You could even return s directly
    return answ

print(digital_root(493193))
1 голос
/ 15 апреля 2020

Вы ничего не делаете с результатом вашего рекурсивного вызова - вот почему ваш код работает неправильно.

Итерирование по индексу в большинстве случаев нехорошо - лучше итерировать по строке напрямую.


Это более чистый способ рекурсии с использованием некоторых встроенных python функций:

def rec_sum(n):
    sn = str(n)
    # base case - return the number
    if len(sn)==1:
        return n

    # not the base case,return whatever the recursive output returns
    return rec_sum(sum(map(int,sn)))


for n in range(1,71):
    print(f"{n:3}=>{rec_sum(n):3}", end = "|")
    if n%7 == 0:
        print()

Вывод:

  1=>  1|  2=>  2|  3=>  3|  4=>  4|  5=>  5|  6=>  6|  7=>  7|
  8=>  8|  9=>  9| 10=>  1| 11=>  2| 12=>  3| 13=>  4| 14=>  5|
 15=>  6| 16=>  7| 17=>  8| 18=>  9| 19=>  1| 20=>  2| 21=>  3|
 22=>  4| 23=>  5| 24=>  6| 25=>  7| 26=>  8| 27=>  9| 28=>  1|
 29=>  2| 30=>  3| 31=>  4| 32=>  5| 33=>  6| 34=>  7| 35=>  8|
 36=>  9| 37=>  1| 38=>  2| 39=>  3| 40=>  4| 41=>  5| 42=>  6|
 43=>  7| 44=>  8| 45=>  9| 46=>  1| 47=>  2| 48=>  3| 49=>  4|
 50=>  5| 51=>  6| 52=>  7| 53=>  8| 54=>  9| 55=>  1| 56=>  2|
 57=>  3| 58=>  4| 59=>  5| 60=>  6| 61=>  7| 62=>  8| 63=>  9|
 64=>  1| 65=>  2| 66=>  3| 67=>  4| 68=>  5| 69=>  6| 70=>  7|

Часть sum(map(int,sn)) означает: map(function,iterable) применяет функцию int() ко всем символам в sn (строки являются итеративными), которые являются строкой вашего числа. Затем он sum() получает его и называет себя с этой суммой.

0 голосов
/ 15 апреля 2020

С рекурсивными функциями, как правило, неплохо бы начать с самого базового c случая, а затем постепенно увеличивать сложность.

Кроме того, полезный трюк заключается в том, чтобы взять list() отреза строки строка в символах, er go list("abc") возвращает ["a", "b", "c"].

Используя это, мы получаем:

def digital_root(n):
    # basic scenario: n is 1 digit, ergo <10. 
    if n < 10:
         return n

    # alternative case: more than 1 digit
    # cut n into digits with a list comprehension
    # str(714) => "714", list(str(714)) => "['7', '1', '4']
    digits = [int(c) for c in list(str(n))]

    # take the digital root of the sum
    return digital_root(sum(digits))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...