-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Hey Matt,
I've been thinking about this probably too much today and came up with a Python implementation of your recursive solution. I had worked out a slightly different equation on my own, but it turns out that it was exactly the same as yours. I'm really not a trained mathematician in any way, so please don't judge too harshly, I guess.
Anyway, I tossed it around and figured that this can be built up from simple cases, starting with 1 pad ahead of the frog. There's also a case for 0 hops ahead of the frog.
- 0 pads ahead of the frog means that the frog doesn't need to make any jumps.
expectedhops(0) = 0 - 1 pad ahead of the frog means the frog only needs to make one jump, and has a 100% chance of choosing the one jump.
expectedhops(1) = 1 - 2 pads ahead of the frog means the frog has a 50% chance of jumping straight to the end. The frog also has a 50% chance of jumping to a position where there is only one pad remaining, which is a case that has already been solved. We can reuse that value by adding 1, representing the number of hops it took to get to that position.
expectedhops(2) = 0.5*1 + 0.5*(1 + expectedhops(1)) = 1.5 - 3 pads looks similar to 2 pads, except there's a 1/3 chance of jumping to any pad initially.
expectedhops(3) = 0.3ish*1 + 0.3ish*(1+expectedhops(1)) + 0.3ish*(1+expectedhops(2)) - etc
The Python code I have is written to model this is below. I only figured that you'd be interested in it because it's a little bit faster in terms of performance since the results are calculated instead of being randomly generated, which will make it easier to test any explicit solutions. I even added some memoization, for a little bonus kick in performance. Should work on both Python 2.7 and Python 3.X, but really, you need to install Python 3.
def expected_hops(pads_remaining):
"""
Calculates the expected number of hops that a frog will
take if the frog can only hop along a single file line of pads
in a single direction and cannot turn around and hop back
but is able to hop any number of pads in the forward direction,
regardless of the number of pads.
"""
assert pads_remaining >= 0
if pads_remaining == 0: return 0
return (1.0 / pads_remaining) * sum((
1 + expected_hops(i)
for i in range(0, pads_remaining)
))
def memoize(function):
"""
Caches the results of the input function.
"""
_cache = {}
def functionwrapper(x):
if x not in _cache:
_cache[x] = function(x)
return _cache[x]
return functionwrapper
expected_hops = memoize(expected_hops)
if __name__ == '__main__':
for i in range(1, 101):
print (i, expected_hops(i))Fun fact, it appears that the expected number of hops for 10,000 lily pads is 9.78 hops, which is much lower than what I would have expected.