diff --git a/README.md b/README.md index fda46c1..a746b50 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # frog_problem -Here is the frog problem code I wrote in an Edinburgh pub. -Feel free to make better version. This one has not changed since I wrote it. V1 was the same code but saved before I changed it to work for different distances so I have not bothered upload it as well (it was still very unifinished). +It uses numpy arrays to simulate multiple frogs. +The answer to how many jumps the frog needs to do to reach the end is quite clear :) -Video is here: https://youtu.be/ZLTyX4zL2Fc +Original Video is here: https://youtu.be/ZLTyX4zL2Fc diff --git a/frog-2.py b/frog-2.py deleted file mode 100644 index c0b0eec..0000000 --- a/frog-2.py +++ /dev/null @@ -1,38 +0,0 @@ -def frog(final_dist=100,max=6): - - # I wrote this quickly in a pub - # Don't judge me - - total_dist = 1 - - while total_dist <= final_dist: - - import random - - cap = 10**max - - trials = 0 - total_leaps = 0 - - while trials <= cap: - - dist = total_dist - leaps = 0 - - while dist > 0: - this_jump = int(random.random()*(dist)+1) - dist -= this_jump - leaps += 1 - - total_leaps += leaps - - trials += 1 - - print "{0}\t{1}".format(total_dist,(total_leaps*1.0)/trials) - - total_dist += 1 - - return "DONE" - - - \ No newline at end of file diff --git a/frog.py b/frog.py new file mode 100644 index 0000000..4f80c12 --- /dev/null +++ b/frog.py @@ -0,0 +1,64 @@ + +import numpy as np +import matplotlib.pyplot as plt + + +randomGenerator = np.random.default_rng() # Require numpy v1.17+ + + +ite = 1000 # Number of loops for the average +maxDistance = 1000 + + +totalDist = np.arange(1, maxDistance) + +randomLeap = np.empty_like(totalDist) +totalLeaps = np.zeros_like(totalDist) + +for i in range(ite): + + print(f" - Iteration {i+1}/{ite}", end="\r") + + distLeft = totalDist.copy() + + leaps = np.zeros_like(totalDist) + + stillLeaping = np.ones_like(totalDist, dtype=bool) + + while np.any(stillLeaping): + + randomLeap[stillLeaping] = randomGenerator.integers( + 1, distLeft[stillLeaping], endpoint=True) + + np.subtract(distLeft, randomLeap, where=stillLeaping, out=distLeft) + + leaps[stillLeaping] += 1 + + stillLeaping[distLeft == 0] = False # Arrived at the end + + np.add(totalLeaps, leaps, out=totalLeaps) + +print() + +averageLeaps = totalLeaps/ite + +A, B = np.polyfit(np.log(totalDist), averageLeaps, 1) + +print(f"Average number of leaps ≈ {A:.5}*ln(Total distance)+{B:.5}") + +plt.plot(totalDist, A*np.log(totalDist)+B, linewidth=2, label=f"y≈{A:.5}*ln(x)+{B:.5}") + +plt.scatter(totalDist, averageLeaps, s=2, marker="*", color="green") + +plt.grid(True) + +# plt.xscale("symlog") + +plt.xlabel("Total distance") +plt.ylabel("Leaps") + +plt.legend() + +plt.title("Average number of leaps") + +plt.show()