Skip to content

Instantly share code, notes, and snippets.

@orestis
Last active January 2, 2018 16:39
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 orestis/58cec3973607019689397388b1dcccd8 to your computer and use it in GitHub Desktop.
Save orestis/58cec3973607019689397388b1dcccd8 to your computer and use it in GitHub Desktop.
Elixir Streams in Clojure
;; Stream.iterate(0, &(&1 + 1))
;; |> Enum.take(5)
;; gives us [0, 1, 2, 3, 4]
(take 5 (iterate #(+ % 1) 0))
;; => (0 1 2 3 4)
;; Mandelbrot
;; defmodule Mandelbrot do
;; def sequence({cr, ci}) do
;; Stream.iterate({0, 0}, fn {r, i} ->
;; # z₂ = z₁² + c
;; {(r * r - i * i) + cr, (i * r + r * i) + ci}
;; end)
;; end
;; end
(defn mandelbrot-sequence [cr ci]
(iterate (fn [[r i]] [
(+ cr (- (* r r) (* i i)))
(+ ci (+ (* i r) (* r i)))
])
[0 0]))
;; bits taken from https://github.com/joni/fractals/blob/master/mandelbrot/MandelbrotColor.java
;; and https://github.com/juliangamble/clojure-ants-simulation/blob/master/src/ants.clj
(import
'(java.awt Color Graphics Dimension)
'(java.awt.image BufferedImage)
'(javax.swing JPanel JFrame))
(def WIDTH 800)
(def HEIGHT 800)
(def ITERS 1000)
(def colors (mapv (fn [i] (. Color (HSBtoRGB (/ i 256) 1 (/ i (+ i 8))))) (range ITERS)))
(defn pixel-color [col row]
(let [w2 (/ WIDTH 2.0)
w4 (/ 4.0 WIDTH)
h2 (/ HEIGHT 2.0)
cr (* w4 (- col w2))
ci (* w4 (- row h2))
iters (take ITERS (mandelbrot-sequence cr ci))
escaped (take-while (fn [[x y]] (<= (+ (* x x) (* y y)) 4.0)) iters)
iters-count (count escaped)
escaped? (= ITERS iters-count)
]
(if escaped? (. Color black) (new Color (get colors iters-count)))))
(defn render [g]
(let [img (new BufferedImage WIDTH HEIGHT
(. BufferedImage TYPE_INT_ARGB))
bg (. img (getGraphics))]
(doto bg
(.setColor (. Color red))
(.fillRect 0 0 (. img (getWidth)) (. img (getHeight))))
(dorun (for [x (range WIDTH) y (range HEIGHT)]
(doto bg
(.setColor (pixel-color x y))
(.fillRect x y 1 1))))
(. g (drawImage img 0 0 nil))
(. bg (dispose))))
(def panel (doto (proxy [JPanel] []
(paint [g] (render g)))
(.setPreferredSize (new Dimension
WIDTH
HEIGHT))))
(def frame (doto (new JFrame) (.add panel) .pack .show))
;; eval this as you change the code to see the effects
(. panel (repaint))
;; Stream.unfold({0, 1}, fn {a, b} -> {a, {b, a + b}} end)
;; [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
(defn unfold [acc fn-next]
(let [fn' (fn [[_ acc]] (fn-next acc))
s (take-while (complement nil?) (rest (iterate fn' [nil acc])))]
(map first s)))
(take 10 (unfold [0 1] (fn [[a b]] [a [b (+ a b)]])))
;; => (0 1 1 2 3 5 8 13 21 34)
;; Stream.unfold(5, fn 0 -> nil; n -> {n, n-1} end) |> Enum.to_list()
(unfold 5 (fn [x] (if (zero? x) nil [x (dec x)])))
;; => (5 4 3 2 1)
@orestis
Copy link
Author

orestis commented Jan 2, 2018

mandelbrot drawing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment