This commit is contained in:
Manas Karekar 2013-03-03 17:18:54 -08:00
commit 7b633f4529
10 changed files with 87 additions and 85 deletions

View file

@ -68,7 +68,9 @@ The output is telling you that you have a failing test in the file named
`01_equalities.clj`, on line 3. So you just need to open that file up and make `01_equalities.clj`, on line 3. So you just need to open that file up and make
it pass! You'll always be filling in the blanks to make tests pass. it pass! You'll always be filling in the blanks to make tests pass.
Sometimes there could be several correct answers (or even an infinite number): Sometimes there could be several correct answers (or even an infinite number):
any of them will work in these cases. any of them will work in these cases. Some tests will pass even if you replace
the blanks with whitespace or nothing instead of the expected answer. Make sure
you give one correct expression to replace each blank.
The koans differ from normal TDD in that the tests are already written for you, The koans differ from normal TDD in that the tests are already written for you,
so you'll have to pay close attention to the failure messages, because up until so you'll have to pay close attention to the failure messages, because up until

View file

@ -1,21 +1,21 @@
(meditations (meditations
"We shall contemplate truth by testing reality, via equality" "We shall contemplate truth by testing reality, via equality"
(= __ true) (= true true)
"To understand reality, we must compare our expectations against reality" "To understand reality, we must compare our expectations against reality"
(= __ (+ 1 1)) (= 2 (+ 1 1))
"You can test equality of many things" "You can test equality of many things"
(= (+ 3 4) __ (+ 2 __)) (= (+ 3 4) 7 (+ 2 5))
"Some things may appear different, but be the same" "Some things may appear different, but be the same"
(= 2 2/1 __) (= 2 2/1 4/2)
"You cannot generally float to heavens of integers" "You cannot generally float to heavens of integers"
(= __ (= 2 2.0)) (= false (= 2 2.0))
"But a looser equality is also possible" "But a looser equality is also possible"
(== 2.0 2 __) (== 2.0 2 4/2)
"When things cannot be equal, they must be different" "When things cannot be equal, they must be different"
(not= :fill-in-the-blank __)) (not= :fill-in-the-blank :not))

View file

