user2147243
user2147243

Reputation: 35

replace goto using recursion

I have a simple digit root calculation (ie. sum all the digits in an integer, and if the total is more than one digit, repeat the process until you end up with a single digit answer).

My first impulse is to simply calculate the sum of the digits in the initial string, test if the result is more than one digit, and if so, goto the start of the summing suite:

eg.

line = "123456789"
sum_digits = 0    
# label: if I could use goto, it would go to here!
n_chars = len(line)
while n_chars > 0:
    sum_digits = sum_digits + int(line[0])
    line = line[1:]
    n_chars -= 1
line = str(sum_digits)
if len(line) < 2: # all done
    print("digital root is ", sum_digits);
else:
    goto label: # need to repeat until get single digit root number

But, of course, python doesn't support 'goto' -- so I guess this should be written as a recursive function? What is the neatest way to code this?

ps. I'm trying to keep the code very simple to understand/explain as I'm doing this as a coding exercise with my son, who is learning programming

Upvotes: 1

Views: 323

Answers (7)

starcodex
starcodex

Reputation: 2298

To replace the goto the idea is to keep track of what the line is after every iteration you find its sum.

So, if I understand your question, the following should work:

def find_root(line):
    while len(line) > 1:
         sum_digits = 0
         for num in list(line):
             sum_digits += int(num)
         line = str(sum_digits)
    print line


>>find_root("123456789")
9
>>find_root("93856")
4

Upvotes: 1

John La Rooy
John La Rooy

Reputation: 304413

Or you can just "do it the math way"

def find_root(s):
    return (int(s) - 1) % 9 + 1

>>> find_root("12345")
6
>>> find_root("8753")
5
>>> find_root("6743")
2

Upvotes: 1

ManZzup
ManZzup

Reputation: 526

try a main loop

EDIT: sorry about that, forgot to reset sum_digit

line = "123456789"
sum_digits = 0    
# label: if I could use goto, it would go to here!

while len(line) > 1:
   n_chars = len(line)
   while n_chars > 0:
       sum_digits = sum_digits + int(line[0])
       line = line[1:]
       n_chars -= 1
   line = str(sum_digits)
   sum_digits = 0

print("digital root is ", sum_digits);

Upvotes: 0

matt
matt

Reputation: 2449

def dig_root(line):
    while len(line) > 1:
        total = 0
        for num in line:
            total += int (num)
        line = str(total)
    print "The digital root is: " + str (line)

>>> dig_root("12345")

The digital root is: 6

>>> dig_root("8753")

The digital root is: 5

>>> dig_root("6743")

The digital root is: 2

There we go. I need to read more carefully.

Upvotes: 0

user890167
user890167

Reputation:

Might I suggest the following:

>>> def digiroot(number_string):
...     while len(number_string) > 1:
...             sum = 0
...             for i in number_string:
...                     sum += int(i)
...             number_string = str(sum)
...     print number_string
... 
>>> digiroot("124")
7
>>> digiroot("12487")
4
>>> digiroot("12487123")
1
>>> digiroot("123456789")
9

Upvotes: 0

venpa
venpa

Reputation: 4318

Using recursion and list comprehension:

def sumdigits(n):
    if len(n) > 1:
        t=sum([int(d) for d in n])
        return sumdigits(str(t))
    else:
        return n

print sumdigits("123456789")
  1. get the numbers as string
  2. if length of string is more than one recursively call the function to calculate the sum
  3. otherwise return the sum

Upvotes: 0

bobbruno
bobbruno

Reputation: 94

You could try the following code:

def calc_root(num_string):
    root = 10
    num_string2 = str(num_string)
    while root >= 10:
       root = sum([int(x) for x in num_string2])
       num_string2 = str(root)
    return root

That will reduce to a single-digit root with no recursion. The idea is that it will stay on the while loop as long as the calculated root is equal or larger than 10.

You could add a check for isdigit on num_string2 and an exception, but that would complicate the code and should be a later step.

Upvotes: 0

Related Questions