Last active
July 19, 2023 20:22
-
-
Save jimpil/ed7f6cf9729955c1d6c99463defb9c3d to your computer and use it in GitHub Desktop.
Double-Cola (CodeWars) Clojure solutions
This file contains hidden or 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
(ns double-cola.core) | |
;Sheldon, Leonard, Penny, Rajesh and Howard are in the queue | |
;for a "Double Cola" drink vending machine; there are no other | |
;people in the queue. The first one in the queue (Sheldon) buys | |
;a can, drinks it and doubles! The resulting two Sheldons go to | |
;the end of the queue. Then the next in the queue (Leonard) buys | |
;a can, drinks it and gets to the end of the queue as two Leonards, | |
;and so on. | |
(def theq ["Sheldon" "Leonard" "Penny" "Rajesh" "Howard"]) | |
(defn- expand [q i] (mapcat (partial repeat (Math/pow 2 (double i))) q)) | |
(defn who-drinks-lazy | |
[q nth-cola] | |
{:pre [(seq q) | |
(pos-int? nth-cola)]} | |
(-> (partial expand q) | |
(mapcat (range)) | |
(nth (dec nth-cola)))) | |
(comment | |
(who-drinks-lazy theq 1) ;; => "Sheldon" | |
(who-drinks-lazy theq 52) ;; => "Penny" | |
(who-drinks-lazy theq 10010) ;; => "Howard" | |
(who-drinks-lazy theq 7230702951) ;; => ArithmeticException (integer-overflow) - wtf? | |
) | |
(defn who-drinks-optimised | |
[q nth-cola] | |
{:pre [(seq q) | |
(pos-int? nth-cola)]} | |
(let [q-count (count q)] | |
(loop [round 1 | |
total q-count] | |
(let [repetitions (long (Math/pow 2 (double (dec round))))] | |
(if (<= nth-cola total) | |
(let [round-total (* q-count repetitions) | |
cutoff (- total nth-cola) | |
round-index (- round-total cutoff 1)] | |
(->> (range 0 (inc round-total) repetitions) ;; 6 elements | |
(partition 2 1) ;; 5 boundary groups (i.e. [start end]) | |
(keep-indexed | |
(fn [i [start end]] | |
(when (< (dec start) round-index end) | |
(nth q i)))) | |
first)) | |
(recur (inc round) | |
(+ total (* q-count (* 2 repetitions))))))))) | |
(comment | |
(who-drinks-optimised theq 1) ;; => "Sheldon" | |
(who-drinks-optimised theq 52) ;; => "Penny" | |
(who-drinks-optimised theq 10010) ;; => "Howard" | |
(time (who-drinks-optimised theq 7230702951)) ;; => "Leonard" | |
) | |
(defn who-drinks-clever | |
[q nth-cola] | |
{:pre [(seq q) | |
(pos-int? nth-cola)]} | |
(let [qcount (count q) | |
qcount-1 (dec qcount)] | |
(loop [n nth-cola] | |
(if (> n qcount) | |
(recur (-> (- n qcount-1) | |
(/ 2) | |
long)) | |
(nth q (dec n)))))) | |
(comment | |
(who-drinks-clever theq 1) ;; => "Sheldon" | |
(who-drinks-clever theq 52) ;; => "Penny" | |
(who-drinks-clever theq 10010) ;; => "Howard" | |
(time (who-drinks-clever theq 7230702951)) ;; => "Leonard" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment