2

I want to make a function that returns two values. The first should be the output of the ackerman function, and the second should be the number of times the function is called.

I've made the Ack function:

def ack(m,n):
    if m == 0:
        return n + 1
    elif m > 0 and n == 0:
        return ack(m - 1.0, 1.0)
    elif m > 0 and n > 0:
        return ack(m - 1.0, ack(m, n - 1.0))

I tried making a global count and adding it before the if and elifs and return it with the answer:

global count
count +=1

if m == 0:
    return n+1, count

This is obviously wrong. It will return the count every time m = 0, and it would be a tuple.

How can I make it so that it returns a list of the answer of (for example) ack(3,4), which should be 125, and the number of times it had to call ack(m,n). So if I call ack(1.0,0.0) it should return [2.0, 2]. I need a list because I need to make some calculations with that sum.

The reason I need to know is because of an assignment out teacher gave us and I am completely stuck.

Zahand
  • 490
  • 3
  • 12
  • 23

2 Answers2

2

Just add 1 each time you recurse:

def ack(m,n):
    if m == 0:
        return (n + 1, 1)
    elif m > 0 and n == 0:
        a, cnt = ack(m - 1.0, 1.0)
        return a, cnt+1
    elif m > 0 and n > 0:
        a1, cnt1 = ack(m, n - 1.0)
        a2, cnt2 = ack(m - 1.0, a1)
        return a2, 1 + cnt1 + cnt2



>>> ack(3, 4)
    (125.0, 10307)
>>> ack(1, 0)
    (2.0, 2)
Elias Dorneles
  • 22,556
  • 11
  • 85
  • 107
  • Could you explain how this works? Since I am new to programming I don't quite understand what "a" is and how you can give two variables the same value? (a, cnt = ack(m-1.0,1.0)). If I try (for example): a, b = 3 and print a and b, I get an error. – Zahand Apr 13 '14 at 20:19
  • Oh and btw, doesn't this return a tuple? I need a list so that I can access the values at the indexes and make more calculations whit them. – Zahand Apr 13 '14 at 20:21
  • 1
    It works the same way as the recursion you were already doing works. The assignment is tuple unpacking; `a, b = (1, 2)` causes `a` to name the `1` and `b` to name the `2`. You can do almost everything with a tuple that you can do with list - you just can't replace its elements. – Karl Knechtel Apr 13 '14 at 20:59
  • @Zahand Well, Karl explained it already. The function returns a tuple, yes, which you use just like a list, the difference is that its content is fixed. In `a, cnt = ack(m - 1.0, 1.0)`, the ack function returns a tuple with two elements, `a` will get the first element (the result of the calulation) and `cnt` will get the second (the total count). – Elias Dorneles Apr 13 '14 at 21:21
0

Just add a count and increment each call:

def ack(m,n):
    if m == 0:
        return n + 1, 1
    elif m > 0 and n == 0:
        res, count = ack(m - 1, 1)
        return res, count + 1
    elif m > 0 and n > 0:
        t, tc = ack(m, n - 1)
        res, rc = ack(m - 1, t)
        return res, tc + rc + 1
Yuval Adam
  • 161,610
  • 92
  • 305
  • 395