Permalink
Browse files

Merging from the official book repository

  • Loading branch information...
abedra committed Apr 5, 2012
1 parent 05f6545 commit e10099afa98f342647ab6ec89e826b360272c8c7
Showing with 65,970 additions and 7,701 deletions.
  1. +0 −1 .gitignore
  2. BIN classes/examples/tasklist.class
  3. BIN classes/examples/tasklist__init.class
  4. +1 −0 clojurebreaker/Procfile
  5. +17 −0 clojurebreaker/README.md
  6. +9 −0 clojurebreaker/project.clj
  7. +57 −0 clojurebreaker/resources/public/css/reset.css
  8. +65,540 −0 clojurebreaker/scoring-table
  9. +25 −0 clojurebreaker/snippets.clj
  10. +70 −0 clojurebreaker/src/clojurebreaker/game.clj
  11. +27 −0 clojurebreaker/src/clojurebreaker/models/game.clj
  12. +11 −0 clojurebreaker/src/clojurebreaker/server.clj
  13. +13 −0 clojurebreaker/src/clojurebreaker/views/common.clj
  14. +43 −0 clojurebreaker/src/clojurebreaker/views/welcome.clj
  15. +43 −0 clojurebreaker/test/clojurebreaker/game_test.clj
  16. +0 −5 data/.svn/all-wcprops
  17. +0 −34 data/.svn/entries
  18. +0 −11 data/sequences/.svn/all-wcprops
  19. +0 −62 data/sequences/.svn/entries
  20. +0 −12 data/sequences/.svn/text-base/compositions.xml.svn-base
  21. +2 −2 data/sequences/compositions.xml
  22. +0 −47 data/snippets/.svn/all-wcprops
  23. +0 −266 data/snippets/.svn/entries
  24. +0 −25 data/snippets/.svn/text-base/Person.java.svn-base
  25. +0 −15 data/snippets/.svn/text-base/StringUtils.java.svn-base
  26. +0 −7 data/snippets/.svn/text-base/bootstrap-mysql.clj.svn-base
  27. +0 −63 data/snippets/.svn/text-base/example-build.xml.svn-base
  28. +0 −14 data/snippets/.svn/text-base/isBlank.java.svn-base
  29. +0 −39 data/snippets/.svn/text-base/macros.clj.svn-base
  30. +0 −15 data/snippets/.svn/text-base/xml_callback.clj.svn-base
  31. BIN lib/commons-fileupload-1.2.1.jar
  32. BIN lib/commons-io-1.4.jar
  33. BIN lib/jline-0.9.94.jar
  34. +1 −3 project.clj
  35. +0 −5 src/.svn/all-wcprops
  36. +0 −34 src/.svn/entries
  37. +0 −221 src/examples/.svn/all-wcprops
  38. +0 −1,261 src/examples/.svn/entries
  39. +0 −130 src/examples/.svn/text-base/atom_snake.clj.svn-base
  40. +0 −32 src/examples/.svn/text-base/chat.clj.svn-base
  41. +0 −45 src/examples/.svn/text-base/concurrency.clj.svn-base
  42. +0 −72 src/examples/.svn/text-base/cryptovault.clj.svn-base
  43. +0 −56 src/examples/.svn/text-base/cryptovault_complete.clj.svn-base
  44. +0 −53 src/examples/.svn/text-base/error_kit.clj.svn-base
  45. +0 −9 src/examples/.svn/text-base/expectorate.clj.svn-base
  46. +0 −128 src/examples/.svn/text-base/exploring.clj.svn-base
  47. +0 −166 src/examples/.svn/text-base/functional.clj.svn-base
  48. +0 −18 src/examples/.svn/text-base/generator.clj.svn-base
  49. +0 −15 src/examples/.svn/text-base/gulp.clj.svn-base
  50. +0 −18 src/examples/.svn/text-base/index_of_any.clj.svn-base
  51. +0 −116 src/examples/.svn/text-base/interop.clj.svn-base
  52. +0 −42 src/examples/.svn/text-base/introduction.clj.svn-base
  53. +0 −72 src/examples/.svn/text-base/io.clj.svn-base
  54. +0 −14 src/examples/.svn/text-base/lazy_index_of_any.clj.svn-base
  55. +0 −38 src/examples/.svn/text-base/life_without_multi.clj.svn-base
  56. +0 −58 src/examples/.svn/text-base/macros.clj.svn-base
  57. +0 −16 src/examples/.svn/text-base/male_female.clj.svn-base
  58. +0 −22 src/examples/.svn/text-base/male_female_seq.clj.svn-base
  59. +0 −20 src/examples/.svn/text-base/memoized_male_female.clj.svn-base
  60. +0 −34 src/examples/.svn/text-base/midi.clj.svn-base
  61. +0 −58 src/examples/.svn/text-base/multimethods.clj.svn-base
  62. +0 −64 src/examples/.svn/text-base/pi.clj.svn-base
  63. +0 −5 src/examples/.svn/text-base/preface.clj.svn-base
  64. +0 −20 src/examples/.svn/text-base/primes.clj.svn-base
  65. +0 −155 src/examples/.svn/text-base/protocols.clj.svn-base
  66. +0 −27 src/examples/.svn/text-base/replace_symbol.clj.svn-base
  67. +0 −94 src/examples/.svn/text-base/sequences.clj.svn-base
  68. +0 −170 src/examples/.svn/text-base/snake.clj.svn-base
  69. +0 −103 src/examples/.svn/text-base/snippet.clj.svn-base
  70. +0 −37 src/examples/.svn/text-base/tasklist.clj.svn-base
  71. +0 −31 src/examples/.svn/text-base/test.clj.svn-base
  72. +0 −31 src/examples/.svn/text-base/trampoline.clj.svn-base
  73. +0 −64 src/examples/.svn/text-base/utils.clj.svn-base
  74. +0 −26 src/examples/.svn/text-base/wallingford.clj.svn-base
  75. +1 −1 src/examples/atom_snake.clj
  76. +0 −2 src/examples/cryptovault.clj
  77. +0 −4 src/examples/cryptovault_complete.clj
  78. +2 −2 src/examples/exploring.clj
  79. +0 −2 src/examples/generator.clj
  80. +0 −1 src/examples/gulp.clj
  81. +60 −0 src/examples/import_static.clj
  82. +7 −12 src/examples/introduction.clj
  83. +1 −0 src/examples/io.clj
  84. +0 −41 src/examples/macros/.svn/all-wcprops
  85. +0 −232 src/examples/macros/.svn/entries
  86. +0 −11 src/examples/macros/.svn/text-base/bench_1.clj.svn-base
  87. +0 −6 src/examples/macros/.svn/text-base/chain_1.clj.svn-base
  88. +0 −6 src/examples/macros/.svn/text-base/chain_2.clj.svn-base
  89. +0 −5 src/examples/macros/.svn/text-base/chain_3.clj.svn-base
  90. +0 −7 src/examples/macros/.svn/text-base/chain_4.clj.svn-base
  91. +0 −6 src/examples/macros/.svn/text-base/chain_5.clj.svn-base
  92. +0 −1 src/examples/male_female.clj
  93. +1 −2 src/examples/male_female_seq.clj
  94. +0 −3 src/examples/midi.clj
  95. +0 −35 src/examples/multimethods/.svn/all-wcprops
  96. +0 −198 src/examples/multimethods/.svn/entries
  97. +0 −22 src/examples/multimethods/.svn/text-base/account.clj.svn-base
  98. +0 −9 src/examples/multimethods/.svn/text-base/default.clj.svn-base
  99. +0 −15 src/examples/multimethods/.svn/text-base/service_charge_1.clj.svn-base
  100. +0 −13 src/examples/multimethods/.svn/text-base/service_charge_2.clj.svn-base
  101. +0 −20 src/examples/multimethods/.svn/text-base/service_charge_3.clj.svn-base
  102. +4 −4 src/examples/primes.clj
  103. +17 −17 src/examples/protocols.clj
  104. +0 −2 src/examples/replace_symbol.clj
  105. +0 −1 src/examples/sequences.clj
  106. +0 −29 src/examples/server/.svn/all-wcprops
  107. +0 −164 src/examples/server/.svn/entries
  108. +0 −54 src/examples/server/.svn/text-base/complete.clj.svn-base
  109. +0 −17 src/examples/server/.svn/text-base/step_1.clj.svn-base
  110. +0 −45 src/examples/server/.svn/text-base/step_2.clj.svn-base
  111. +0 −57 src/examples/server/.svn/text-base/step_3.clj.svn-base
  112. +1 −1 src/examples/snake.clj
  113. +1 −1 src/examples/trampoline.clj
  114. +0 −5 src/examples/wallingford.clj
  115. +0 −23 src/reader/.svn/all-wcprops
  116. +0 −130 src/reader/.svn/entries
  117. +0 −10 src/reader/.svn/text-base/snake.clj.svn-base
  118. +0 −4 src/reader/.svn/text-base/snippet_server.clj.svn-base
  119. +0 −10 src/reader/.svn/text-base/tasklist.clj.svn-base
  120. +1 −1 src/reader/snake.clj
  121. +0 −5 test/.svn/all-wcprops
  122. +0 −31 test/.svn/entries
  123. +0 −5 test/examples/.svn/all-wcprops
  124. +0 −31 test/examples/.svn/entries
  125. +0 −143 test/examples/test/.svn/all-wcprops
  126. +0 −816 test/examples/test/.svn/entries
  127. +0 −26 test/examples/test/.svn/text-base/chat.clj.svn-base
  128. +0 −26 test/examples/test/.svn/text-base/concurrency.clj.svn-base
  129. +0 −79 test/examples/test/.svn/text-base/exploring.clj.svn-base
  130. +0 −14 test/examples/test/.svn/text-base/fail.clj.svn-base
  131. +0 −35 test/examples/test/.svn/text-base/functional.clj.svn-base
  132. +0 −21 test/examples/test/.svn/text-base/index_of_any.clj.svn-base
  133. +0 −45 test/examples/test/.svn/text-base/interop.clj.svn-base
  134. +0 −34 test/examples/test/.svn/text-base/introduction.clj.svn-base
  135. +0 −11 test/examples/test/.svn/text-base/lazy_index_of_any.clj.svn-base
  136. +0 −23 test/examples/test/.svn/text-base/life_without_multi.clj.svn-base
  137. +0 −38 test/examples/test/.svn/text-base/macros.clj.svn-base
  138. +0 −11 test/examples/test/.svn/text-base/male_female.clj.svn-base
  139. +0 −11 test/examples/test/.svn/text-base/male_female_seq.clj.svn-base
  140. +0 −11 test/examples/test/.svn/text-base/memoized_male_female.clj.svn-base
  141. +0 −25 test/examples/test/.svn/text-base/multimethods.clj.svn-base
  142. +0 −11 test/examples/test/.svn/text-base/preface.clj.svn-base
  143. +0 −14 test/examples/test/.svn/text-base/replace_symbol.clj.svn-base
  144. +0 −47 test/examples/test/.svn/text-base/sequences.clj.svn-base
  145. +0 −46 test/examples/test/.svn/text-base/snake.clj.svn-base
  146. +0 −20 test/examples/test/.svn/text-base/snippet.clj.svn-base
  147. +0 −16 test/examples/test/.svn/text-base/tasklist.clj.svn-base
  148. +0 −16 test/examples/test/.svn/text-base/trampoline.clj.svn-base
  149. +0 −12 test/examples/test/.svn/text-base/wallingford.clj.svn-base
  150. +7 −17 test/examples/test/introduction.clj
  151. +0 −41 test/examples/test/macros/.svn/all-wcprops
  152. +0 −232 test/examples/test/macros/.svn/entries
  153. +0 −11 test/examples/test/macros/.svn/text-base/bench_1.clj.svn-base
  154. +0 −7 test/examples/test/macros/.svn/text-base/chain_1.clj.svn-base
  155. +0 −7 test/examples/test/macros/.svn/text-base/chain_2.clj.svn-base
  156. +0 −7 test/examples/test/macros/.svn/text-base/chain_3.clj.svn-base
  157. +0 −7 test/examples/test/macros/.svn/text-base/chain_4.clj.svn-base
  158. +0 −7 test/examples/test/macros/.svn/text-base/chain_5.clj.svn-base
  159. +0 −35 test/examples/test/multimethods/.svn/all-wcprops
  160. +0 −198 test/examples/test/multimethods/.svn/entries
  161. +0 −18 test/examples/test/multimethods/.svn/text-base/account.clj.svn-base
  162. +0 −10 test/examples/test/multimethods/.svn/text-base/default.clj.svn-base
  163. +0 −13 test/examples/test/multimethods/.svn/text-base/service_charge_1.clj.svn-base
  164. +0 −13 test/examples/test/multimethods/.svn/text-base/service_charge_2.clj.svn-base
  165. +0 −13 test/examples/test/multimethods/.svn/text-base/service_charge_3.clj.svn-base
  166. +1 −1 test/examples/test/sequences.clj
  167. +5 −8 test/examples/test/snake.clj
  168. +2 −1 test/examples/test/wallingford.clj
View
@@ -1,4 +1,3 @@
-
/Programming-Clojure.iml
/build.clj
/hello.out
Binary file not shown.
Binary file not shown.
View
@@ -0,0 +1 @@
+web: lein run
View
@@ -0,0 +1,17 @@
+# clojurebreaker
+
+A website written in noir.
+
+## Usage
+
+```bash
+lein deps
+lein run
+```
+
+## License
+
+Copyright (C) 2011 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
+
@@ -0,0 +1,9 @@
+; START: clojurebreaker-project
+(defproject clojurebreaker "0.1.0-SNAPSHOT"
+ :description "Clojurebreaker game for Programming Clojure 2nd Edition"
+ :dependencies [[org.clojure/clojure "1.3.0"]
+ [org.clojure/math.combinatorics "0.0.1"]
+ [org.clojure/test.generative "0.1.3"]
+ [noir "1.2.0"]]
+ :main clojurebreaker.server)
+; END: clojurebreaker-project
@@ -0,0 +1,57 @@
+html {
+ margin:0;
+ padding:0;
+ border:0;
+}
+
+body, div, span, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, code,
+del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, dialog, figure, footer, header,
+hgroup, nav, section {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-weight: inherit;
+ font-style: inherit;
+ font-size: 100%;
+ font-family: inherit;
+ vertical-align: baseline;
+}
+
+article, aside, dialog, figure, footer, header,
+hgroup, nav, section {
+ display:block;
+}
+
+body {
+ line-height: 1.5;
+ background: white;
+}
+
+table {
+ border-collapse: separate;
+ border-spacing: 0;
+}
+
+caption, th, td {
+ text-align: left;
+ font-weight: normal;
+ float:none !important;
+}
+table, th, td {
+ vertical-align: middle;
+}
+
+blockquote:before, blockquote:after, q:before, q:after { content: ''; }
+blockquote, q { quotes: "" ""; }
+
+a img { border: none; }
+
+/*:focus { outline: 0; }*/
+
+
+
View

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,25 @@
+;; this file contains the intermediate steps in building the
+;; Clojurebreaker game. See the clojurebreaker/src directory for the
+;; completed code.
+
+; START:exact-matches-shell
+(defn exact-matches
+ "Given two collections, return the number of positions where
+ the collections contain equal items."
+ [c1 c2])
+; END:exact-matches-shell
+
+; START:integers-closed
+(defspec closed-under-addition
+ +'
+ [^long a ^long b]
+ (assert (integer? %)))
+; END:integers-closed
+
+; START:incorrect-spec
+(defspec incorrect-spec
+ +'
+ [^long a ^long b]
+ (assert (< a %))
+ (assert (< b %)))
+; END:incorrect-spec
@@ -0,0 +1,70 @@
+(ns clojurebreaker.game
+ (:use clojure.pprint)
+ (:require [clojure.data :as data]
+ [clojure.math.combinatorics :as comb]
+ [clojure.java.io :as io]))
+
+;; START:exact-matches
+(defn exact-matches
+ "Given two collections, return the number of positions where
+ the collections contain equal items."
+ [c1 c2]
+ (let [[_ _ matches] (data/diff c1 c2)]
+ (count (remove nil? matches))))
+;; END:exact-matches
+
+;; START:unordered-matches
+(defn unordered-matches
+ "Given two collections, return a map where each key is an item
+ in both collections, and each value is the number of times the
+ value occurs in the collection with fewest occurrences."
+ [c1 c2]
+ (let [f1 (select-keys (frequencies c1) c2)
+ f2 (select-keys (frequencies c2) c1)]
+ (merge-with min f1 f2)))
+;; END:unordered-matches
+
+;; START:score
+(defn score
+ [c1 c2]
+ (let [exact (exact-matches c1 c2)
+ unordered (apply + (vals (unordered-matches c1 c2)))]
+ {:exact exact :unordered (- unordered exact)}))
+;; END: score
+
+;; START: generate-turn-inputs
+(defn generate-turn-inputs
+ "Generate all possible turn inputs for a clojurebreaker game
+ with colors and n columns"
+ [colors n]
+ (-> (comb/selections colors n)
+ (comb/selections 2)))
+;; END: generate-turn-inputs
+
+;; START: score-inputs
+(defn score-inputs
+ "Given a sequence of turn inputs, return a lazy sequence of
+ maps with :secret, :guess, and :score."
+ [inputs]
+ (map
+ (fn [[secret guess]]
+ {:secret (seq secret)
+ :guess (seq guess)
+ :score (score secret guess)})
+ inputs))
+;; END: score-inputs
+
+(->> (generate-turn-inputs [:r :g :b] 2)
+ (score-inputs))
+
+;; step 17 score-table
+#_(score-all-games [:R :G :B] 3)
+
+;; step 18 could check either the clj or the tabular form of score-all-games
+;; into source control and use it as a regression test
+;; (add clojure.java.io)
+(use 'clojure.pprint)
+(with-open [w (io/writer "scoring-table")]
+ (binding [*out* w]
+ (print-table (->> (generate-turn-inputs [:r :g :b :y] 4)
+ (score-inputs)))))
@@ -0,0 +1,27 @@
+(ns clojurebreaker.models.game
+ (:require [clojure.data :as data]))
+
+(defn create []
+ (vec (repeatedly 4 (fn [] (rand-nth ["r" "g" "b" "y"])))))
+
+(defn exact-matches
+ "Given two collections, return the number of positions where
+ the collections contain equal items."
+ [c1 c2]
+ (let [[_ _ matches] (data/diff c1 c2)]
+ (count (remove nil? matches))))
+
+(defn unordered-matches
+ "Given two collections, return a map where each key is an item
+ in both collections, and each value is the number of times the
+ value occurs in the collection with fewest occurrences."
+ [c1 c2]
+ (let [f1 (select-keys (frequencies c1) c2)
+ f2 (select-keys (frequencies c2) c1)]
+ (merge-with min f1 f2)))
+
+(defn score
+ [c1 c2]
+ (let [exact (exact-matches c1 c2)
+ unordered (apply + (vals (unordered-matches c1 c2)))]
+ {:exact exact :unordered (- unordered exact)}))
@@ -0,0 +1,11 @@
+(ns clojurebreaker.server
+ (:require [noir.server :as server]))
+
+(server/load-views "src/clojurebreaker/views/")
+
+(defn -main [& m]
+ (let [mode (keyword (or (first m) :dev))
+ port (Integer. (get (System/getenv) "PORT" "8080"))]
+ (server/start port {:mode mode
+ :ns 'clojurebreaker})))
+
@@ -0,0 +1,13 @@
+(ns clojurebreaker.views.common
+ (:use noir.core
+ hiccup.core
+ hiccup.page-helpers))
+
+(defpartial layout [& content]
+ (html5
+ [:head
+ [:title "Clojurebreaker"]
+ (include-css "/css/reset.css")]
+ [:body
+ [:div#wrapper
+ content]]))
@@ -0,0 +1,43 @@
+(ns clojurebreaker.views.welcome
+ (:require [noir.session :as session]
+ [clojurebreaker.views.common :as common]
+ [clojurebreaker.models.game :as game])
+ (:use [noir.core :only (defpartial defpage render)]
+ [hiccup.form-helpers :only (form-to text-field submit-button)]))
+
+; START: clojurebreaker-partial
+(defpartial board [{:keys [one two three four exact unordered]}]
+ (when (and exact unordered)
+ [:div "Exact: " exact " Unordered: " unordered])
+ (form-to [:post "/guess"]
+ (text-field "one" one)
+ (text-field "two" two)
+ (text-field "three" three)
+ (text-field "four" four)
+ (submit-button "Guess")))
+; END: clojurebreaker-partial
+
+; START: clojurebreaker-page
+(defpage "/" {:as guesses}
+ (when-not (session/get :game)
+ (session/put! :game (game/create)))
+ (common/layout (board (or guesses nil))))
+; END: clojurebreaker-page
+
+; START: clojurebreaker-post
+(defpage [:post "/guess"] {:keys [one two three four]}
+ (let [result (game/score (session/get :game) [one two three four])]
+ (if (= (:exact result) 4)
+ (do (session/remove! :game)
+ (common/layout
+ [:h2 "Congratulations, you have solved the puzzle!"]
+ (form-to [:get "/"]
+ (submit-button "Start A New Game"))))
+ (do (session/flash-put! result)
+ (render "/" {:one one
+ :two two
+ :three three
+ :four four
+ :exact (:exact result)
+ :unordered (:unordered result)})))))
+; END: clojurebreaker-post
@@ -0,0 +1,43 @@
+;; START:invariants
+(ns clojurebreaker.game-test
+ (:use [clojure.test.generative :only (defspec) :as test])
+ (:require [clojure.test.generative.generators :as gen]
+ [clojurebreaker.game :as game]
+ [clojure.math.combinatorics :as comb]))
+
+(defn matches
+ "Given a score, returns total number of exact plus
+ unordered matches."
+ [score]
+ (+ (:exact score) (:unordered score)))
+
+(defn scoring-is-symmetric
+ [secret guess score]
+ (= score (game/score guess secret)))
+
+(defn scoring-is-bounded-by-number-of-pegs
+ [secret guess score]
+ (< 0 (matches score) (count secret)))
+(defn reordering-the-guess-does-not-change-matches
+ [secret guess score]
+ (= #{(matches score)}
+ (into #{} (map
+ #(matches (game/score secret %))
+ (comb/permutations guess)))))
+;; END:invariants
+
+;; START:random-secret
+(defn random-secret
+ []
+ (gen/vec #(gen/one-of :r :g :b :y) 4))
+;; END:random-secret
+
+;; START:score-invariants
+(defspec score-invariants
+ game/score
+ [^{:tag `random-secret} secret
+ ^{:tag `random-secret} guess]
+ (assert (scoring-is-symmetric secret guess %))
+ (assert (scoring-is-bounded-by-number-of-pegs secret guess %))
+ (assert (reordering-the-guess-does-not-change-matches secret guess %)))
+;; END:score-invariants
View
@@ -1,5 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 55
-/Bookshelf/!svn/ver/93881/titles/shcloj2/Book/code/data
-END
View
@@ -1,34 +0,0 @@
-10
-
-dir
-104723
-https://svn.pragprog.com/Bookshelf/titles/shcloj2/Book/code/data
-https://svn.pragprog.com/Bookshelf
-
-
-
-2011-04-08T17:38:06.087802Z
-93881
-aaron.bedra
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-82263e25-b5eb-0310-b4ec-9460fbaf34b7
-
-snippets
-dir
-
-sequences
-dir
-
@@ -1,11 +0,0 @@
-K 25
-svn:wc:ra_dav:version-url
-V 65
-/Bookshelf/!svn/ver/93730/titles/shcloj2/Book/code/data/sequences
-END
-compositions.xml
-K 25
-svn:wc:ra_dav:version-url
-V 82
-/Bookshelf/!svn/ver/93730/titles/shcloj2/Book/code/data/sequences/compositions.xml
-END
Oops, something went wrong.

0 comments on commit e10099a

Please sign in to comment.