@ -1,34 +1,34 @@
(meditations (meditations
"Lists can be expressed by function or a quoted form" "Lists can be expressed by function or a quoted form"
(= '(__ __ __ __ __) (list 1 2 3 4 5)) (= '(1 2 3 4 5) (list 1 2 3 4 5))
"They are Clojure seqs (sequences), so they allow access to the first" "They are Clojure seqs (sequences), so they allow access to the first"
(= __ (first '(1 2 3 4 5))) (= 1 (first '(1 2 3 4 5)))
"As well as the rest" "As well as the rest"
(= __ (rest '(1 2 3 4 5))) (= [2 3 4 5] (rest '(1 2 3 4 5)))
"The rest when nothing is left is empty" "The rest when nothing is left is empty"
(= __ (rest '(100))) (= [] (rest '(100)))
"And construction by adding an element to the front is simple" "And construction by adding an element to the front is simple"
(= __ (cons :a '(:b :c :d :e))) (= '(:a :b :c :d :e) (cons :a '(:b :c :d :e)))
"Conjoining an element to a list can be done in the reverse order" "Conjoining an element to a list can be done in the reverse order"
(= __ (conj '(:a :b :c :d :e) 0)) (= '(0 :a :b :c :d :e) (conj '(:a :b :c :d :e) 0))
"You can use a list like a stack to get the first element" "You can use a list like a stack to get the first element"
(= __ (peek '(:a :b :c :d :e))) (= :a (peek '(:a :b :c :d :e)))
"Or the others" "Or the others"
(= __ (pop '(:a :b :c :d :e))) (= '(:b :c :d :e) (pop '(:a :b :c :d :e)))
"But watch out if you try to pop nothing" "But watch out if you try to pop nothing"
(= __ (try (= "No dice!" (try
(pop '()) (pop '())
(catch IllegalStateException e "No dice!"))) (catch IllegalStateException e "No dice!")))
"The rest of nothing isn't so strict" "The rest of nothing isn't so strict"
(= __ (try (= () (try
(rest '()) (rest '())
(catch IllegalStateException e "No dice!")))) (catch IllegalStateException e "No dice!"))))

View file

@ -1,33 +1,33 @@
(meditations (meditations
"You can use vectors in clojure to create an 'Array' like structure" "You can use vectors in clojure to create an 'Array' like structure"
(= __ (count [42])) (= 1 (count [42]))
"You can create a vector in several ways" "You can create a vector in several ways"
(= __ (vec nil)) (= [] (vec nil))
"And populate it in either of these ways" "And populate it in either of these ways"
(= __ (vec '(1))) (= [1] (vec '(1)))
"There is another way as well" "There is another way as well"
(= __ (vector nil)) (= [nil] (vector nil))
"But you can populate it with any number of elements at once" "But you can populate it with any number of elements at once"
(= [1 __] (vec '(1 2))) (= [1 2] (vec '(1 2)))
"And add to it as well" "And add to it as well"
(= __ (conj (vec nil) 333)) (= [333] (conj (vec nil) 333))
"You can get the first element of a vector like so" "You can get the first element of a vector like so"
(= __ (first [:peanut :butter :and :jelly])) (= :peanut (first [:peanut :butter :and :jelly]))
"And the last in a similar fashion" "And the last in a similar fashion"
(= __ (last [:peanut :butter :and :jelly])) (= :jelly (last [:peanut :butter :and :jelly]))
"Or any index if you wish" "Or any index if you wish"
(= __ (nth [:peanut :butter :and :jelly] 3)) (= :jelly (nth [:peanut :butter :and :jelly] 3))
"You can also slice a vector" "You can also slice a vector"
(= __ (subvec [:peanut :butter :and :jelly] 1 3)) (= [:butter :and] (subvec [:peanut :butter :and :jelly] 1 3))
"Equality with collections is in terms of values" "Equality with collections is in terms of values"
(= (list 1 2 3) (vector 1 2 __))) (= (list 1 2 3) (vector 1 2 3)))

View file

@ -1,18 +1,18 @@
(meditations (meditations
"You can create a set in two ways" "You can create a set in two ways"
(= #{} (set __)) (= #{} (set nil))
"They are another important data structure in clojure" "They are another important data structure in clojure"
(= __ (count #{1 2 3})) (= 3 (count #{1 2 3}))
"Remember that a set is a 'set'" "Remember that a set is a 'set'"
(= __ (set '(1 1 2 2 3 3 4 4 5 5))) (= #{1 2 3 4 5} (set '(1 1 2 2 3 3 4 4 5 5)))
"You can ask clojure for the union of two sets" "You can ask clojure for the union of two sets"
(= __ (clojure.set/union #{1 2 3 4} #{2 3 5})) (= #{1 2 3 4 5} (clojure.set/union #{1 2 3 4} #{2 3 5}))
"And also the intersection" "And also the intersection"
(= __ (clojure.set/intersection #{1 2 3 4} #{2 3 5})) (= #{2 3} (clojure.set/intersection #{1 2 3 4} #{2 3 5}))
"But don't forget about the difference" "But don't forget about the difference"
(= __ (clojure.set/difference #{1 2 3 4 5} #{2 3 5}))) (= #{1 4} (clojure.set/difference #{1 2 3 4 5} #{2 3 5})))

View file

@ -1,50 +1,50 @@
(meditations (meditations
"There are two ways to create maps" "There are two ways to create maps"
(= __ (hash-map)) (= {} (hash-map))
"Maps in clojure associate keys with values" "Maps in clojure associate keys with values"
(= __ (count (hash-map))) (= 0 (count (hash-map)))
"A value must be supplied for each key" "A value must be supplied for each key"
(= {:a 1} (hash-map :a __)) (= {:a 1} (hash-map :a 1))
"The size is the number of entries" "The size is the number of entries"
(= __ (count {:a 1 :b 2})) (= 2 (count {:a 1 :b 2}))
"You can look up the value for a given key" "You can look up the value for a given key"
(= __ (get {:a 1 :b 2} :b)) (= 2 (get {:a 1 :b 2} :b))
"Maps can be used as lookup functions" "Maps can be used as lookup functions"
(= __ ({:a 1 :b 2} :a)) (= 1 ({:a 1 :b 2} :a))
"And so can keywords" "And so can keywords"
(= __ (:a {:a 1 :b 2})) (= 1 (:a {:a 1 :b 2}))
"But map keys need not be keywords" "But map keys need not be keywords"
(= __ ({2006 "Torino" 2010 "Vancouver" 2014 "Sochi"} 2010)) (= "Vancouver" ({2006 "Torino" 2010 "Vancouver" 2014 "Sochi"} 2010))
"You may not be able to find an entry for a key" "You may not be able to find an entry for a key"
(= __ (get {:a 1 :b 2} :c)) (= nil (get {:a 1 :b 2} :c))
"But you can provide your own default" "But you can provide your own default"
(= __ (get {:a 1 :b 2} :c :key-not-found)) (= :key-not-found (get {:a 1 :b 2} :c :key-not-found))
"You can find out if a key is present" "You can find out if a key is present"
(= __ (contains? {:a nil :b nil} :b)) (= true (contains? {:a nil :b nil} :b))
"Or if it is missing" "Or if it is missing"
(= __ (contains? {:a nil :b nil} :c)) (= false (contains? {:a nil :b nil} :c))
"Maps are immutable, but you can create a new, 'changed' version" "Maps are immutable, but you can create a new, 'changed' version"
(= {1 "January" 2 __} (assoc {1 "January" } 2 "February")) (= {1 "January" 2 "February"} (assoc {1 "January" } 2 "February"))
"You can also 'remove' an entry" "You can also 'remove' an entry"
(= {__ __} (dissoc {1 "January" 2 "February"} 2)) (= {1 "January"} (dissoc {1 "January" 2 "February"} 2))
"Often you will need to get the keys (which will be in hash order)" "Often you will need to get the keys (which will be in hash order)"
(= (list __ __ __) (= (list 2006 2010 2014)
(sort (keys {2006 "Torino" 2010 "Vancouver" 2014 "Sochi"}))) (sort (keys {2006 "Torino" 2010 "Vancouver" 2014 "Sochi"})))
"Or the values" "Or the values"
(= (list "Sochi" "Torino" __) (= (list "Sochi" "Torino" "Vancouver")
(sort (vals {2006 "Torino" 2010 "Vancouver" 2014 "Sochi"})))) (sort (vals {2006 "Torino" 2010 "Vancouver" 2014 "Sochi"}))))

View file

@ -5,25 +5,25 @@
(meditations (meditations
"Functions are often defined before they are used" "Functions are often defined before they are used"
(= __ (multiply-by-ten 2)) (= 20 (multiply-by-ten 2))
"But they can also be defined inline" "But they can also be defined inline"
(= __ ((fn [n] (* __ n)) 2)) (= 20 ((fn [n] (* 10 n)) 2))
"Or using even shorter syntax" "Or using even shorter syntax"
(= __ (#(* 15 %) __)) (= 20 (#(* 10 %) 2))
"Short anonymous functions may take multiple arguments" "Short anonymous functions may take multiple arguments"
(= __ (#(+ %1 %2 %3) 4 5 6)) (= 15 (#(+ %1 %2 %3) 4 5 6))
"One function can beget another" "One function can beget another"
(= __ ((fn [] (= 9 ((fn []
((fn [a b] (__ a b)) ((fn [a b] (+ a b))
4 5)))) 4 5))))
"Higher-order functions take function arguments" "Higher-order functions take function arguments"
(= 25 (___ (= 25 ((fn [func] (func 5))
(fn [n] (* n n)))) (fn [n] (* n n))))
"But they are often better written using the names of functions" "But they are often better written using the names of functions"
(= 25 (___ square))) (= 25 ((defn square5 [square] (square 5)) square)))

View file

@ -9,38 +9,38 @@
(meditations (meditations
"You will face many decisions" "You will face many decisions"
(= __ (if (false? (= 4 5)) (= :a (if (false? (= 4 5))
:a :a
:b)) :b))
"Some of them leave you no alternative" "Some of them leave you no alternative"
(= __ (if (> 4 3) (= [] (if (> 4 3)
[])) []))
"And in such a situation you may have nothing" "And in such a situation you may have nothing"
(= __ (if (nil? 0) (= nil (if (nil? 0)
[:a :b :c])) [:a :b :c]))
"In others your alternative may be interesting" "In others your alternative may be interesting"
(= :glory (if (not (empty? ())) (= :glory (if (not (empty? ()))
:doom :doom
__)) :glory))
"You may have a multitude of possible paths" "You may have a multitude of possible paths"
(let [x 5] (let [x 5]
(= :your-road (cond (= x __) :road-not-taken (= :your-road (cond (= x 2) :road-not-taken
(= x __) :another-road-not-taken (= x 3) :another-road-not-taken
:else __))) :else :your-road)))
"Or your fate may be sealed" "Or your fate may be sealed"
(= __ (if-not (zero? __) (= 'doom (if-not (zero? 1)
'doom 'doom
'doom)) 'doom))
"In case of emergency, sound the alarms" "In case of emergency, sound the alarms"
(= :sirens (= :sirens
(explain-defcon-level __)) (explain-defcon-level :cocked-pistol))
"But admit it when you don't know what to do" "But admit it when you don't know what to do"
(= __ (= :say-what?
(explain-defcon-level :yo-mama))) (explain-defcon-level :yo-mama)))

View file

@ -1,32 +1,32 @@
(meditations (meditations
"The map function relates a sequence to another" "The map function relates a sequence to another"
(= [__ __ __] (map (fn [x] (* 4 x)) [1 2 3])) (= [4 8 12] (map (fn [x] (* 4 x)) [1 2 3]))
"You may create that mapping" "You may create that mapping"
(= [1 4 9 16 25] (map (fn [x] __) [1 2 3 4 5])) (= [1 4 9 16 25] (map (fn [x] (* x x)) [1 2 3 4 5]))
"Or use the names of existing functions" "Or use the names of existing functions"
(= __ (map nil? [:a :b nil :c :d])) (= [false false true false false] (map nil? [:a :b nil :c :d]))
"A filter can be strong" "A filter can be strong"
(= __ (filter (fn [x] false) '(:anything :goes :here))) (= [] (filter (fn [x] false) '(:anything :goes :here)))
"Or very weak" "Or very weak"
(= __ (filter (fn [x] true) '(:anything :goes :here))) (= [:anything :goes :here] (filter (fn [x] true) '(:anything :goes :here)))
"Or somewhere in between" "Or somewhere in between"
(= [10 20 30] (filter (fn [x] __) [10 20 30 40 50 60 70 80])) (= [10 20 30] (filter (fn [x] (< x 40)) [10 20 30 40 50 60 70 80]))
"Maps and filters may be combined" "Maps and filters may be combined"
(= [10 20 30] (map (fn [x] __) (filter (fn [x] __) [1 2 3 4 5 6 7 8]))) (= [10 20 30] (map (fn [x] (* 10 x)) (filter (fn [x] (< x 4)) [1 2 3 4 5 6 7 8])))
"Reducing can increase the result" "Reducing can increase the result"
(= __ (reduce (fn [a b] (* a b)) [1 2 3 4])) (= 24 (reduce (fn [a b] (* a b)) [1 2 3 4]))
"You can start somewhere else" "You can start somewhere else"
(= 2400 (reduce (fn [a b] (* a b)) __ [1 2 3 4])) (= 2400 (reduce (fn [a b] (* a b)) 100 [1 2 3 4]))
"Numbers are not the only things one can reduce" "Numbers are not the only things one can reduce"
(= "longest" (reduce (fn [a b] (= "longest" (reduce (fn [a b]
(if (< __ __) b a)) (if (< (count a) (count b)) b a))
["which" "word" "is" "longest"]))) ["which" "word" "is" "longest"])))

View file

@ -7,19 +7,19 @@
"!"))) "!")))
(defmulti diet (fn [x] (:eater x))) (defmulti diet (fn [x] (:eater x)))
(defmethod diet :herbivore [a] __) (defmethod diet :herbivore [a] (str (:name a) " eats veggies."))
(defmethod diet :carnivore [a] __) (defmethod diet :carnivore [a] (str (a :name) " eats animals."))
(defmethod diet :default [a] __) (defmethod diet :default [a] (str "I don't know what " (:name a) " eats."))
(meditations (meditations
"Some functions can be used in different ways - with no arguments" "Some functions can be used in different ways - with no arguments"
(= __ (hello)) (= "Hello World!" (hello))
"With one argument" "With one argument"
(= __ (hello "world")) (= "Hello, you silly world." (hello "world"))
"Or with many arguments" "Or with many arguments"
(= __ (= "Hello to this group: Peter, Paul, Mary!"
(hello "Peter" "Paul" "Mary")) (hello "Peter" "Paul" "Mary"))
"Multimethods allow more complex dispatching" "Multimethods allow more complex dispatching"