Created
March 23, 2013 23:53
-
-
Save markhepburn/5229824 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; 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!))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment