-
-
Save adityaathalye/cd3f275086285f15e384ad3707d9cc16 to your computer and use it in GitHub Desktop.
Too many crackle-poppers
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
(ns too.many.crackle-poppers) | |
;; ABOUT: | |
;; | |
;; Solutions to CracklePop, incidentally written in Clojure. | |
;; | |
;; READING GUIDE: | |
;; | |
;; - See the 'check-all-crackle-poppers' function at the bottom, for usage examples. | |
;; - All the solutions use Clojure's standard library functions. | |
;; - Lookup unfamiliar functions at https://clojuredocs.org/quickref | |
;; - Let's call the solutions a bunch of "Crackle Poppers", because why not? | |
;; | |
;; USAGE GUIDE: | |
;; | |
;; If you are a Clojure user, switch to this ns, compile, and start REPL-ing | |
;; up from the forms at the bottom. | |
;; | |
;; If you aren't a Clojure user, do the following to try out the solutions: | |
;; | |
;; - Visit https://repl.it/languages/clojure to access a Clojure REPL session. | |
;; | |
;; - Copy-paste the entire contents of this file into the "main.clj" area. | |
;; | |
;; - Hit "Run". You should see some output in the accompanying "REPL" area. | |
;; The output corresponds to all the top-level constants and functions | |
;; that were defined as a consequence of the "Run". | |
;; | |
;; - Type `(check-all-crackle-poppers)` in the REPL (including the parentheses) | |
;; and hit Enter to evaluate that function---it's a zero-argument function. | |
;; This evaluation should return 'true', which the REPL will print. | |
;; | |
;; - Likewise; try evaluating individual calls to the various crackle poppers. | |
;; For example, evaluate: (crackle-pop canonical-popper range-of-popees) | |
;; Here `crackle-pop` is a function that gets passed two arguments. | |
;; | |
;; - To see what `range-of-popees` is, evaluate it as-is in the REPL | |
;; (type without parentheses, and hit Enter). Similarly, try evaluating | |
;; `crackle-pop`, or `canonical-popper` expressions and see what you get. | |
;; | |
;; CANONICAL IMPLEMENTATION | |
;; - The crackle pop we all know and love. | |
;; | |
(def div? | |
"True when the remainder of n1/n2 is zero. e.g. (div? 4 2) => true" | |
(comp zero? rem)) | |
(defn canonical-popper | |
"First trap all prime factors. Then trap each unique factor one by one. | |
Default to the given number. Order of conditional checks matters." | |
[n] | |
(cond | |
(div? n 15) "CracklePop" | |
(div? n 3) "Crackle" | |
(div? n 5) "Pop" | |
:else n)) | |
;; | |
;; HERETICAL IMPLEMENTATIONS | |
;; - Some oddball and not-so-oddball Crackle Poppers, using features of Clojure, | |
;; and of functional programming. | |
;; | |
(defn crackles? | |
"Truthy when it crackles, Falsey (nil) otherwise. | |
Clojure branching/predicate logic accepts Truthy/Falsey." | |
[n] | |
(when (div? n 3) "Crackle")) | |
(defn pops? | |
"Truthy only when it pops." | |
[n] | |
(when (div? n 5) "Pop")) | |
(defn cracklepops? | |
"Truthy only when it crackles _and_ pops." | |
[n] | |
(when (div? n 15) "CracklePop")) | |
(defn or-popper | |
"Just like conditional matching, but exploit short-circuit behaviour of 'or'. | |
Order of conditional checks matters." | |
[n] | |
(or (cracklepops? n) | |
(crackles? n) | |
(pops? n) | |
n)) | |
(defn juxt-popper | |
"Once someone discovers `juxt`, it _must_ be used _everywhere_. EVERYWHERE. | |
MMWAAAAHAHAHAHAHAHAHAAHHAAAAA. Order of conditional checks matters. | |
((juxt f g h) 42) -> [(f 42) (g 42) (h 42)] | |
cf. https://clojuredocs.org/clojure.core/juxt" | |
[n] | |
(some identity ((juxt cracklepops? crackles? pops? identity) | |
n))) | |
(defn lookup-popper | |
"Encode crackle pop as a lookup table based on remainders of 15. | |
Order of match ceases to matter." | |
[n] | |
(let [crackle-pop-lookup-table {0 "CracklePop" | |
3 "Crackle" | |
6 "Crackle" | |
9 "Crackle" | |
12 "Crackle" | |
5 "Pop" | |
10 "Pop"}] | |
(get crackle-pop-lookup-table | |
(rem n 15) | |
;; default to the given 'n', when not looked-up | |
n))) | |
(def cyclical-popper | |
"Encode crackle pop as a repeating sequence... it is cyclic in modulo 3, 5, and 15. | |
The sequence is ordered by definition." | |
(let [n identity | |
c (constantly "Crackle") | |
p (constantly "Pop") | |
cp (constantly "CracklePop")] | |
(cycle [n n c | |
n p c | |
n n c | |
p n c | |
n n cp]))) | |
;; | |
;; USAGE EXAMPLES | |
;; | |
(def range-of-popees (range 1 101)) ; a sea of popees would be too big | |
(def crackle-pop map) ; now, what `map` can do crackle-pop can too | |
(defn check-all-crackle-poppers | |
"A quick and dirty test. Canonical or Heretical, do all the Poppers | |
ultimately agree with each other?" | |
[] | |
(= (crackle-pop canonical-popper | |
range-of-popees) | |
(crackle-pop or-popper | |
range-of-popees) | |
(crackle-pop juxt-popper | |
range-of-popees) | |
(crackle-pop lookup-popper | |
range-of-popees) | |
(crackle-pop (fn [f n] (f n)) | |
cyclical-popper | |
range-of-popees))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment