Skip to content

Instantly share code, notes, and snippets.

@orestis
Last active January 2, 2018 16:39
Show Gist options
  • Select an option

  • Save orestis/58cec3973607019689397388b1dcccd8 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
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