typestar

Mandelbrot in ASCII in Mojo

The demo Mojo is known for - escape-time rendering, four columns at a time.

comptime F4 = SIMD[DType.float64, 4]
comptime I4 = SIMD[DType.int32, 4]
comptime WIDTH = 60
comptime HEIGHT = 24
comptime MAX_ITERS = 40


def escape_counts(cx: F4, cy: F4) -> I4:
    var zx = F4(0.0)
    var zy = F4(0.0)
    var counts = I4(0)
    for _ in range(MAX_ITERS):
        var alive = (zx * zx + zy * zy).le(F4(4.0))
        if not alive.reduce_or():
            break
        counts += alive.select(I4(1), I4(0))
        var next_x = zx * zx - zy * zy + cx
        zy = 2.0 * zx * zy + cy
        zx = next_x
    return counts


def main():
    var shades: List[String] = [" ", ".", ":", "-", "=", "+", "*", "#", "@"]
    var levels = len(shades) - 1
    for row in range(HEIGHT):
        var cy = F4(-1.2 + 2.4 * Float64(row) / Float64(HEIGHT))
        var line = String()
        for block in range(0, WIDTH, 4):
            var cx = F4(0.0)
            for lane in range(4):
                var column = Float64(block + lane)
                cx[lane] = -2.2 + 3.0 * column / Float64(WIDTH)
            var counts = escape_counts(cx, cy)
            for lane in range(4):
                line += shades[Int(counts[lane]) * levels // MAX_ITERS]
        print(line)

How it works

  1. escape_counts iterates z = z * z + c on four points in parallel.
  2. A mask counts only the lanes still alive, and breaks once all have escaped.
  3. Each count picks a shade character, drawing a 60 by 24 grid.

Keywords and builtins used here

The run, in numbers

Lines
37
Characters to type
957
Tokens
318
Three-star pace
65 tpm

At the three-star pace of 65 tokens a minute, this run takes about 294 seconds.

Type this snippet

Step 1 of 2 in Encore, step 21 of 22 in Parameters & SIMD.

← Previous Next →