Skip to content

Instantly share code, notes, and snippets.

@markhepburn
Created March 23, 2013 23:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markhepburn/5229824 to your computer and use it in GitHub Desktop.
Save markhepburn/5229824 to your computer and use it in GitHub Desktop.
;;; 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