Instantly share code, notes, and snippets.

markhepburn/core.clj Created Mar 23, 2013

What would you like to do?
 ;;; 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!)))