├── .gitignore ├── 1_artillery ├── README.md ├── project.clj └── src │ └── artillery │ ├── core.clj │ └── work.clj ├── 2_snake ├── README.md ├── project.clj └── src │ └── snake │ ├── core.clj │ └── work.clj ├── 3_durak ├── README.md ├── project.clj ├── resources │ ├── b1fh.png │ ├── b1pb.png │ ├── b1pl.png │ ├── b1pr.png │ ├── b1pt.png │ ├── b2fh.png │ ├── b2pb.png │ ├── b2pl.png │ ├── b2pr.png │ ├── b2pt.png │ ├── blue_back.png │ ├── clubs_10.png │ ├── clubs_11.png │ ├── clubs_12.png │ ├── clubs_13.png │ ├── clubs_14.png │ ├── clubs_2.png │ ├── clubs_3.png │ ├── clubs_4.png │ ├── clubs_5.png │ ├── clubs_6.png │ ├── clubs_7.png │ ├── clubs_8.png │ ├── clubs_9.png │ ├── diamonds_10.png │ ├── diamonds_11.png │ ├── diamonds_12.png │ ├── diamonds_13.png │ ├── diamonds_14.png │ ├── diamonds_2.png │ ├── diamonds_3.png │ ├── diamonds_4.png │ ├── diamonds_5.png │ ├── diamonds_6.png │ ├── diamonds_7.png │ ├── diamonds_8.png │ ├── diamonds_9.png │ ├── hearts_10.png │ ├── hearts_11.png │ ├── hearts_12.png │ ├── hearts_13.png │ ├── hearts_14.png │ ├── hearts_2.png │ ├── hearts_3.png │ ├── hearts_4.png │ ├── hearts_5.png │ ├── hearts_6.png │ ├── hearts_7.png │ ├── hearts_8.png │ ├── hearts_9.png │ ├── joker_black.png │ ├── joker_red.png │ ├── red_back.png │ ├── spades_10.png │ ├── spades_11.png │ ├── spades_12.png │ ├── spades_13.png │ ├── spades_14.png │ ├── spades_2.png │ ├── spades_3.png │ ├── spades_4.png │ ├── spades_5.png │ ├── spades_6.png │ ├── spades_7.png │ ├── spades_8.png │ └── spades_9.png └── src │ └── durak │ ├── core.clj │ ├── logic.clj │ └── work.clj ├── 4_cellular_automaton ├── README.md ├── project.clj └── src │ └── cellular_automaton │ └── work.clj ├── 5_k_means ├── README.md ├── project.clj └── src │ └── k_means │ ├── core.clj │ └── work.clj ├── 6_derivative ├── .gitignore ├── README.md ├── project.clj └── src │ └── derivative │ └── core.clj ├── 7_church_encoding ├── .gitignore ├── README.md ├── project.clj └── src │ └── church_encoding │ ├── core.clj │ └── work.clj ├── README.md └── misc ├── fourclj-grabber ├── .gitignore ├── README.md ├── project.clj └── src │ └── fourclj_grabber │ └── core.clj ├── images ├── 1_artillery_plane.png ├── 1_artillery_ufo.png ├── 2_snake.png ├── 2_snake_small.png ├── 3_durak.png ├── 3_durak_small.png ├── 4_cellular_automaton_ant.png ├── 4_cellular_automaton_life.png ├── 4_cellular_automaton_wireworld.png ├── 4_cellular_automaton_wireworld_small.png ├── 5_k_means.png ├── 6_derivative.png └── 6_derivative_small.png └── qtut ├── .gitignore ├── README.md ├── project.clj └── src └── leiningen └── new ├── qtut.clj └── qtut ├── core.clj ├── project.clj └── work.clj /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | lib 3 | classes 4 | checkouts 5 | pom.xml 6 | *.jar 7 | *.class 8 | .lein-deps-sum 9 | .lein-failures 10 | .lein-plugins 11 | solution.clj 12 | .lein-repl-history -------------------------------------------------------------------------------- /1_artillery/README.md: -------------------------------------------------------------------------------- 1 | Calculate fire angle and hit target. 2 | 3 | [Detailed description and work file.](https://github.com/nbeloglazov/clojure-interactive-tasks/blob/master/1_artillery/src/artillery/work.clj) 4 | 5 | Screenshots: 6 | 7 | ![Artillery plane](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/1_artillery_plane.png) 8 | 9 | ![Artillery ufo](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/1_artillery_ufo.png) 10 | -------------------------------------------------------------------------------- /1_artillery/project.clj: -------------------------------------------------------------------------------- 1 | (defproject artillery "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.5.1"] 3 | [quil/quil "1.7.0"]]) 4 | -------------------------------------------------------------------------------- /1_artillery/src/artillery/core.clj: -------------------------------------------------------------------------------- 1 | (ns artillery.core 2 | (:require [quil.core :refer :all])) 3 | 4 | (def w 800) 5 | (def h 600) 6 | (def falling-speed [0 -10]) 7 | (def missile-speed 10) 8 | (def dead-dist 20) 9 | (def target-size 10) 10 | 11 | (def initial-missile {:pos nil 12 | :speed nil}) 13 | 14 | (defn inside-border? [x y] 15 | (and (<= 0 x (width)) 16 | (<= 0 y (height)))) 17 | 18 | (defn rand-range [from to] 19 | (+ from (rand-int (- to from)))) 20 | 21 | (defn advance [object speed] 22 | (swap! object update-in [:pos] #(map + % speed))) 23 | 24 | (defn advance-speed [object accel] 25 | (swap! object update-in [:speed] #(map + % accel))) 26 | 27 | (defn missile-speed-from-angle [angle] 28 | (if (nil? angle) 29 | [0 -100] 30 | [(* (cos angle) missile-speed) 31 | (* (sin angle) missile-speed)])) 32 | 33 | (defn hit? [m-x m-y t-x t-y] 34 | (< (dist m-x m-y t-x t-y) dead-dist)) 35 | 36 | (defn angle [[x y]] 37 | (atan2 y x)) 38 | 39 | (defn launch-missile [{[p-x p-y] :pos type :type} {[t-x t-y] :pos} solution] 40 | (missile-speed-from-angle 41 | (if (= :static type) 42 | (solution) 43 | (solution p-x p-y t-x t-y)))) 44 | 45 | (defmacro fn-state [vars & body] 46 | `(fn [] (let ~(vec (apply concat 47 | (for [var vars] 48 | [var `(state ~(keyword var))]))) 49 | ~@body))) 50 | 51 | (defn update-target [target target-gen] 52 | (let [{:keys [status pos speed]} @target 53 | [x y] pos] 54 | (cond (or (nil? @target) 55 | (not (inside-border? x y))) 56 | (reset! target (target-gen)) 57 | (= status :live) 58 | (advance target speed) 59 | :else 60 | (advance target falling-speed)))) 61 | 62 | (defn update-missile [target missile player solution] 63 | (let [[m-x m-y] (:pos @missile) 64 | [t-x t-y] (:pos @target)] 65 | (cond 66 | (not (:fired @target)) 67 | (do (reset! missile {:pos (:pos @player) 68 | :speed (launch-missile @player @target solution)}) 69 | (swap! target assoc :fired true)) 70 | (and (not (nil? m-x)) 71 | (hit? m-x m-y t-x t-y)) 72 | (do (reset! missile initial-missile) 73 | (swap! target assoc :status :dead)) 74 | (not (or (nil? m-x) (inside-border? m-x m-y))) 75 | (do (reset! missile initial-missile) 76 | (swap! target assoc :fired false)) 77 | (not (nil? m-x)) 78 | (do (advance missile (:speed @missile)) 79 | (advance-speed missile (:missile-accel @player)))))) 80 | 81 | (defn update-player [player] 82 | (when-not (apply inside-border? (:pos @player)) 83 | (swap! player update-in [:speed 0] #(* % -1))) 84 | (advance player (:speed @player))) 85 | 86 | (defn update-fn [solution] 87 | (fn-state [target missile target-gen player] 88 | (update-target target target-gen) 89 | (update-player player) 90 | (update-missile target missile player solution))) 91 | 92 | (defn prepare-matrix [status pos speed] 93 | (translate pos) 94 | (->> (if (= status :live) 95 | speed 96 | falling-speed) 97 | angle 98 | rotate)) 99 | 100 | (defn draw-plane [{:keys [status pos speed]}] 101 | (push-matrix) 102 | (prepare-matrix status pos speed ) 103 | (stroke-weight 3) 104 | (line -20 0 20 0) 105 | (line -25 5 -20 0) 106 | (line -10 -5 5 0) 107 | (line -10 5 5 0) 108 | (pop-matrix)) 109 | 110 | (defn draw-ufo [{:keys [status pos speed]}] 111 | (push-matrix) 112 | (prepare-matrix status pos speed) 113 | (scale 0.7) 114 | (stroke-weight 3) 115 | (let [points [[0 0] [-20 0] [-20 10] [-10 20] [10 20] [20 10] [20 0] [0 0] [20 -15] [10 0] [0 0] [-20 -15] [-10 -0]]] 116 | (doseq [pair (partition 2 1 points)] 117 | (apply line (flatten pair)))) 118 | (point 8 10) 119 | (point -8 10) 120 | (pop-matrix)) 121 | 122 | (defn draw-missile [{:keys [pos speed]}] 123 | (when-not (nil? pos) 124 | (stroke-weight 2) 125 | (push-matrix) 126 | (translate pos) 127 | (rotate (angle speed)) 128 | (line -10 0 10 0) 129 | (line -10 -2 -10 2) 130 | (line 2 2 10 0) 131 | (line 2 -2 10 0) 132 | (pop-matrix))) 133 | 134 | (defn draw-player [{:keys [pos]}] 135 | (push-matrix) 136 | (translate pos) 137 | (stroke-weight 2) 138 | (line -8 0 8 0) 139 | (line -8 5 -8 0) 140 | (line 8 5 8 0) 141 | (line 0 15 0 0) 142 | (line -2 8 0 15) 143 | (line 2 8 0 15) 144 | (pop-matrix)) 145 | 146 | (def draw 147 | (fn-state [target missile player] 148 | (push-matrix) 149 | (apply-matrix 1 0 0 0 -1 0) 150 | (translate 0 (- h)) 151 | (background 200) 152 | (fill 0) 153 | ((:draw @target) @target) 154 | (draw-missile @missile) 155 | (draw-player @player) 156 | (pop-matrix))) 157 | 158 | (defn setup [target-gen player] 159 | (smooth) 160 | (frame-rate 10) 161 | (->> {:target (atom nil) 162 | :missile (atom initial-missile) 163 | :target-gen target-gen 164 | :player (atom player)} 165 | seq 166 | flatten 167 | (apply set-state!))) 168 | 169 | (defn run [target-gen player solution] 170 | (let [update (update-fn solution) 171 | update #(dotimes [_ 3] (update))] 172 | (sketch 173 | :title "Air defense" 174 | :setup (partial setup target-gen player) 175 | :draw #(do (update) (draw)) 176 | :size [800 600]))) 177 | 178 | (def plane-static 179 | (partial run 180 | (fn [] {:pos [0 500] 181 | :speed [5 0] 182 | :status :live 183 | :draw draw-plane}) 184 | {:pos [(/ w 2) 0] 185 | :speed [0 0] 186 | :missile-accel [0 0] 187 | :type :static})) 188 | 189 | (def plane-dynamic 190 | (partial run 191 | (fn [] {:pos [0 (- h 10 (rand-int 400))] 192 | :speed [5 0] 193 | :status :live 194 | :draw draw-plane}) 195 | {:pos [(/ w 2) 0] 196 | :speed [2.5 0] 197 | :missile-accel [0 0] 198 | :type :dynamic})) 199 | 200 | (def ufo-static 201 | (partial run 202 | (fn [] {:pos [500 300] 203 | :speed [0 0] 204 | :status :live 205 | :draw draw-ufo}) 206 | {:pos [0 0] 207 | :speed [0 0] 208 | :missile-accel [0 -0.1] 209 | :type :static})) 210 | 211 | (def ufo-dynamic 212 | (partial run 213 | (fn [] {:pos [(+ 10 (rand-int (- w 20))) (rand-range 100 500)] 214 | :speed [0 0] 215 | :status :live 216 | :draw draw-ufo}) 217 | {:pos [(/ w 2) 0] 218 | :speed [2.5 0] 219 | :missile-accel [0 -0.1] 220 | :type :dynamic})) 221 | 222 | -------------------------------------------------------------------------------- /1_artillery/src/artillery/work.clj: -------------------------------------------------------------------------------- 1 | (ns artillery.work 2 | (:require [artillery.core :refer (plane-static plane-dynamic ufo-static ufo-dynamic)])) 3 | 4 | 5 | ;;; You goal is to hit plane my missile. 6 | ;;; Plane always starts at position x = 0, y = 500. 7 | ;;; Plane speed is equal to 5. 8 | ;;; Plane flies from the left to the right. So it's positions will be (0, 500), (5, 500), (10, 500), etc... 9 | ;;; You position is x = 400, y = 0. 10 | ;;; Missile speed is 10. 11 | ;;; Your goal is to calculate what angle you need to launch missile at in order to hit the plane. 12 | ;;; Your solution is a function that takes no parameters (constant function) and returns this angle. 13 | 14 | ;;; Here is an example of such function. 15 | ;;; It always returns PI/2 (missile is launched straight up). 16 | ;;; You can either calculate answer or find it by trying and adjusting different angles. 17 | (defn plane-static-solution [] 18 | (* 0.5 Math/PI)) 19 | 20 | ;;; Here's a function that will show an animation with plane flying and you launching missiles. 21 | ;;; You need to pass your solution (function name) to this function. 22 | (plane-static plane-static-solution) 23 | 24 | 25 | 26 | ;;; Your goal is the same but now plane starts at random position. 27 | ;;; And you're also moving!. 28 | ;;; So only plane's speed and missiles' speed are constant now. 29 | ;;; You need to write a function that takes 4 numbers - your coordinates (player) and plane coordinates (target). 30 | ;;; Function should calculate angle to launch missile at. 31 | 32 | ;;; Example 33 | ;;; pl-x, pl-y - player's (your) coordinates. 34 | ;;; trg-x trg-y - target coordinates. 35 | ;;; Run and see how it launches missile now and then fix it to hit the plane. 36 | (defn plane-dynamic-solution [pl-x pl-y trg-x trg-y] 37 | (Math/atan2 (- trg-y pl-y) (- trg-x pl-x))) 38 | 39 | ;;; To run program uncomment function and run it. 40 | ; (plane-dynamic plane-dynamic-solution) 41 | 42 | 43 | 44 | ;;; Now you need to hit UFO. 45 | ;;; You're lucky - it's not moving, just hanging in the air. 46 | ;;; But now gravity force is enabled so your missile won't fly in a straight way but rather in a curve. Remember Worms game? :) 47 | ;;; Gravity force decreases missile y speed by 0.1 every turn. 48 | ;;; UFO position x = 500, y = 300 (constants). 49 | ;;; UFO speed is equal to 0 (it's not moving). 50 | ;;; Your position x = 0, y = 0 (constants). 51 | ;;; Initial missile speed is 10. 52 | ;;; You need to write function that takes no arguments and returns angle. 53 | 54 | ;;; Now you don't have template function, so write one yourself. 55 | ;;; Hint: try to pass random angle at first e.g. 0.5 and see how it works. 56 | ;;; To check your solution use ufo-static function: 57 | ; (ufo-static YOUR_SOLUTION) 58 | 59 | 60 | 61 | ;;; Same UFO, but now it appears at random position (same as plane-dynamic). 62 | ;;; And you're moving now. 63 | ;;; Write a function that takes 4 arguments: your position (x, y) and UFO's position (x, y) and returns an angle. 64 | ;;; To check your solution use ufo-dynamic function: 65 | ; (ufo-dynamic YOUR_SOLUTION) 66 | 67 | 68 | 69 | ;;; If you're still full of energy - add wind to simulation. 70 | ;;; Open core.clj file and try to figure out (it's not very easy) where missile speed is changed and try to add wind. 71 | ;;; And solve tasks with new obstacles. 72 | -------------------------------------------------------------------------------- /2_snake/README.md: -------------------------------------------------------------------------------- 1 | Write a bot for playing [snake](http://en.wikipedia.org/wiki/Snake_%28video_game%29) game. 2 | 3 | [Detailed description and work file](https://github.com/nbeloglazov/clojure-interactive-tasks/blob/master/2_snake/src/snake/work.clj) 4 | 5 | Screenshots: 6 | 7 | ![Snake](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/2_snake.png) 8 | -------------------------------------------------------------------------------- /2_snake/project.clj: -------------------------------------------------------------------------------- 1 | (defproject snake "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.5.1"] 3 | [quil/quil "1.7.0"]]) 4 | -------------------------------------------------------------------------------- /2_snake/src/snake/core.clj: -------------------------------------------------------------------------------- 1 | (ns snake.core 2 | (:use quil.core)) 3 | 4 | (def w 800) 5 | (def h 600) 6 | (def cell-size 20) 7 | (def board-width (/ w cell-size)) 8 | (def board-height (/ h cell-size)) 9 | (def dirs {:right [1 0] 10 | :left [-1 0] 11 | :up [0 -1] 12 | :down [0 1]}) 13 | 14 | (defn to-real-coords [cell] 15 | (map #(* cell-size %) cell)) 16 | 17 | (defn draw-cell [draw-fn cell] 18 | (let [[real-x real-y] (to-real-coords cell)] 19 | (draw-fn real-x real-y cell-size cell-size))) 20 | 21 | (defn neib-cell [cell dir] 22 | (let [[new-x new-y] (map + cell (dirs dir))] 23 | [(mod (+ new-x board-width) board-width) 24 | (mod (+ new-y board-height) board-height)])) 25 | 26 | (defn rand-free-cell [{:keys [body]} apples walls] 27 | (let [body (set body)] 28 | (->> #(vector (rand-int board-width) (rand-int board-height)) 29 | repeatedly 30 | (remove #(or (apples %) 31 | (body %) 32 | (walls %))) 33 | first))) 34 | 35 | (defn dead? [head body walls] 36 | (boolean 37 | (or (walls head) 38 | (some #(= head %) body)))) 39 | 40 | (defmacro fn-state [vars & body] 41 | `(fn [] (let ~(vec (apply concat 42 | (for [var vars] 43 | [var `(state ~(keyword var))]))) 44 | ~@body))) 45 | 46 | 47 | (defn add-apple [snake apples walls] 48 | (let [new-apple (rand-free-cell @snake @apples @walls)] 49 | (swap! apples conj new-apple))) 50 | 51 | (defn update-apples [snake apples walls] 52 | (dotimes [_ (- (:num (meta @apples)) 53 | (count @apples))] 54 | (add-apple snake apples walls))) 55 | 56 | (defn update-snake [snake dir apples walls] 57 | (let [{:keys [body grow?]} @snake 58 | new-head (neib-cell (first body) dir) 59 | ate? (@apples new-head) 60 | new-body (if-not (dead? new-head body @walls) 61 | (cons new-head 62 | ((if (and ate? grow?) identity butlast) body)) 63 | [(rand-free-cell {:body []} @apples @walls)])] 64 | (swap! apples disj new-head) 65 | (swap! snake assoc :body new-body))) 66 | 67 | (defn update-fn [solution] 68 | (fn-state [snake apples walls] 69 | (let [new-dir (solution (:body @snake) 70 | @apples 71 | @walls)] 72 | (update-snake snake new-dir apples walls)) 73 | (update-apples snake apples walls))) 74 | 75 | (defn draw-snake [{:keys [body]}] 76 | (fill 0 255 0) 77 | (doseq [cell body] 78 | (draw-cell rect cell))) 79 | 80 | (defn draw-apples [apples] 81 | (fill 255 0 0) 82 | (doseq [apple apples] 83 | (draw-cell ellipse apple))) 84 | 85 | (defn draw-walls [walls] 86 | (fill 139 69 19) 87 | (doseq [wall walls] 88 | (draw-cell rect wall))) 89 | 90 | (def draw 91 | (fn-state [snake apples walls] 92 | (background 200) 93 | (ellipse-mode :corner) 94 | (draw-snake @snake) 95 | (draw-apples @apples) 96 | (draw-walls @walls))) 97 | 98 | (defn setup-fn [num-of-apples walls grow?] 99 | (fn [] 100 | (smooth) 101 | (set-state! 102 | :snake (atom {:body [[0 0]] 103 | :grow? grow?}) 104 | :walls (atom walls) 105 | :apples (atom (with-meta #{} {:num num-of-apples}))) 106 | (->> [:snake :apples :walls] (map state) (apply update-apples)) 107 | (frame-rate 10))) 108 | 109 | (defn run [num-of-apples walls grow? solution] 110 | (let [update (update-fn solution)] 111 | (sketch 112 | :title "snake" 113 | :setup (setup-fn num-of-apples walls grow?) 114 | :draw #(do (update) (draw)) 115 | :size [w h]))) 116 | 117 | (defn add-adjacent-wall [walls] 118 | (let [dir (rand-nth [:up :down :left :right]) 119 | cell (rand-nth (seq walls))] 120 | (conj walls (neib-cell cell dir)))) 121 | 122 | (defn generate-walls-blot [size] 123 | (->> [board-width board-height] 124 | (map rand-int) 125 | vec 126 | hash-set 127 | (iterate add-adjacent-wall) 128 | (remove #(< (count %) size)) 129 | first)) 130 | 131 | 132 | (defn make-move [snake-pos apple-pos] 133 | (cond (< (first snake-pos) (first apple-pos)) :right 134 | (> (first snake-pos) (first apple-pos)) :left 135 | (< (second snake-pos) (second apple-pos)) :down 136 | :else :up)) 137 | 138 | (defn run-not-grow [solution] 139 | (run 1 #{} false 140 | (fn [[head & _] apples _] 141 | (solution head (first apples))))) 142 | 143 | (defn run-grow [solution] 144 | (run 1 #{} true 145 | (fn [snake apples _] 146 | (solution snake (first apples))))) 147 | 148 | (defn run-many-apples [solution] 149 | (run 5 #{} true 150 | (fn [snake apples _] 151 | (solution snake apples)))) 152 | 153 | (defn run-with-walls [solution] 154 | (let [walls (->> #(generate-walls-blot 20) 155 | (repeatedly 5) 156 | (apply concat) 157 | set)] 158 | (run 5 walls true solution))) 159 | -------------------------------------------------------------------------------- /2_snake/src/snake/work.clj: -------------------------------------------------------------------------------- 1 | (ns snake.work 2 | (:require [snake.core :refer (run-not-grow run-grow run-many-apples run-with-walls)])) 3 | 4 | ;;; You're writing a bot for playing snake. 5 | ;;; So, you are a snake and your goal is to collect apples. 6 | ;;; Field size: 40 x 30 7 | ;;; Every turn you move to one of the adjacent cell. 8 | ;;; Your function must take 2 arguments: snake position and apple position and decide which direction to move. 9 | ;;; Directions are: :up, :down, :left, :right (they are keywords). Your function must return one of these directions. 10 | ;;; Position (snake or apple) is a vector of 2 elements: x and y. 11 | ;;; In this task snake is not growing from eating apples so there is no danger of snake hitting itself. 12 | ;;; Note: upper left corner cell is (0, 0). 13 | 14 | ;;; Uncomment and substitute your solution 15 | ; (run-not-grow YOUR_SOLUTION_HERE) 16 | 17 | 18 | 19 | ;;; Snake is growing now. (each time snake eats an apple, body length increases). 20 | ;;; You need to write similar function as in previous task. 21 | ;;; It takes 2 arguments. 22 | ;;; First argument is snake body - collection of cells, each cell is a vector of x and y. First cell is the head. 23 | ;;; Second argument is apple position - vector of x and y. 24 | ;;; It should return direction: :up, :down, :left or :right. 25 | ;;; Note that you cannot change direction to the opposite in 1 move: snake will hit it's tail if length is 2 or more. 26 | ;;; Well, you can change direction but snake will die :\ 27 | 28 | ;;; Uncomment and substitute your solution 29 | ; (run-grow YOUR_SOLUTION_HERE) 30 | 31 | 32 | 33 | ;;; Now you have many apples (five) instead of one. 34 | ;;; Function the same as previous but it takes set of apples instead of the single apple. 35 | ;;; Each apple in the set is a vector of x and y. 36 | 37 | ;;; Uncomment and substitute your solution 38 | ; (run-many-apples YOUR_SOLUTION_HERE) 39 | 40 | 41 | 42 | ;;; Walls are added. So snake can hit wall and die. 43 | ;;; Your function now takes third argument - set of walls. 44 | ;;; Each wall is a cell that snake is not allowed to bump to. 45 | ;;; Wall is a vector of x and y. 46 | 47 | ;;; Uncomment and substitute your solution 48 | ; (run-with-walls YOUR_SOLUTION_HERE) 49 | -------------------------------------------------------------------------------- /3_durak/README.md: -------------------------------------------------------------------------------- 1 | Write a bot for playing [durak](http://en.wikipedia.org/wiki/Durak) card game. 2 | 3 | [Detailed description and work file](https://github.com/nbeloglazov/clojure-interactive-tasks/blob/master/3_durak/src/durak/work.clj) 4 | 5 | Screenshots: 6 | 7 | ![Durak](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/3_durak.png) 8 | -------------------------------------------------------------------------------- /3_durak/project.clj: -------------------------------------------------------------------------------- 1 | (defproject durak "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.5.1"] 3 | [quil/quil "1.7.0"]]) 4 | -------------------------------------------------------------------------------- /3_durak/resources/b1fh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b1fh.png -------------------------------------------------------------------------------- /3_durak/resources/b1pb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b1pb.png -------------------------------------------------------------------------------- /3_durak/resources/b1pl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b1pl.png -------------------------------------------------------------------------------- /3_durak/resources/b1pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b1pr.png -------------------------------------------------------------------------------- /3_durak/resources/b1pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b1pt.png -------------------------------------------------------------------------------- /3_durak/resources/b2fh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b2fh.png -------------------------------------------------------------------------------- /3_durak/resources/b2pb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b2pb.png -------------------------------------------------------------------------------- /3_durak/resources/b2pl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b2pl.png -------------------------------------------------------------------------------- /3_durak/resources/b2pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b2pr.png -------------------------------------------------------------------------------- /3_durak/resources/b2pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/b2pt.png -------------------------------------------------------------------------------- /3_durak/resources/blue_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/blue_back.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_10.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_11.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_12.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_13.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_14.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_2.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_3.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_4.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_5.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_6.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_7.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_8.png -------------------------------------------------------------------------------- /3_durak/resources/clubs_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/clubs_9.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_10.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_11.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_12.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_13.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_14.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_2.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_3.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_4.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_5.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_6.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_7.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_8.png -------------------------------------------------------------------------------- /3_durak/resources/diamonds_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/diamonds_9.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_10.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_11.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_12.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_13.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_14.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_2.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_3.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_4.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_5.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_6.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_7.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_8.png -------------------------------------------------------------------------------- /3_durak/resources/hearts_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/hearts_9.png -------------------------------------------------------------------------------- /3_durak/resources/joker_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/joker_black.png -------------------------------------------------------------------------------- /3_durak/resources/joker_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/joker_red.png -------------------------------------------------------------------------------- /3_durak/resources/red_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/red_back.png -------------------------------------------------------------------------------- /3_durak/resources/spades_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_10.png -------------------------------------------------------------------------------- /3_durak/resources/spades_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_11.png -------------------------------------------------------------------------------- /3_durak/resources/spades_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_12.png -------------------------------------------------------------------------------- /3_durak/resources/spades_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_13.png -------------------------------------------------------------------------------- /3_durak/resources/spades_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_14.png -------------------------------------------------------------------------------- /3_durak/resources/spades_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_2.png -------------------------------------------------------------------------------- /3_durak/resources/spades_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_3.png -------------------------------------------------------------------------------- /3_durak/resources/spades_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_4.png -------------------------------------------------------------------------------- /3_durak/resources/spades_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_5.png -------------------------------------------------------------------------------- /3_durak/resources/spades_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_6.png -------------------------------------------------------------------------------- /3_durak/resources/spades_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_7.png -------------------------------------------------------------------------------- /3_durak/resources/spades_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_8.png -------------------------------------------------------------------------------- /3_durak/resources/spades_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/3_durak/resources/spades_9.png -------------------------------------------------------------------------------- /3_durak/src/durak/core.clj: -------------------------------------------------------------------------------- 1 | (ns durak.core 2 | (:use quil.core 3 | durak.logic 4 | [clojure.java.io :only (resource)]) 5 | (:import [java.awt.event KeyEvent])) 6 | 7 | (def margin-top 20) 8 | (def margin-left 200) 9 | (def hand-cards-gap 40) 10 | (def overlap 50) 11 | (def hand-table-gap 30) 12 | (def table-cards-gap 10) 13 | (def card-height 96) 14 | (def card-width 72) 15 | 16 | (defmacro fn-state [vars & body] 17 | `(fn [] (let ~(vec (apply concat 18 | (for [var vars] 19 | [var `(state ~(keyword var))]))) 20 | ~@body))) 21 | 22 | (defn card-url [{:keys [rank suit]}] 23 | (let [name (str (name suit) "_" rank ".png") 24 | res (resource name)] 25 | (if (nil? res) 26 | (throw (IllegalArgumentException. (str "Could not find image " name))) 27 | res))) 28 | 29 | (defn load-images [] 30 | (let [cards-images (into {} (map #(vector % (load-image (card-url %))) deck))] 31 | (assoc cards-images :back (load-image (resource "blue_back.png"))))) 32 | 33 | (defn setup-fn [player-a player-b] 34 | (fn [] 35 | (smooth) 36 | (set-state! :images (load-images) 37 | :state (atom (init-game player-a player-b))) 38 | (frame-rate 10))) 39 | 40 | (defn draw-player [player images top] 41 | (doseq [[ind card] (map-indexed vector player)] 42 | (when-not (nil? card) 43 | (image (images card) (+ margin-left (* ind hand-cards-gap)) top)))) 44 | 45 | (defn draw-table [table attacker images] 46 | (let [pairs (partition-all 2 table) 47 | y-top-card (+ margin-top card-height hand-table-gap) 48 | y-bottom-card (+ y-top-card (- card-height overlap))] 49 | (doseq [[ind [attack-card defend-card]] (map-indexed vector pairs)] 50 | (let [x (+ margin-left (* ind (+ table-cards-gap card-width))) 51 | [y-at y-def] ((if (zero? attacker) identity reverse) [y-top-card y-bottom-card])] 52 | (image (images attack-card) x y-at) 53 | (when-not (nil? defend-card) 54 | (image (images defend-card) x y-def)))))) 55 | 56 | (defn draw-deck [deck images] 57 | (let [y-deck (+ margin-top 58 | (/ (- (+ (* 4 card-height) 59 | (* 2 hand-table-gap)) 60 | overlap 61 | card-height) 62 | 2)) 63 | x (/ (- margin-left card-height card-width) 2) 64 | y-trump (+ y-deck (/ (- card-height card-width) 2))] 65 | (when-let [trump (last deck)] 66 | (push-matrix) 67 | (translate x y-trump) 68 | (rotate (/ Math/PI -2)) 69 | (image (images trump) (- card-width) (/ card-width 2)) 70 | (pop-matrix) 71 | (dotimes [ind (dec (count deck))] 72 | (image (images :back) x (- y-deck (* ind 2))))))) 73 | 74 | (def draw 75 | (fn-state [images state] 76 | (background 200) 77 | (fill 0) 78 | (let [{:keys [players table attacker deck]} @state 79 | [pl-a pl-b] players] 80 | (draw-player pl-a (constantly (:back images)) margin-top) 81 | (draw-player pl-b images (+ margin-top 82 | (* 3 card-height) 83 | (- overlap) 84 | (* 2 hand-table-gap))) 85 | (draw-table table attacker images) 86 | (draw-deck deck images)))) 87 | 88 | (def key-pressed 89 | (fn-state [state] 90 | (cond (= KeyEvent/VK_SPACE (key-code)) 91 | (do (swap! state next-action)) 92 | (= KeyEvent/VK_R (key-code)) 93 | (reset! state (apply init-game (:player-fns @state)))))) 94 | 95 | (defn run [player-a player-b] 96 | (let [setup (setup-fn player-a player-b)] 97 | (sketch 98 | :title "Durak" 99 | :setup setup 100 | :draw draw 101 | :key-pressed key-pressed 102 | :size [800 600]))) 103 | 104 | (def simple-bot 105 | {:attack 106 | (fn [{:keys [table hand trump]}] 107 | (if (empty? table) 108 | (first hand) 109 | nil)) 110 | :defend 111 | (fn [{:keys [table hand trump]}] 112 | (first (filter #(higher? % (last table) trump) hand)))}) 113 | 114 | (def run-game (partial run simple-bot)) 115 | -------------------------------------------------------------------------------- /3_durak/src/durak/logic.clj: -------------------------------------------------------------------------------- 1 | (ns durak.logic) 2 | 3 | (def deck 4 | (for [suit [:spades :hearts :diamonds :clubs] 5 | rank (range 6 15)] 6 | {:suit suit 7 | :rank rank})) 8 | 9 | (defn op [attacker] 10 | (- 1 attacker)) 11 | 12 | (defn draw-cards-player [player deck] 13 | (let [need (max (min (- 6 (count player)) 14 | (count deck)) 15 | 0)] 16 | [(concat player (take need deck)) 17 | (drop need deck)])) 18 | 19 | (defn higher? [{suit-a :suit rank-a :rank} 20 | {suit-b :suit rank-b :rank} 21 | trump] 22 | (if (= suit-a suit-b) 23 | (> rank-a rank-b) 24 | (= suit-a trump))) 25 | 26 | (defn draw-cards [{:keys [players deck attacker] :as state}] 27 | (let [players (mapv #(remove nil? %) players) 28 | [pl1 deck] (draw-cards-player (players attacker) deck) 29 | [pl2 deck] (draw-cards-player (players (op attacker)) deck)] 30 | (-> state 31 | (assoc-in [:deck] deck) 32 | (assoc-in [:players attacker] pl1) 33 | (assoc-in [:players (op attacker)] pl2)))) 34 | 35 | (defn init-game [player-a player-b] 36 | (let [deck (shuffle deck)] 37 | (draw-cards {:player-fns [player-a player-b] 38 | :table [] 39 | :deck deck 40 | :trump (:suit (last deck)) 41 | :attacker (rand-int 2) 42 | :players [[] []]}))) 43 | 44 | (defn discard [{:keys [table players attacker] :as state}] 45 | {:pre [(even? (count table))]} 46 | (-> state 47 | (assoc-in [:table] []) 48 | (update-in [:attacker] op) 49 | draw-cards)) 50 | 51 | (defn defender-takes [{:keys [table players attacker] :as state}] 52 | {:pre [(odd? (count table))]} 53 | (-> state 54 | (assoc-in [:table] []) 55 | (update-in [:players (op attacker)] concat table) 56 | draw-cards)) 57 | 58 | (defn contains-rank? [table {:keys [rank]}] 59 | (some #(= rank (:rank %)) table)) 60 | 61 | (defn call-player-fn [type {:keys [attacker players player-fns table trump]}] 62 | (let [player-ind (if (= type :attack) attacker (op attacker))] 63 | ((get-in player-fns [player-ind type]) 64 | {:table table 65 | :hand (remove nil? (players player-ind)) 66 | :trump trump}))) 67 | 68 | (defn throw-iae [& args] 69 | (throw (IllegalArgumentException. (apply str args)))) 70 | 71 | (defn validate-attack-card [card {:keys [attacker players table]}] 72 | (when-not (or (empty? table) 73 | (contains-rank? table card)) 74 | (throw-iae "Can't attack with " 75 | card 76 | ". There is no such rank on the table: " 77 | table)) 78 | (when (every? #(not= card %) (players attacker)) 79 | (throw-iae "Can't attack with " 80 | card 81 | ". Attacker doesn't have such card: " 82 | (players attacker)))) 83 | 84 | (defn validate-defend-card [card {:keys [attacker players table trump]}] 85 | (when (every? #(not= card %) (players (op attacker))) 86 | (throw-iae "Can't defend with " 87 | card 88 | ". Defender doesn't have such card: " 89 | (players (op attacker)))) 90 | (when-not (higher? card (last table) trump) 91 | (throw-iae "Can't defend with " 92 | card 93 | ". It's lower than attack card: " 94 | (last table)))) 95 | 96 | (defn move-to-table [card player state] 97 | (-> state 98 | (update-in [:table] conj card) 99 | (update-in [:players player] #(replace {card nil} %)))) 100 | 101 | (defn end-of-game? [{:keys [table players deck]}] 102 | (and (empty? deck) 103 | (some empty? players) 104 | (empty? table))) 105 | 106 | 107 | (defn next-action [{:keys [table attacker players] :as state}] 108 | (if (end-of-game? state) 109 | ;;; Return state without modification 110 | state 111 | ;;; Check if this attack of defense. 112 | (if (even? (count table)) 113 | ;;; Attack 114 | (if (->> (op attacker) players (remove nil?) empty?) 115 | ;;; Defender has no cards. End of attack 116 | (discard state) 117 | ;;; Defender has at least 1 card. Attack continues. 118 | (if-let [card (call-player-fn :attack state)] 119 | ;;; Attacker selected card for attack. 120 | (do (validate-attack-card card state) 121 | (move-to-table card attacker state)) 122 | ;;; Attacker select no card for attach. End of attack. 123 | (discard state))) 124 | ;;; Defend 125 | (if-let [card (call-player-fn :defend state)] 126 | ;;; Defender selected card for defense. 127 | (do (validate-defend-card card state) 128 | (move-to-table card (op attacker) state)) 129 | ;;; Defender selected no card for defense. He takes all cards from the table. 130 | (defender-takes state))))) 131 | 132 | -------------------------------------------------------------------------------- /3_durak/src/durak/work.clj: -------------------------------------------------------------------------------- 1 | (ns durak.work 2 | (:require [durak.core :refer [run-game]])) 3 | 4 | 5 | ;;; Your task is to write a bot for playing card game "Durak": http://en.wikipedia.org/wiki/Durak 6 | ;;; Your bot plays against another built-in bot (2 players). 7 | ;;; Bot is a map that contains 2 functions: function to attack and function to defend. 8 | ;;; It must have following format: {:attack YOUR_ATTACK_FN :defend YOUR_DEFEND_FN} 9 | ;;; Attack and defend functions are similar: they both take same arguments and both must return a card. 10 | ;;; Attack function is called when your are an attacker and it should select 1 card from your hand and put it on the table. 11 | ;;; Note that if it is not the first card in current attack, it must have the same rank as one of the cards on the table (check rules). 12 | ;;; If you return nil it means that you don't want to attack and attack is finished. 13 | ;;; Defend function is called when your are a defender and it should select 1 card from your hand and put it on the table. 14 | ;;; If you return nil it means you can't (or don't want to) defend and you take all cards from the table to you hand. 15 | 16 | ;;; Card is a map with 2 keys: rank and suit. 17 | ;;; Rank is a number from 6 to 14. 18 | ;;; 11 - Jack 19 | ;;; 12 - Queen 20 | ;;; 13 - King 21 | ;;; 14 - Ace 22 | ;;; Suit is one of the 4 keywords: :spades, :hearts, :diamonds or :clubs 23 | ;;; Examples: {:rank 6, :suit :clubs} {:rank 14, :suit :hearts} 24 | 25 | ;;; Functions input: 26 | ;;; Each function takes single argument - map of following structure (example): 27 | ;;; {:hand [{:rank 6, :suit :clubs} 28 | ;;; {:rank 8, :suit :hearts}], 29 | ;;; :table [{:rank 6, :suite :hearts}], 30 | ;;; :trump :clubs} 31 | ;;; Hand is a sequence of cards in your hand. 32 | ;;; Table is a sequence of cards already on table. 33 | ;;; If you are an attacker and it's the start of the attack then table will be empty. 34 | ;;; If you are a defender then table will be non-empty and your need to beat last card from the table. 35 | ;;; Cards on the table can be represented like: attack - defense - attack - defense - attack. Odd cards are attack cards, even cards are defense cards. 36 | ;;; Trump is trump suit of the game. 37 | 38 | ;;; To test your solution use run-game function: (run-game YOUR_SOLUTION) 39 | ;;; Your bot is the player in the bottom part of screen (cards a visible to your). 40 | ;;; To run next action press SPACE, to restart game press R. 41 | ;;; When game is over (one of the players has no cards in his hand) nothing will happen when your press SPACE. 42 | ;;; If your press SPACE and nothing happen and game is not over yet, look at stacktraces, probably your bot (or built-in bot) tries to perform invalid atttack or defense. 43 | 44 | 45 | 46 | ;;; Implement program that takes 2 bots, runs game and returns winner. 47 | ;;; Study init-game and next-action function in the src/durak/logic.clj. They can be used to run game. 48 | 49 | 50 | 51 | ;;; Implement bot that memorizes all cards played in game and use some smarter logic based on probability of opponents cards. 52 | ;;; Use clojure atoms or refs to store data between moves. 53 | ;;; If you've implemented this bot in the first task then you can skip it :) 54 | 55 | 56 | 57 | ;;; Implement attack and defense functions that they ask user input so human can play. 58 | ;;; I don't know how to do it, may be some hacks with swing like creating and invoking dialog to ask for user input. 59 | 60 | 61 | 62 | ;;; Modify program so it 3 or 4 players can play at the same table. 63 | -------------------------------------------------------------------------------- /4_cellular_automaton/README.md: -------------------------------------------------------------------------------- 1 | Implement generic cellular automaton simulator that supports arbitrary rules and user interaction. 2 | 3 | [Detailed description and work file](https://github.com/nbeloglazov/clojure-interactive-tasks/blob/master/4_cellular_automaton/src/cellular_automaton/work.clj) 4 | 5 | Screenshots: 6 | 7 | ![Conway's Game of Life](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/4_cellular_automaton_life.png) 8 | ![Langton's ant](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/4_cellular_automaton_ant.png) 9 | ![Wireworld](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/4_cellular_automaton_wireworld.png) -------------------------------------------------------------------------------- /4_cellular_automaton/project.clj: -------------------------------------------------------------------------------- 1 | (defproject cellular-automaton "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.5.1"] 3 | [quil "1.7.0"]]) 4 | -------------------------------------------------------------------------------- /4_cellular_automaton/src/cellular_automaton/work.clj: -------------------------------------------------------------------------------- 1 | (ns cellular-automaton.work 2 | (:require [quil.core :refer :all])) 3 | 4 | ;;; Your task is to implement cellular automaton. 5 | ;;; The most famous example of cellular automaton is Conway's Game of Life. 6 | ;;; Unlike previous tasks now you have to implement both visualization and bots. So you need to implement everything :) 7 | ;;; I suggest to use quil library for animation (it was used in all previous tasks): https://github.com/quil/quil 8 | ;;; or you can use whatever you want. 9 | ;;; Keep in mind that is should be simple to run your simulator with different automata (Game of Life is only one example of many). 10 | 11 | 12 | ;;; Implement and run Brian's Brain automaton in your simulator: http://en.wikipedia.org/wiki/Brian%27s_Brain 13 | 14 | 15 | ;;; Implement Wireworld automaton: http://en.wikipedia.org/wiki/Wireworld 16 | 17 | 18 | ;;; Add Wireworld implementation to Rosetta Code (it's not present here yet): http://rosettacode.org/wiki/Wireworld 19 | 20 | 21 | ;;; Implement Von Neumann cellular automaton: http://en.wikipedia.org/wiki/Von_Neumann_cellular_automata 22 | 23 | 24 | ;;; Implement Langton's ant: http://en.wikipedia.org/wiki/Langton%27s_ant 25 | 26 | 27 | ;;; Add ability to change cells states by mouse click, to restart and pause simulation. 28 | -------------------------------------------------------------------------------- /5_k_means/README.md: -------------------------------------------------------------------------------- 1 | Implement [k-means](http://en.wikipedia.org/wiki/K-means_clustering) clustering algorithm. 2 | 3 | [Detailed description and work file](https://github.com/nbeloglazov/clojure-interactive-tasks/blob/master/5_k_means/src/k_means/work.clj) 4 | 5 | Screenshots: 6 | 7 | ![k-means](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/5_k_means.png) 8 | -------------------------------------------------------------------------------- /5_k_means/project.clj: -------------------------------------------------------------------------------- 1 | (defproject k-means "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.5.1"] 3 | [quil "1.7.0"]]) 4 | -------------------------------------------------------------------------------- /5_k_means/src/k_means/core.clj: -------------------------------------------------------------------------------- 1 | (ns k-means.core 2 | (:use quil.core)) 3 | 4 | (def w 800) 5 | (def h 600) 6 | (def d 10) 7 | (def num-of-points 20) 8 | 9 | (defmacro fn-state [vars & body] 10 | `(fn [] (let ~(vec (apply concat 11 | (for [var vars] 12 | [var `(state ~(keyword var))]))) 13 | ~@body))) 14 | 15 | (defn random-color [] 16 | (->> #(+ 127 (rand-int 127)) 17 | (repeatedly 3) 18 | (apply color))) 19 | 20 | (defn circle-points [[x y] rad n] 21 | (let [random (java.util.Random.) 22 | dist-fn #(* (.nextGaussian random) 0.3333333 rad)] 23 | (repeatedly n #(let [angle (rand (* 2 Math/PI)) 24 | dist (dist-fn)] 25 | [(+ x (* (cos angle) dist)) 26 | (+ y (* (sin angle) dist))])))) 27 | 28 | (def regenerate-points 29 | (fn-state [points initial-fn] 30 | (reset! points (vec (initial-fn))))) 31 | 32 | (def colors (repeatedly random-color)) 33 | 34 | (def recalculate-clusters 35 | (fn-state [clusters points solution] 36 | (reset! clusters (solution @points)))) 37 | 38 | (defn setup-fn [initial-fn solution] 39 | (fn [] 40 | (set-state! 41 | :clusters (atom []) 42 | :points (atom []) 43 | :solution solution 44 | :initial-fn initial-fn) 45 | (regenerate-points) 46 | (recalculate-clusters))) 47 | 48 | 49 | (defn draw-cluster [points color] 50 | (fill color) 51 | (doseq [[x y] points] 52 | (ellipse x y d d))) 53 | 54 | (def draw 55 | (fn-state [clusters] 56 | (background 200) 57 | (doseq [[cluster color] (map vector @clusters colors)] 58 | (draw-cluster cluster color)))) 59 | 60 | (def mouse-pressed 61 | (fn-state [points] 62 | (swap! points conj [(mouse-x) (mouse-y)]) 63 | (recalculate-clusters))) 64 | 65 | (def space (keyword " ")) 66 | 67 | (defn key-pressed [] 68 | (when (= (key-as-keyword) space) 69 | (regenerate-points) 70 | (recalculate-clusters))) 71 | 72 | (defn run [initial-fn solution] 73 | (sketch 74 | :title "k-means" 75 | :setup (setup-fn initial-fn solution) 76 | :draw draw 77 | :mouse-pressed mouse-pressed 78 | :key-pressed key-pressed 79 | :size [w h])) 80 | 81 | (defn n-clusters [n max-rad min-rad n-points] 82 | (letfn [(random-circle [] 83 | (let [r (+ min-rad (rand-int (- max-rad min-rad)))] 84 | [(+ r (rand-int (- w r r))) 85 | (+ r (rand-int (- h r r))) 86 | r])) 87 | (intersects? [[x0 y0 r0] 88 | [x1 y1 r1]] 89 | (< (dist x0 y0 x1 y1) (+ r0 r1))) 90 | (intersects-any? [clusters circle] 91 | (some #(intersects? circle %) clusters)) 92 | (add-circle [clusters] 93 | (->> (repeatedly 100 random-circle) 94 | (remove #(intersects-any? clusters %)) 95 | (#(nth % 0 (random-circle))) 96 | (conj clusters))) 97 | (circle-to-points [[x y r]] 98 | (circle-points [x y] r n-points))] 99 | (->> (nth (iterate add-circle []) n) 100 | (map circle-to-points) 101 | (apply concat) 102 | #_shuffle))) 103 | 104 | (def run-empty (partial run #(vector))) 105 | 106 | (def run-2-clusters (partial run (partial n-clusters 2 100 200 30))) 107 | 108 | (def run-3-clusters (partial run (partial n-clusters 3 100 200 30))) 109 | 110 | (def run-random-clusters (partial run #(n-clusters (+ 2 (rand-int 5)) 50 100 30))) 111 | 112 | (defn random-points [] 113 | (->> #(vector (rand-int w) (rand-int h)) 114 | (repeatedly num-of-points))) 115 | 116 | (defn stupid [points] 117 | (map vector points)) 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /5_k_means/src/k_means/work.clj: -------------------------------------------------------------------------------- 1 | (ns k-means.work 2 | (:require [k-means.core :refer [run-empty run-2-clusters run-3-clusters run-random-clusters]])) 3 | 4 | 5 | ;;; Your task is to implement clustering algorithm. 6 | ;;; You're a given a set of points on plan and goal is to divide them into k clusters. 7 | ;;; Implement k-means algorithm to solve this task: http://en.wikipedia.org/wiki/K-means_clustering 8 | ;;; Your function must take collection of points. Each point is [x y]. 9 | ;;; It must return collection of clusters. Each cluster - collection of points. 10 | ;;; Example: there are 4 points: [0 0] [1 1] [9 9] [10 10] and you need to partition them into 2 clusters. 11 | ;;; Input will be [[0 0] [9 9] [1 1] [10 10]] and output should be something like [[[0 0] [1 1]] [[9 9] [10 10]]]. 12 | ;;; Note that you don't get k - number of clusters. You need to specify it somewhere in function. 13 | ;;; To test you solution use following tests: 14 | 15 | ; (run-empty SOLUTION) 16 | 17 | ; (run-2-clusters SOLUTION) 18 | 19 | ; (run-3-clusters SOLUTION) 20 | 21 | ;;; Interaction: mouse click - add new point 22 | ;;; space - reset simulation (remove all points or regenerate them, depenends on test) 23 | ;;; Note: you may need use different version of your function (with k = 2 for run-2-clusters and k = 3 for run-3-clusters). 24 | 25 | 26 | 27 | ;;; Now try to improve your solution so it can determine k based on given set of points. So if there are visually 3 clusters it should partition points to 3 clusters, if 4 than to 4 clusters. 28 | ;;; Test your solution on this test: 29 | 30 | ; (run-random-clusters SOLUTION) 31 | 32 | 33 | 34 | ;;; Implement some other clustering algorithm. 35 | -------------------------------------------------------------------------------- /6_derivative/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | pom.xml 6 | *.jar 7 | *.class 8 | .lein-deps-sum 9 | .lein-failures 10 | .lein-plugins 11 | -------------------------------------------------------------------------------- /6_derivative/README.md: -------------------------------------------------------------------------------- 1 | Implement function for symbolic differentiation of clojure expression, e.g. `(+ 2 x)`. 2 | 3 | [Detailed description and work file](https://github.com/nbeloglazov/clojure-interactive-tasks/blob/master/6_derivative/src/derivative/core.clj) 4 | 5 | Screenshots: 6 | 7 | ![Derivative](https://raw.github.com/nbeloglazov/clojure-interactive-tasks/master/misc/images/6_derivative.png) 8 | f = sin(2x) 9 | Plots of f, f' and f'' are shown. -------------------------------------------------------------------------------- /6_derivative/project.clj: -------------------------------------------------------------------------------- 1 | (defproject derivative "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.5.1"] 3 | [incanter/incanter "1.5.4" :exclusions [incanter/incanter-mongodb]]]) 4 | -------------------------------------------------------------------------------- /6_derivative/src/derivative/core.clj: -------------------------------------------------------------------------------- 1 | (ns derivative.core 2 | (:require [incanter.charts :refer [add-function function-plot]] 3 | [incanter.core :refer [view sin cos log]])) 4 | 5 | ;;; Helper function. Ignore it.. 6 | (defn functions-plot [min-x max-x f & fns] 7 | (reduce #(add-function % %2 min-x max-x) 8 | (function-plot f min-x max-x) 9 | fns)) 10 | 11 | ;;; Helper variable. Ignore it. 12 | (def ^:dynamic x) 13 | 14 | ;;; Helper function. Ignore it. 15 | (defn calc-expr [expr x-value] 16 | (binding [x x-value] 17 | (eval expr))) 18 | 19 | ;;; Helper function. Ignore it. 20 | (defn expr-plot [min-x max-x & fns] 21 | (apply functions-plot min-x max-x (map #(partial calc-expr %) fns))) 22 | 23 | 24 | ;;; Task is to implement derivative function. 25 | ;;; It takes expression - valid clojure form like (+ x x) or (* 5 (+ x (* 7 x))) and returns derivative of this expression. 26 | ;;; All functions in expression are binary or unary, so (* x x x) is not allowed, it should be written as follows: (* (* x x) x) 27 | ;;; derivative should support following functions: +, -, *, / - binary, sin, cos, log - unary. 28 | ;;; It must return valid clojure expression. 29 | ;;; Examples: 30 | ;;; (derivative '(+ x x)) => 2 or '(+ 1 1) 31 | ;;; (derivative '(sin (* 2 x))) => (* 2 (cos (* 2 x))) or it's equilavent. 32 | 33 | ; Change this function so it calculates derivative. 34 | ; Currently it just returns given expression. 35 | (defn derivative [expr] 36 | expr) 37 | 38 | 39 | ;;; Tests. 40 | ;;; Uncomment and try every function. 41 | 42 | ;;; f = x^2 43 | (defn test-simple [] 44 | (let [f '(* x x)] 45 | (view (expr-plot -10 10 f (derivative f))))) 46 | 47 | ;(test-simple) 48 | 49 | 50 | 51 | ;;; f = x^2 52 | (defn test-second-derivative [] 53 | (let [f '(* x x)] 54 | (view (expr-plot -10 10 f (derivative f) (derivative (derivative f)))))) 55 | 56 | ;(test-second-derivative) 57 | 58 | 59 | 60 | ;;; f = -7x^2 + 2x + 5 61 | (defn test-complex [] 62 | (let [f '(+ (+ (* -7 (* x x)) 63 | (* 2 x)) 64 | 5)] 65 | (view (expr-plot -5 5 f (derivative f) (derivative (derivative f)))))) 66 | 67 | ;(test-complex) 68 | 69 | 70 | 71 | ;;; f = 1/(1 + x^2) 72 | (defn test-division [] 73 | (let [f '(/ 1 (+ (* x x) 74 | 1))] 75 | (view (expr-plot -4 4 f (derivative f))))) 76 | 77 | ;(test-division) 78 | 79 | 80 | 81 | ;;; f = sin(2x) 82 | (defn test-trigonometry [] 83 | (let [f '(sin (* 2 x))] 84 | (view (expr-plot (- Math/PI) Math/PI f (derivative f) (derivative (derivative f)))))) 85 | 86 | ;(test-trigonometry) 87 | 88 | 89 | 90 | ;;; f = log(1 + x^2) 91 | (defn test-logarithm [] 92 | (let [f '(log (+ 1 (* x x)))] 93 | (view (expr-plot -4 4 f (derivative f))))) 94 | 95 | ;(test-logarithm) 96 | p 97 | -------------------------------------------------------------------------------- /7_church_encoding/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | pom.xml 6 | *.jar 7 | *.class 8 | .lein-deps-sum 9 | .lein-failures 10 | .lein-plugins 11 | -------------------------------------------------------------------------------- /7_church_encoding/README.md: -------------------------------------------------------------------------------- 1 | Implement arithmetic, recursion, lists in lambda calculus. 2 | 3 | [Detailed description and work file](https://github.com/nbeloglazov/clojure-interactive-tasks/blob/master/7_church_encoding/src/church_encoding/work.clj) 4 | -------------------------------------------------------------------------------- /7_church_encoding/project.clj: -------------------------------------------------------------------------------- 1 | (defproject church-encoding "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.5.1"]]) 3 | -------------------------------------------------------------------------------- /7_church_encoding/src/church_encoding/core.clj: -------------------------------------------------------------------------------- 1 | (ns church-encoding.core) 2 | 3 | (defn to-normal-num [n] 4 | ((n inc) 0)) 5 | 6 | (defn to-church-num [n] 7 | (fn [f] (fn [x] (nth (iterate f x) n)))) 8 | 9 | (defn run-tests [pass? log-result tests] 10 | (let [check-and-log (fn [test] 11 | (let [result (pass? test)] 12 | (log-result (if result "OK" "Fail") test) 13 | result)) 14 | passed (->> tests 15 | (map check-and-log) 16 | (filter true?) 17 | count)] 18 | (printf "%d/%d passed\n" passed (count tests)))) 19 | 20 | (defn test-plus [plus] 21 | (run-tests 22 | (fn [[a b]] 23 | (= (to-normal-num 24 | ((plus (to-church-num a)) (to-church-num b))) 25 | (+ a b))) 26 | (fn [result [a b]] 27 | (printf "%4s %d + %d = %d\n" result a b (+ a b))) 28 | [[0 0] 29 | [0 1] 30 | [1 0] 31 | [2 3] 32 | [10 10]])) 33 | 34 | (defn test-mult [mult] 35 | (run-tests 36 | (fn [[a b]] 37 | (= (to-normal-num 38 | ((mult (to-church-num a)) (to-church-num b))) 39 | (* a b))) 40 | (fn [result [a b]] 41 | (printf "%4s %d * %d = %d\n" result a b (* a b))) 42 | [[0 0] 43 | [1 0] 44 | [1 1] 45 | [2 2] 46 | [3 6]])) 47 | 48 | 49 | (defn test-pow [pow] 50 | (run-tests 51 | (fn [[a b]] 52 | (= (to-normal-num 53 | ((pow (to-church-num a)) (to-church-num b))) 54 | (int (Math/pow a b)))) 55 | (fn [result [a b]] 56 | (printf "%4s %d ^ %d = %d\n" result a b (int (Math/pow a b)))) 57 | [[1 0] 58 | [1 1] 59 | [2 2] 60 | [2 3] 61 | [0 2]])) 62 | 63 | (defn test-dec [dec] 64 | (run-tests 65 | (fn [n] 66 | (= (to-normal-num 67 | (dec (to-church-num n))) 68 | (- n 1))) 69 | (fn [result n] 70 | (printf "%4s (dec %d) = %d\n" result n (- n 1))) 71 | [1 2 3 4 5])) 72 | 73 | (defn test-sum [sum] 74 | (run-tests 75 | (fn [n] 76 | (= (to-normal-num (sum (to-church-num n))) 77 | (apply + (range (inc n))))) 78 | (fn [result n] 79 | (printf "%4s (sum %d) = %d\n" result n (apply + (range (inc n))))) 80 | [0 1 2 3 4 5])) 81 | 82 | 83 | (defn test-list [{:keys [empty? empty-list cons head tail]}] 84 | (letfn [(to-lambda-list [coll] 85 | (reduce #((cons %2) %1) empty-list (reverse coll))) 86 | (to-vec [lambda-list] 87 | (((empty? lambda-list) 88 | (delay [])) 89 | (delay (clojure.core/cons (head lambda-list) 90 | @(to-vec (tail lambda-list)))))) 91 | (to-word [result] 92 | (if result " OK" "Fail"))] 93 | (let [res [(let [res (((empty? empty-list) true) false)] 94 | (println (to-word res) "(empty? empty-list) must be true") 95 | res) 96 | (let [lamdba-list ((cons 42) empty-list) 97 | h (head lamdba-list) 98 | res (= h 42)] 99 | (println (to-word res) "(head (cons 42 empty-list)) = 42") 100 | res) 101 | (let [lambda-list ((cons 42) empty-list) 102 | t (tail lambda-list) 103 | res (((empty? t) true) false)] 104 | (println (to-word res) "(empty? (tail (cons 42 empty-list))) must be true") 105 | res) 106 | (let [lambda-list (to-lambda-list [1 2 3 4 5]) 107 | res (= [1 2 3 4 5] @(to-vec lambda-list))] 108 | (println (to-word res) "converting [1 2 3 4 5] to lambda list and back to clojure vector using passed functions") 109 | res)] 110 | passed (count (filter true? res))] 111 | (printf "%d/%d passed\n" passed (count res))))) 112 | 113 | (defn test-map-reduce [{:keys [empty? empty-list cons head tail map reduce]}] 114 | (letfn [(to-lambda-list [coll] 115 | (clojure.core/reduce #((cons %2) %1) empty-list (reverse coll))) 116 | (to-vec [lambda-list] 117 | (((empty? lambda-list) 118 | (delay [])) 119 | (delay (clojure.core/cons (head lambda-list) 120 | @(to-vec (tail lambda-list)))))) 121 | (to-word [result] 122 | (if result " OK" "Fail"))] 123 | (let [l (to-lambda-list [1 2 3 4 5]) 124 | res [(let [res-v @(to-vec ((map #(* % %)) l)) 125 | res (= [1 4 9 16 25] res-v)] 126 | (println (to-word res) "(map square [1 2 3 4 5]) must [1 4 9 16 25]") 127 | (when-not res 128 | (println " Got" res-v)) 129 | res) 130 | (let [mult (fn [a] (fn [b] (* a b))) 131 | res-v (((reduce mult) 1) l) 132 | res (= res-v 120)] 133 | (println (to-word res) "(reduce * 1 [1 2 3 4 5]) must be 120") 134 | (when-not res 135 | (println " Got" res-v)) 136 | res)] 137 | passed (count (filter true? res))] 138 | (printf "%d/%d passed\n" passed (count res))))) 139 | 140 | -------------------------------------------------------------------------------- /7_church_encoding/src/church_encoding/work.clj: -------------------------------------------------------------------------------- 1 | (ns church-encoding.work 2 | (:use [church-encoding.core])) 3 | 4 | ;;; Task is to implement arithmetic for Church numerals. 5 | ;;; Check this page: http://en.wikipedia.org/wiki/Church_encoding 6 | ;;; You can use utility function to-church-num and to-normal-num to convert regular number to church and church to regular: 7 | ;;; Note that to-church-num returns function that takes single argument f 8 | ;;; and returns function that takes single argument x that calculates (f (f ... (f x)...)) 9 | ;;; All functions in this task must be single argument functions that return other functions. 10 | 11 | ;;; Example: 12 | 13 | (def church-5 (to-church-num 5)) ; 5 in church numerals 14 | 15 | (defn print-star [x] (print "*") x) ; Takes 1 argument, prints a star and retuns argument without modification. 16 | 17 | ((church-5 print-star) nil) ; Prints ***** to console 18 | 19 | (to-normal-num church-5) ; returns 5 20 | 21 | (def church-2 (to-church-num 2)) ; we'll use it in examples later 22 | 23 | 24 | 25 | ;;; Implement + (plus) for church numerals. 26 | 27 | (def plus :YOUR_IMPLEMENTATION_HERE) 28 | 29 | (to-normal-num ((plus church-2) church-2)) ; must return 4 30 | 31 | (test-plus plus) ; test your solution 32 | 33 | 34 | 35 | ;;; Implement * (multiplication) for church numerals 36 | 37 | (def mult :YOUR_IMPLEMENTATION_HERE) 38 | 39 | (to-normal-num ((mult church-2) church-5)) ; must return 10 40 | 41 | (test-mult mult) ; test your solution 42 | 43 | 44 | 45 | ;;; Implement ^ (pow function) for church numerals. 46 | 47 | (def pow :YOUR_IMPLEMENTATION_HERE) 48 | 49 | (to-normal-num ((pow church-2) church-5)) ; must return 32 50 | 51 | (test-pow pow) ; test your solution 52 | 53 | 54 | 55 | ;;; Implement dec function for church numerals. 56 | 57 | (def dec :YOUR_IMPLEMENTATION_HERE) 58 | 59 | (to-normal-num (dec church-5)) ; must return 4 60 | 61 | (test-dec dec) ; test your solution 62 | 63 | 64 | 65 | ;;; Implement sum function. sum takes number n and returns sum of all numbers less or equals to n. 66 | ;;; You'll need to use recursion here. For recursion you'll need lazy values. 67 | ;;; You can use delay for that: http://clojuredocs.org/clojure_core/1.2.0/clojure.core/delay 68 | 69 | (def sum :YOUR_IMPLEMENTATION_HERE) 70 | 71 | (to-normal-num (sum church-2)) ; must return 3 72 | 73 | (test-sum sum) 74 | 75 | 76 | ;;; Implement set of function to create/manipulate lists. 77 | ;;; Your need to implement following functions: 78 | ;;; empty? - checks if list is empty, returns true or false. see church booleans http://en.wikipedia.org/wiki/Church_encoding#Church_booleans 79 | ;;; empty-list - used as "end" of the list. 80 | ;;; head - returns head of a list 81 | ;;; tail - returns tail of a list 82 | ;;; cons - takes 2 arguments h and t, and creates a list such that (head (cons a b)) = a, (tail (cons a b)) = b 83 | ;;; 84 | ;;; Help: http://en.wikipedia.org/wiki/Church_encoding#List_encodings 85 | 86 | (def empty? :YOUR_IMPLEMENTATION_HERE) 87 | 88 | (def empty-list :YOUR_IMPLEMENTATION_HERE) 89 | 90 | (def head :YOUR_IMPLEMENTATION_HERE) 91 | 92 | (def tail :YOUR_IMPLEMENTATION_HERE) 93 | 94 | (def cons :YOUR_IMPLEMENTATION_HERE) 95 | 96 | (((empty? empty-list) true) false) ; must return true 97 | 98 | (head (cons "Hello" empty-list)) ; must return "Hello" 99 | 100 | (let [list (cons "Hello" empty-list) 101 | t (tail list)] 102 | ((empty? t) true) false) ; must return true 103 | 104 | (test-list {:empty? empty? 105 | :empty-list empty-list 106 | :head head 107 | :tail tail 108 | :cons cons}) ; test your solution 109 | 110 | 111 | 112 | ;;; Additional task. 113 | ;;; Implement map and reduce functions for lambda lists. 114 | ;;; map takes 2 arguments: function and list 115 | ;;; reduce takes 3 arguments: function, init value and list 116 | 117 | (def map :YOUR_IMPLEMENTATION_HERE) 118 | 119 | (def reduce :YOUR_IMPLEMENTATION_HERE) 120 | 121 | (test-map-reduce {:empty? empty? 122 | :empty-list empty-list 123 | :head head 124 | :tail tail 125 | :cons cons 126 | :map map 127 | :reduce reduce}) 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Small collection of interactive problems to practice clojure. Each problem is a clojure project that contains core.clj file with description of a problem and you need to implement your solution there. There is no automatic checking system, you check it manually. Solutions are visualised so you can look at it and decide whether it's good or not. Some tasks contain math and algorithms problems. Check tasks below to see screenshot examples. 2 | 3 | **Instructions** 4 | 5 | 1. Install java and [leiningen](https://github.com/technomancy/leiningen) if you don't have them. 6 | 2. Choose task (any folder except `misc`). 7 | 3. Open `$TASK_NAME/src/$TASK_NAME/work.clj` file to read excercises. 8 | 4. Solve them. 9 | 10 | **Tasks** 11 | * [Artillery](https://github.com/nbeloglazov/clojure-interactive-tasks/tree/master/1_artillery) 12 | * [Snake](https://github.com/nbeloglazov/clojure-interactive-tasks/tree/master/2_snake) 13 | * [Durak](https://github.com/nbeloglazov/clojure-interactive-tasks/tree/master/3_durak) 14 | * [Cellular automaton](https://github.com/nbeloglazov/clojure-interactive-tasks/tree/master/4_cellular_automaton) 15 | * [k-means](https://github.com/nbeloglazov/clojure-interactive-tasks/tree/master/5_k_means) 16 | * [Derivative](https://github.com/nbeloglazov/clojure-interactive-tasks/tree/master/6_derivative) 17 | * [Church encoding](https://github.com/nbeloglazov/clojure-interactive-tasks/tree/master/7_church_encoding) 18 | -------------------------------------------------------------------------------- /misc/fourclj-grabber/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | pom.xml 6 | *.jar 7 | *.class 8 | .lein-deps-sum 9 | .lein-failures 10 | .lein-plugins 11 | -------------------------------------------------------------------------------- /misc/fourclj-grabber/README.md: -------------------------------------------------------------------------------- 1 | # fourclj-grabber 2 | 3 | A Clojure library designed to ... well, that part is up to you. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © 2012 FIXME 12 | 13 | Distributed under the Eclipse Public License, the same as Clojure. 14 | -------------------------------------------------------------------------------- /misc/fourclj-grabber/project.clj: -------------------------------------------------------------------------------- 1 | (defproject fourclj-grabber "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :dependencies [[org.clojure/clojure "1.4.0"] 7 | [clj-http "0.5.5"] 8 | [org.clojure/data.json "0.1.3"] 9 | [org.clojure/data.csv "0.1.2"] 10 | [enlive/enlive "1.0.1"] 11 | [tentacles "0.2.0-beta1"]]) 12 | -------------------------------------------------------------------------------- /misc/fourclj-grabber/src/fourclj_grabber/core.clj: -------------------------------------------------------------------------------- 1 | (ns fourclj-grabber.core 2 | (:require [clojure.data.json :as json] 3 | [clojure.data.csv :as csv] 4 | [clojure.string :as string] 5 | [clojure.set :as set] 6 | [clojure.java.io :as io] 7 | [clj-http.client :as client] 8 | [net.cgrand.enlive-html :as html] 9 | [tentacles.gists :as gists])) 10 | 11 | (def base-url "http://www.4clojure.com/") 12 | (def problems-file "problems.csv") 13 | (def solutions-file "solutions_%d.clj") 14 | (def scores-file "scores.clj") 15 | 16 | (def lesson-1 [1 2 14 15 16 35 36 42 162 166]) 17 | (def lesson-2 [17 18 64 71 24 32 61 50 67 77]) 18 | (def lesson-3 [26 28 34 39 83 126 65 69 121 79]) 19 | (def lesson-6 [23 27 30 33 41 95 107 135 102 158]) 20 | (def lesson-7 [74 106 108 120 146]) 21 | (def lesson-9 [118 31 45 153 171 148 114 104 75 117]) 22 | (def lesson-12 [100 66 55 58 98 85 80 70 46 91]) 23 | 24 | (def users 25 | (set (map name 26 | '[cgrand 27 | megaterik 28 | kabbi 29 | anjenson 30 | hlebiksi 31 | zayankovsky 32 | lanakomar 33 | quadrocube 34 | pavelfromby 35 | efimikvitaliy 36 | kolina 37 | nikelandjelo 38 | mashabarashko]))) 39 | 40 | (defn string-to-html [str] 41 | (->> (.getBytes str) 42 | (java.io.ByteArrayInputStream.) 43 | (net.cgrand.xml/parse))) 44 | 45 | (defn get-problem [id] 46 | (try 47 | (->> (str base-url "/api/problem/" id) 48 | client/get 49 | :body 50 | json/read-json 51 | (#(assoc % :id id))) 52 | (catch Exception e nil))) 53 | 54 | (defn fields-for-csv [problem] 55 | (map problem [:id :title :difficulty :description :tests])) 56 | 57 | (defn write-csv [file csv] 58 | (with-open [writer (io/writer file)] 59 | (csv/write-csv writer csv))) 60 | 61 | (defn write-problems-to-csv [] 62 | (->> (range 200) 63 | (map get-problem) 64 | (remove nil?) 65 | (map fields-for-csv) 66 | (write-csv problems-file))) 67 | 68 | (defn login [login password] 69 | (->> (client/post 70 | (str base-url "login") 71 | {:form-params {:user login :pwd password}}) 72 | :cookies)) 73 | 74 | 75 | (defn extract-solution [sol] 76 | {:user (-> (html/select sol [:.solution-username]) first html/text string/lower-case (string/replace #"'s solution:" "")) 77 | :solution (-> (html/select sol [:pre]) first html/text)}) 78 | 79 | (defn get-solutions [problem name cookies] 80 | (let [html (-> (client/get 81 | (str base-url "/problem/solutions/" problem) 82 | {:cookies cookies}) 83 | :body 84 | string-to-html) 85 | following-solutions (map extract-solution (html/select html [:.follower-solution])) 86 | my-solution {:user name 87 | :solution (-> (html/select html [[:pre html/first-of-type]] ) first html/text)}] 88 | (cons my-solution following-solutions))) 89 | 90 | (defn build-content [problem solutions] 91 | (let [{:keys [description tests]} (get-problem problem)] 92 | (->> (map #(str ";" (:user %) \newline (:solution %) \newline \newline) solutions) 93 | (string/join \newline) 94 | (str ";" description \newline 95 | (string/join \newline tests) 96 | \newline \newline \newline) 97 | (apply str) 98 | (hash-map (format solutions-file problem))))) 99 | 100 | (defn write-solutions-to-file [problem solutions] 101 | (spit (format solutions-file problem) (build-content problem solutions))) 102 | 103 | (defn get-solutions-filter [problem logn password users] 104 | (->> (login logn password) 105 | (get-solutions problem logn) 106 | (filter #(users (:user %))))) 107 | 108 | (defn get-solutions-as-file 109 | ([problem logn password users] 110 | (build-content problem (get-solutions-filter problem logn password users))) 111 | ([problem logn password] 112 | (get-solutions-as-file problem logn password (fn [_] true)))) 113 | 114 | (defn find-gist [gist-name auth] 115 | (->> (gists/user-gists (re-find #"[^:]*" auth) {:auth auth}) 116 | (filter #(.contains (:description %) gist-name)) 117 | first)) 118 | 119 | (defn map-values [f m] 120 | (into {} (for [[k v] m] [k (f k v)]))) 121 | 122 | (defn write-solutions-to-gist [{:keys [problems users github-auth gist-name login-4clj password-4clj]}] 123 | (let [solutions (into {} (pmap #(get-solutions-as-file % login-4clj password-4clj users) problems))] 124 | (do 125 | (if-let [gist (find-gist gist-name github-auth)] 126 | (let [solutions (map-values #(hash-map :content %2) solutions)] 127 | (gists/edit-gist (:id gist) {:auth github-auth :files solutions})) 128 | (gists/create-gist solutions {:auth github-auth :description gist-name :public false})) 129 | nil))) 130 | 131 | (defn update-lesson [tasks name github-pass fclj-pass] 132 | (write-solutions-to-gist 133 | {:problems tasks 134 | :users users 135 | :github-auth (format "nbeloglazov:%s" github-pass) 136 | :gist-name name 137 | :login-4clj "nikelandjelo" 138 | :password-4clj fclj-pass})) 139 | 140 | (defn update-lesson-2 [github-pass fclj-pass] 141 | (update-lesson lesson-2 "Lesson 2" github-pass fclj-pass)) 142 | 143 | (defn update-lesson-3 [github-pass fclj-pass] 144 | (update-lesson lesson-3 "Lesson 3" github-pass fclj-pass)) 145 | 146 | (defn update-lesson-6 [github-pass fclj-pass] 147 | (update-lesson lesson-6 "Lesson 6" github-pass fclj-pass)) 148 | 149 | (defn update-lesson-7 [github-pass fclj-pass] 150 | (update-lesson lesson-7 "Lesson 7" github-pass fclj-pass)) 151 | 152 | (defn update-all-lessons [github-pass fclj-pass] 153 | (doseq [fns [update-lesson-2 update-lesson-3 update-lesson-6 update-lesson-7]] 154 | (println "Do!") 155 | (fns github-pass fclj-pass))) 156 | 157 | (defn get-scores [fclj-name fclj-pass & task-colls] 158 | (letfn [(users-for-problem [problem] 159 | (let [users (map :user (get-solutions-filter problem fclj-name fclj-pass users))] 160 | (zipmap users (repeat #{problem})))) 161 | (map-value [f m] 162 | (into {} (for [[k v] m] [k (f v)]))) 163 | (count-intersections [tasks] 164 | (->> (map set task-colls) 165 | (map #(set/intersection % tasks)) 166 | (map count)))] 167 | (->> (apply concat task-colls) 168 | (pmap users-for-problem) 169 | (apply merge-with set/union) 170 | (map-value count-intersections)))) 171 | 172 | (defn write-scores [fclj-name fclj-pass & task-colls] 173 | (let [data (read-string (slurp scores-file)) 174 | new-scores (apply get-scores fclj-name fclj-pass task-colls)] 175 | (->> (conj data [new-scores (java.util.Date.)]) 176 | prn-str 177 | (spit scores-file)))) 178 | 179 | (defn show-difference-last [] 180 | (let [all (read-string (slurp scores-file)) 181 | [latest prev] (map first (reverse all)) 182 | names (set (concat (keys latest) (keys prev)))] 183 | (doseq [name (sort names)] 184 | (when (not= (latest name) (prev name)) 185 | (println name) 186 | (println (prev name)) 187 | (println (latest name)) 188 | (println \newline))))) 189 | 190 | -------------------------------------------------------------------------------- /misc/images/1_artillery_plane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/1_artillery_plane.png -------------------------------------------------------------------------------- /misc/images/1_artillery_ufo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/1_artillery_ufo.png -------------------------------------------------------------------------------- /misc/images/2_snake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/2_snake.png -------------------------------------------------------------------------------- /misc/images/2_snake_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/2_snake_small.png -------------------------------------------------------------------------------- /misc/images/3_durak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/3_durak.png -------------------------------------------------------------------------------- /misc/images/3_durak_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/3_durak_small.png -------------------------------------------------------------------------------- /misc/images/4_cellular_automaton_ant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/4_cellular_automaton_ant.png -------------------------------------------------------------------------------- /misc/images/4_cellular_automaton_life.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/4_cellular_automaton_life.png -------------------------------------------------------------------------------- /misc/images/4_cellular_automaton_wireworld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/4_cellular_automaton_wireworld.png -------------------------------------------------------------------------------- /misc/images/4_cellular_automaton_wireworld_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/4_cellular_automaton_wireworld_small.png -------------------------------------------------------------------------------- /misc/images/5_k_means.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/5_k_means.png -------------------------------------------------------------------------------- /misc/images/6_derivative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/6_derivative.png -------------------------------------------------------------------------------- /misc/images/6_derivative_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbeloglazov/clojure-interactive-tasks/560fd5b8d3abb5dd3af88fa72cb16bf463d9b4c2/misc/images/6_derivative_small.png -------------------------------------------------------------------------------- /misc/qtut/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /lib 3 | /classes 4 | /checkouts 5 | pom.xml 6 | *.jar 7 | *.class 8 | .lein-deps-sum 9 | .lein-failures 10 | .lein-plugins -------------------------------------------------------------------------------- /misc/qtut/README.md: -------------------------------------------------------------------------------- 1 | # qtut 2 | 3 | A Leiningen template for FIXME. 4 | 5 | ## Usage 6 | 7 | FIXME 8 | 9 | ## License 10 | 11 | Copyright © 2012 FIXME 12 | 13 | Distributed under the Eclipse Public License, the same as Clojure. 14 | -------------------------------------------------------------------------------- /misc/qtut/project.clj: -------------------------------------------------------------------------------- 1 | (defproject qtut/lein-template "0.1.0" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html"} 6 | :eval-in-leiningen true) -------------------------------------------------------------------------------- /misc/qtut/src/leiningen/new/qtut.clj: -------------------------------------------------------------------------------- 1 | (ns leiningen.new.qtut 2 | (:use [leiningen.new.templates :only [renderer name-to-path ->files]])) 3 | 4 | (def render (renderer "qtut")) 5 | 6 | (defn qtut 7 | "FIXME: write documentation" 8 | [name] 9 | (let [data {:name name 10 | :sanitized (name-to-path name)}] 11 | (->files data 12 | ["src/{{sanitized}}/core.clj" (render "core.clj" data)] 13 | ["src/{{sanitized}}/work.clj" (render "work.clj" data)] 14 | ["project.clj" (render "project.clj" data)]))) 15 | -------------------------------------------------------------------------------- /misc/qtut/src/leiningen/new/qtut/core.clj: -------------------------------------------------------------------------------- 1 | (ns {{name}}.core 2 | (:use quil.core)) 3 | 4 | (def initial-state {:iteration (atom 0)}) 5 | 6 | (defmacro fn-state [vars & body] 7 | `(fn [] (let ~(vec (apply concat 8 | (for [var vars] 9 | [var `(state ~(keyword var))]))) 10 | ~@body))) 11 | 12 | (defn setup [] 13 | (smooth) 14 | (apply set-state! (flatten (seq initial-state))) 15 | (frame-rate 10)) 16 | 17 | (defn update-fn [solution] 18 | (fn-state [iteration] 19 | (swap! iteration + (solution)))) 20 | 21 | (def draw 22 | (fn-state [iteration] 23 | (background 200) 24 | (fill 0) 25 | (ellipse @iteration @iteration 10 10))) 26 | 27 | 28 | (defn run [solution] 29 | (let [update (update-fn solution)] 30 | (sketch 31 | :title "{{name}}" 32 | :setup setup 33 | :draw #(do (update) (draw)) 34 | :size [800 600]))) 35 | 36 | -------------------------------------------------------------------------------- /misc/qtut/src/leiningen/new/qtut/project.clj: -------------------------------------------------------------------------------- 1 | (defproject {{name}} "0.1.0-SNAPSHOT" 2 | :dependencies [[org.clojure/clojure "1.4.0"] 3 | [quil/quil "1.6.0"]]) 4 | -------------------------------------------------------------------------------- /misc/qtut/src/leiningen/new/qtut/work.clj: -------------------------------------------------------------------------------- 1 | (ns {{name}}.work 2 | (:use {{name}}.core)) 3 | 4 | (defn solution [] 5 | 1) 6 | 7 | (defn -main [& args] 8 | (run solution)) 9 | --------------------------------------------------------------------------------