Last active
December 10, 2016 07:25
-
-
Save gdeer81/2f6e7b43361c62a402c0282e7ecb568a to your computer and use it in GitHub Desktop.
bouncey ball problem with 2 different solutions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;compare the two approaches to solving the same problem | |
;;A child plays with a ball on the nth floor of a big building the height of which is known | |
;;(float parameter "h" in meters, h > 0) . | |
;;He lets out the ball. The ball rebounds for example to two-thirds | |
;;(float parameter "bounce", 0 < bounce < 1) | |
;;of its height. | |
;;His mother looks out of a window that is 1.5 meters from the ground | |
;;(float parameters window < h). | |
;;How many times will the mother see the ball either falling or bouncing in front of the window | |
;;(return a positive integer unless conditions are not fulfilled in which case return -1) ? | |
;;(bouncing-balls 3 0.66 1.5) => 3 | |
;;(bouncing-balls 30 0.66 1.5) => 15 | |
;;the first approach is what you would typically see in a languages that encourages mutation | |
;;declare variables and then create a loop and bang on those variables until the loop ends | |
(defn bouncing-balls-with-ugly-mutation [h bounce window] | |
(if (not (< 0 bounce 1)) | |
-1 | |
(let [curr_height (atom h) | |
times (atom 0)] | |
(while (> @curr_height window) | |
(if (> (* bounce @curr_height) window) | |
(do (reset! curr_height (* @curr_height bounce)) (swap! times #(+ 2 %)) ) | |
(do (reset! curr_height (* @curr_height bounce)) (swap! times inc)) | |
)) | |
@times))) | |
;;this approach could probably be cleaned up a little but it introduces NO mutable variables | |
;;the function keeps calling itself with new values until it reaches the base case | |
(defn bouncing-balls | |
([h bounce window] (bouncing-balls h bounce window 0)) | |
([h bounce window bounces] | |
(if (not (< 0 bounce 1)) | |
-1 | |
(if (> window h) | |
bounces | |
(if (> (* bounce h) window) | |
(bouncing-balls (* h bounce) bounce window (+ 2 bounces)) | |
(bouncing-balls (* h bounce) bounce window (inc bounces))))))) | |
;;this implementation is identicle to the one above but with more detailed naming convention >_< | |
(defn bouncing-balls2 | |
([ball-position bounce-percentage mother-position] (bouncing-balls ball-position bounce-percentage mother-position 0)) | |
([ball-position bounce-percentage mother-position times-mother-has-seen-the-ball] | |
(if (not (< 0 bounce-percentage 1)) | |
-1 | |
(let [mother-position-higher-than-current-ball-position? (> mother-position ball-position) | |
balls-next-position (* bounce-percentage ball-position) | |
balls-next-position-higher-than-mother-position? (> balls-next-position mother-position) | |
then-return-current-number-of-times-mother-has-seen-the-ball times-mother-has-seen-the-ball | |
increase-the-number-of-times-mother-has-seen-the-ball-by-two (+ 2 times-mother-has-seen-the-ball) | |
increase-the-number-of-times-mother-has-seen-the-ball-by-one (inc times-mother-has-seen-the-ball) | |
call-bouncing-balls-again-but (partial (bouncing-balls2 balls-next-position bounce-percentage mother-position)) | |
] | |
(if mother-position-higher-than-current-ball-position? then-return-current-number-of-times-mother-has-seen-the-ball | |
(if balls-next-position-higher-than-mother-position? | |
(call-bouncing-balls-again-but increase-the-number-of-times-mother-has-seen-the-ball-by-two) | |
(call-bouncing-balls-again-but increase-the-number-of-times-mother-has-seen-the-ball-by-one))))))) | |
;;;this is the mathematician's solution | |
(defn bouncing-balls [h bounce window] | |
(if-not (and (> h 0) (< 0 bounce 1) (< window h)) -1 | |
(-> (/ window h) Math/log (/ (Math/log bounce)) Math/ceil int (* 2) dec))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment