Skip to content

Instantly share code, notes, and snippets.

@swannodette
Created June 10, 2010 16:00
Show Gist options
  • Save swannodette/433208 to your computer and use it in GitHub Desktop.
Save swannodette/433208 to your computer and use it in GitHub Desktop.
(ns cellular-automata-basic)
(defrecord cellular-automaton [^long nrows ^long ncols data-vector])
(defn random-ca
[nrows ncols n]
(cellular-automaton.
nrows
ncols
(let [a (longs (make-array Long/TYPE (* nrows ncols)))]
(amap a i result
(aset result i (long (rand-int 2)))))))
(defn update-ca [ca update-rule]
(let [{nrows :nrows ncols :ncols dv :data-vector} ca
nrows (long nrows)
ncols (long ncols)
dv (longs dv)]
(assoc ca :data-vector
(amap dv idx result
(let [i (unchecked-remainder idx ncols)
j (if (= idx (long 0)) 0 (unchecked-divide idx ncols))]
(aset result idx (long (update-rule dv i j ncols nrows))))))))
(defmacro get-ca
[data-vector i j ncols]
`(aget ~data-vector (+ (* ~i ~ncols) ~j)))
(defmacro fast-int-array [& rest]
(let [vsym (gensym "v")]
`(let [~vsym (longs (make-array Long/TYPE 8))]
~@(map-indexed (fn [i x] `(aset ~vsym ~i ~x)) rest)
~vsym)))
(defn ^:static sum-8-neighbors ^long [dv ^long i ^long j ^long ncols]
(let [dv (longs dv)
v (longs (fast-int-array
(get-ca dv (dec i) (dec j) ncols)
(get-ca dv (dec i) j ncols)
(get-ca dv (dec i) (inc j) ncols)
(get-ca dv i (inc j) ncols)
(get-ca dv (inc i) (inc j) ncols)
(get-ca dv (inc i) j ncols)
(get-ca dv (inc i) (dec j) ncols)
(get-ca dv i (dec j) ncols)))]
(areduce v i sum (int 0)
(+ sum (int (aget v i))))))
(comment
(defn ^:static sum-8-neighbors ^long [dv ^long i ^long j ^long ncols]
(let [dv (longs dv)
v (make-array Integer/TYPE 10)]
(areduce v i sum (int 0)
(+ sum (int (aget v i))))))
)
(defn ur-8neigh-minmax [dv i j others ncols nrows]
(let [ncols (longs ncols)
nrows (longs nrows)
i (longs i)
j (longs j)
dv (longs dv)]
(if (or (= i (dec nrows)) (zero? i) (= j (dec ncols)) (zero? j))
(get-ca dv i j ncols)
(let [sum (sum-8-neighbors dv i j ncols)]
(if (and (>= sum (int (nth others 0))) (<= sum (int (nth others 1))))
(nth others 2)
(get-ca dv i j ncols))
(get-ca dv i j ncols)))))
(def a (random-ca 2000 2000 1))
(def b (random-ca 500 500 1))
(comment
(dotimes [_ 10]
(time
(dotimes [_ 1]
(update-ca a #(ur-8neigh-minmax %1 %2 %3 [2 5 1] %4 %5)))))
(dotimes [_ 10]
(time
(dotimes [_ 1]
(update-ca b #(ur-8neigh-minmax %1 %2 %3 [2 5 1] %4 %5)))))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment