Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive function dies with Memory Error

Say we have a function that translates the morse symbols:

  • . -> -.
  • - -> ...-

If we apply this function twice, we get e.g:

. -> -. -> ...--.

Given an input string and a number of repetitions, want to know the length of the final string. (Problem 1 from the Flemish Programming Contest VPW, taken from these slides which provide a solution in Haskell).

For the given inputfile

4
. 4
.- 2
-- 2 
--... 50

We expect the solution

44
16
20
34028664377246354505728

Since I don't know Haskell, this is my recursive solution in Python that I came up with:

def encode(msg, repetition, morse={'.': '-.', '-': '...-'}):
    if isinstance(repetition, str):
        repetition = eval(repetition)
    while repetition > 0:
        newmsg = ''.join(morse[c] for c in msg)
        return encode(newmsg, repetition-1)
    return len(msg)


def problem1(fn):
    with open(fn) as f:
        f.next()
        for line in f:
            print encode(*line.split())

which works for the first three inputs but dies with a memory error for the last input.

How would you rewrite this in a more efficient way?

Edit

Rewrite based on the comments given:

def encode(p, s, repetition):
    while repetition > 0:
        p,s = p + 3*s, p + s
        return encode(p, s, repetition-1)
    return p + s


def problem1(fn):
    with open(fn) as f:
        f.next()
        for line in f:
            msg, repetition = line.split()
            print encode(msg.count('.'), msg.count('-'), int(repetition))

Comments on style and further improvements still welcome

like image 594
BioGeek Avatar asked May 09 '12 17:05

BioGeek


People also ask

Does recursion use stack or heap?

Memory Allocation in Recursion. When a function is called, its memory is allocated on a stack.

Which of the following is false about recursion?

Explanation: A recursive function is tail recursive when recursive call is executed by the function in the last. 9. Which of the following statements is false about recursion? Explanation: A recursive function needn't have a return value.

What is recursion error?

In some ways, recursion is analogous to a loop. Both execute the same code multiple times, and both require a condition (to avoid an infinite loop, or rather, infinite recursion in this case). When there are too many function calls, or a function is missing a base case, JavaScript will throw this error.

How does memory recursion work?

When any function is called from main(), the memory is allocated to it on the stack. A recursive function calls itself, the memory for a called function is allocated on top of memory allocated to the calling function and a different copy of local variables is created for each function call.


1 Answers

Consider that you don't actually have to output the resulting string, only the length of it. Also consider that the order of '.' and '-' in the string do not affect the final length (e.g. ".- 3" and "-. 3" produce the same final length).

Thus, I would give up on storing the entire string and instead store the number of '.' and the number of '-' as integers.

like image 61
DGH Avatar answered Sep 18 '22 09:09

DGH