clojure-koans/src/path_to_answer_sheet.clj

250 lines
8 KiB
Clojure
Raw Normal View History

(ns path-to-answer-sheet
(:use [runner.koans :only [ordered-koans]]
[path-to-enlightenment :only [meditations __ ___]]
[clojure.string :only [join split trim]]
[clojure.test :only [*test-out*]]))
(def answers
{"equalities" {"__" [true
2
7
2010-10-29 15:18:09 +00:00
5
4/2
false
2010-11-04 13:01:34 +00:00
6/3
3]}
2011-02-14 01:53:25 +00:00
"lists" {"__" [1 2 3 4 5
1
[2 3 4 5]
()
[:a :b :c :d :e]
[0 :a :b :c :d :e]
:a
[:b :c :d :e]
"No dice!"
()]}
2011-02-14 01:53:25 +00:00
2010-10-29 15:45:47 +00:00
"vectors" {"__" [1
[]
[1]
[nil]
2
[333]
:peanut
:jelly
:jelly
[:butter :and]
3]}
2011-02-14 01:53:25 +00:00
2010-10-29 15:45:47 +00:00
"sets" {"__" [3
2010-10-27 22:30:34 +00:00
#{1 2 3 4 5}
#{1 2 3 4 5}
#{2 3}
#{1 4}]}
2011-02-14 01:53:25 +00:00
"maps" {"__" [0
1
2
2
1
1
"Vancouver"
2011-02-03 18:26:58 +00:00
nil
:key-not-found
true
false
"February"
1 "January"
2006 2010 2014
"Vancouver"]}
2011-02-14 01:53:25 +00:00
2010-10-29 15:07:11 +00:00
"functions" {"__" [20
10 5
30 2
2010-11-05 22:33:06 +00:00
15
20 '*]
"___" ['(fn [f] (f 5))
'(fn [f] (f 5))]}
2011-02-14 01:53:25 +00:00
"conditionals" {"__" [:a
[]
0
:glory
2010-11-04 01:38:20 +00:00
4 6 :your_road
2011-04-29 20:34:17 +00:00
''doom 0
:cocked-pistol
:say-what?]}
2011-02-14 01:53:25 +00:00
"higher_order_functions" {"__" [4 8 12
'(* x x)
[false false true false false]
()
true
'(< x 31)
'(* 10 x) '(< x 4)
24
100
'(count a) '(count b)]}
2011-02-14 01:53:25 +00:00
"runtime_polymorphism" {"__" ['(str (:name a) " eats veggies.")
'(str (:name a) " eats animals.")
'(str "I don't know what " (:name a) " eats.")
"Hello World!"
"Hello, you silly world."
"Hello to this group: Peter, Paul, Mary!" ]}
2011-02-14 01:53:25 +00:00
2011-03-31 13:11:27 +00:00
"lazy_sequences" {"__" [[1 2 3 4]
[0 1 2 3 4]
10
95
'(range 20)
:a]
"___" ['(fn [x] :foo)]}
"sequence_comprehensions" {"__" [[0 1 2 3 4 5]
'(* index index)
'(range 10)
'(odd? index) '(* index index)
'[row column]
]}
2011-02-14 01:53:25 +00:00
2010-11-17 04:23:33 +00:00
"creating_functions" {"__" [true false true
4
:a :b :c :d
2010-11-17 04:23:33 +00:00
:c :d
4
8]
"___" ['(complement nil?)
'multiply-by-5
2010-11-17 04:23:33 +00:00
'(comp dec square)]}
2011-02-14 01:53:25 +00:00
"recursion" {"__" [true
'acc
'(loop [coll coll
acc ()]
(if (seq coll)
(recur (rest coll) (conj acc (first coll)))
acc))
'(loop [n n
acc 1]
2010-11-03 03:55:34 +00:00
(if (zero? n)
acc
(recur (dec n) (* acc n))))]
"___" ['not]}
2011-02-14 01:53:25 +00:00
"destructuring" {"__" [":bar:foo"
'(format (str "First comes %s, "
"then comes %s, "
"then comes %s with the baby carriage")
a b c)
'(apply str
2011-02-14 01:53:25 +00:00
(interpose " "
(apply list
first-name
last-name
(interleave (repeat "aka") aliases))))
'{:original-parts full-name
2010-11-12 00:16:55 +00:00
:named-parts {:first first-name :last last-name}}
'(str street-address ", " city ", " state)
'city 'state
'(str street-address ", " city ", " state)]
"___" ['(fn [[fname lname]
{:keys [street-address city state]}]
(str fname " " lname ", "
street-address ", " city ", " state))
]}
"refs" {"__" ["hello"
"hello"
"better"
"better!!!"
'(dosync (ref-set the-world 0))
'(map :jerry [@the-world @bizarro-world])
2010-11-10 02:19:10 +00:00
]
"___" ['(fn [x] (+ 20 x))]}
2011-03-31 12:44:54 +00:00
"atoms" {"__" [0
1
'(swap! atomic-clock (partial + 4))
20
20
'atomic-clock 20 :fin
]}
2011-02-14 01:53:25 +00:00
"macros" {"__" ['~(first form)
'~(nth form 2)
'form
'(drop 2 form)
"Hello, Macros!"
10
''(+ 9 1)
''(* 10 2)
''(+ 10 (2 * 3))]}
"datatypes" {"__" ['(print
(str "You're really the "
(.category this)
", " recipient "... sorry."))
"peace"
"literature"
"physics"
nil
[true false]
(str "Congratulations on your Best Picture Oscar, "
"Evil Alien Conquerors!")]}})
(defn replace-with [s k replacements]
(let [unreplaced-texts (split s (re-pattern (str "\\b" k "\\b")))]
(join
(butlast
(interleave
unreplaced-texts
(concat (map pr-str replacements) (repeat k)))))))
(defn koan-text [koan]
(slurp (str "src/koans/" koan ".clj")))
(defn answers-for [koan sym]
((answers koan {}) sym []))
(defn fill-in-answers [text koan sym]
(replace-with text sym (answers-for koan sym)))
(defn print-non-failing-error [koan]
(println (str "\n" koan ".clj is passing without filling in the blanks")))
(defn ensure-failing-without-answers []
(binding [clojure.test/*test-out*
(java.io.PrintWriter. (java.io.ByteArrayOutputStream.))]
(if (every?
(fn [koan]
(let [form (koan-text koan)
result (load-string form)]
(if result
(print-non-failing-error koan)
:pass)))
ordered-koans)
(println "\nTests all fail before the answers are filled in."))))
(defn ensure-passing-with-answers []
(try
(dorun (map
(fn [koan]
(load-string
(-> (koan-text koan)
(fill-in-answers koan "__")
(fill-in-answers koan "___"))))
ordered-koans))
(println "\nAll tests pass after the answers are filled in.")
(catch Exception e
(println "\nAnswer sheet fail: " e)
(.printStackTrace e)
(println "Answer sheet fail"))))
(defn run []
(ensure-failing-without-answers)
(ensure-passing-with-answers))