Genetically Educated Bunnies
Tags: Coding, Puzzle, Recursion, Computer Science, Optimisation

Solution

The first step for the solution of the problems would be to write the recursive functions associated with them. This is a trivial task but it’s necessary in order to better understand how they can eventually be manipulated and optimised. Focusing on the first problem, the recursive function should be more or less equivalent to the following:

Notice how the recursive function generates a binary tree which needs to be traversed in order to produce a viable result. That is 2 at the power of g passes where g is the depth of the tree. Also notice that every time a node has been reached, its values are going to be maintained in memory until the subsequent nodes resolve. So every time you run the function, the memory complexity rapidly increases to O(2^g) and then rapidly decreases to Ω(1), therefore the space required for the operation is O(2^g). It is not an ideal solution because if the input number g tends to be a big number, the program would not be able to return a viable answer with limited time or space resources.

If somehow we had two values w and k representing f(g − 1, n) and f(g − 2, n) the resulting function could theoretically be as complex as time Θ(1) with memory Θ(1). However, we need to calculate f(g − 1, n) and f(g − 2, n) before we run the function. Taking a closer look at the tree leaves at depth g < 1, we notice that the values of w and k are always assuming the value n. Then traversing backwards we notice that w assumes the last value that the function had. However k needs to hold the value of the function taken before the last value. If we iterate from the last nodes we can set up k being equal to w because for the next iteration the current w would be the value f(g − 2, n). Then we can set up w for the next iteration assigning the current result of the function because in the next iteration, the current result would be equal to the value f(g − 1, n). It’s important that we set k before w so we don’t lose the value that w holds. Summarising what we’ve just theorised:

We’ve reached a much better solution, and it only requires time complexity O(g) with memory complexity Θ(1) since we reuse w and k for every iteration and we do not need every node of the binary tree, actively storing only the last two values of the function.

Focusing on the second problem, we get the following recursive function:

We notice that since the function only requires the last value to work, its time and space complexities are O(g). However the recursive function is linear which means that it can be summarised with the following:

We can further optimise the function by removing the recursion and handling the special cases:

To get a clear picture of the function we can plot the corresponding graph:

Plot of the original, optimised function.

The farmer needs to know how many generations g were necessary in order to breed k given bunnies starting with thoroughbred rabbits. So we need to calculate g from f(g) = k which now expands in 5g + 2 = k when g ≥ 1 and k = 2 when g < 1. Since g is not something we know in advance, we need to address the right condition for this to work. Given that the function changes at g = 1, knowing that f(g) = k and and so f(1) = 7 we can assume k = 7 for the branching condition.

At this point it is unclear if given k < 7 what the g value should be; an infinite number of answers can be found in that case, so we simply inform the farmer that he can’t use the program to calculate the number of generations if the number of bunnies is less than 7.

For values of k ≥ 7 we get k = 5g + 2, g = (k − 2) / 5 which can be visualised with the following plot:

Plot of the “solution” function.

We can finally write the second function:

In conclusion we can say that even if the problem doesn’t have a clear answer for k < 7, that doesn’t mean we shouldn’t look for a solution in the range k ≥ 7. The farmer thanks you for all you have done for him and decides to sell all of his rabbits. He can now focus on his real passion: beekeeping.