public
Created

  • Download Gist
core.clj
Clojure
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
;;; In all its on-the-day gory glory. I will admit to being
;;; /slightly/ on the seedy side... Most of these solutions,
;;; particularly problems 3 and 4, are brute-forced and I'm pretty
;;; sure can be more solved much more efficiently. I'll have a stab
;;; later, but this is all I got up to (I was starting to look at
;;; seesaw for a game-of-life GUI, but as you can see didn't get too
;;; far)
;;;
;;; Thanks everyone! It was great to see so many people passionate
;;; about Clojure, and I'm really greatful to Logaan and all the
;;; organisers for putting this on.
;;; Mark (Hepburn)
 
(ns clj-meetup.core
(:use clojure.test
seesaw.color
seesaw.core
seesaw.dev
seesaw.graphics)
(:require [clojure.string :as string]
[clojure.math.combinatorics :as combo]))
 
 
;;; multiples of 3 and 5
(defn problem1 [upto]
(->> (range)
(take upto)
(filter #(or (zero? (mod % 3)) (zero? (mod % 5))))
(reduce +)))
(comment
(problem1 1000) ; => 233168
)
 
(deftest test-prob1
(is (= 23 (problem1 10)))
(is (= 233168 (problem1 1000))))
 
 
 
;;; even fibonacci numbers
 
(defn fib [x y]
(cons x (lazy-seq y (fib y (+ x y)))))
 
(defn problem2 [upper-bound]
(->> (fib 1 2)
(take-while #(< % upper-bound))
(filter #(even? %))
(reduce +)))
(comment
(problem2 4e6) ; => 4613732
)
 
(deftest test-prob2
(is (= (problem2 4e6) 4613732)))
 
 
;;; largest palindrome product
 
(defn is-palindrome? [num]
(let [sn (str num)]
(= (string/reverse sn) sn)))
 
(defn problem3 []
(first
(for [x (range 999 100 -1)
y (range 999 100 -1)
:let [prod (* x y)]
:when (is-palindrome? prod)]
prod)))
 
(deftest test-problem3
(testing "Check the (assumed) solution for the largest palindromic product;"
(testing "checking palindromicity of a number"
(is (= true (is-palindrome? 12321)))
(is (= true (is-palindrome? 3)))
(is (= false (is-palindrome? 1232))))
(testing "the main entry point"
(is (= 580085 (problem3))))))
 
 
;;; Smallest multiple
 
(defn div-by-all [num rng]
(every? zero? (map #(mod num %) rng)))
 
(defn problem4 [upper]
(let [rng (range 1 upper)
gub (reduce * rng)]
(->> (range upper gub)
(filter #(div-by-all % rng))
(first))))
(comment
(problem4 20) ; => 232792560
)
 
(deftest test-problem4
(is (= 2520 (problem4 10))))
 
 
;;; Game of life
 
(defn gen-neighbours [[x y :as coord]]
(let [nfn (juxt dec identity inc)]
(disj (set (combo/cartesian-product (nfn x) (nfn y)))
coord)))
 
(defn num-neighbours [coord board]
(count (remove nil? (map (gen-neighbours coord) board))))
 
(defn alive-now? [cell board]
(board cell))
 
(defn alive-next? [num-neighbours live?]
(or (and live?
(< 1 num-neighbours 4))
(and (not live?)
(= 3 num-neighbours))))
 
(defn game-of-life [board]
(let [board (set board)
tmpboard (reduce #(into %1 (gen-neighbours %2)) #{} board)]
(filter #(alive-next? (num-neighbours % board) (alive-now? % board)) tmpboard)))
 
(deftest test-gol
(testing "Testing all components of the game of life implementation;"
(testing "Generating neighbours"
(is (= #{[0 1] [0 2] [0 3] [1 1] [1 3] [2 1] [2 2] [2 3]}
(gen-neighbours [1 2]))))
(testing "Number of neighbours"
(is (= 2 (num-neighbours [2 2] #{[1 2] [2 2] [3 2]})))
(is (= 1 (num-neighbours [1 2] #{[1 2] [2 2] [3 2]}))))
(testing "The main entry point"
(is (= (game-of-life [[1 2] [2 2] [3 2]])
[[2 1] [2 2] [2 3]])))))
 
 
 
;;; GoL GUI:
(def *cell-pixels* 20)
 
 
 
(debug!)
 
(def *board* (atom #{}))
 
(defn paint-board [c g]
(let [w (.getWidth c)
h (.getHeight c)]
(doto g
(.setBackground (color :white))
(.setColor (color :black))
(.fillRect 0 0 (/ w 2) (/ h 2)))
(doseq [[x y] *board*]
)))
 
(defn -main [& args]
(invoke-later
(-> (frame :title "Game Of Life"
:content "Hello, Seesaw"
:on-close :exit)
pack!
show!)))

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.