Recho

DocsExamplesSketches
Bairui Su
Bairui Su/Running Race
Created 2025-09-09
//โžœ                                    ๐ŸŒ๐Ÿ’จ
//โžœ                                   ๐Ÿข๐Ÿ’จ
//โžœ                              ๐Ÿšถโ€โ™‚๏ธ๐Ÿ’จ
//โžœ                     ๐Ÿš—๐Ÿ’จ
//โžœ           ๐Ÿš€๐Ÿ’จ
{
  const x = (count) => 40 - (count % 40);
  echo("๐ŸŒ๐Ÿ’จ".padStart(x(snail)), {quote: false});
  echo("๐Ÿข๐Ÿ’จ".padStart(x(turtle)), {quote: false});
  echo("๐Ÿšถโ€โ™‚๏ธ๐Ÿ’จ".padStart(x(human)), {quote: false});
  echo("๐Ÿš—๐Ÿ’จ".padStart(x(car)), {quote: false});
  echo("๐Ÿš€๐Ÿ’จ".padStart(x(rocket)), {quote: false});
}
Bairui Su
Bairui Su/Matrix Rain
Created 2025-08-22
//โžœ              w       $  R        |       @      2         !
//โžœ        j     M          &        C              m        ,
//โžœ         _#   D          9 z      L         ?    Z=
//โžœ         !d   `          [        *         g    g     3
//โžœ         t|   [      -  BS  E     k e      u<    J :  o6      j
//โžœ         I*   !      j  R$ p7     p I&D    k,      j  ?1      M
//โžœ      k  j#   W O D  (      ,   > a s#     XY   9' .  XK y    )
//โžœ      a  $\  *n [B   W  W   F    6[ w>  R  AOL   p j  _B U    Z
//โžœ      X  /1     NX9  K      ~     7  Z /u  b_    o H ,:u=$    6
//โžœ    Btb* rE a    yD  i    n ^     ks , S!  |?      &  ?$ l    a
//โžœ    $ 3  @  y    ro  9       b    Oh ! I-  ^7      x  =t     X
//โžœ    8 n  <  F    8ZG -       +    8i 2 .j  j       bx ,tf     G
//โžœ    _ 8  t  3    GH& T u           S K y   M   !   Ln 45Y   K L
//โžœ    }    d  ca   @ h   4           T 7 6   T   (   !y_hx7   P r
//โžœ    u    i  /    FH0   =      K    v P     `   e   <[ XjD  <6 u
//โžœ   M%    V  {    vg    |      V    4 q     7 [ R   ;   [@  =; \
//โžœ    R       y    [:    }      ) `v S       [ %     /   g-  u= 3
//โžœ    g       $    UH    g      & rD @       b H     =    o  4+ R
//โžœ    9       g    96           W c  ~         t          *  mq
//โžœ            ;    vI           )    p          \             M
//โžœ            )    wc           A                 ~
//โžœ                  d           _          =      D
//โžœ                  `           ~          q      #
//โžœ                  |           m                 e
//โžœ                  e           W                 ^
{
  frame;

  // Create a new buffer.
  const buffer = d3.range(width * height).map(() => " ");

  // Update all columns.
  for (let i = columns.length - 1; i >= 0; --i) {
    const column = columns[i];
    const {lifespan, length, chars} = column;
    const n = chars.length;
    if (lifespan < 0) columns[i] = createColumn(height);
    else if (lifespan <= n) chars[n - lifespan] = " ";
    else {
      for (let j = length - 1; j < n; ++j) chars[j] = randomChar();
      chars.push(randomChar());
    }
    column.lifespan -= 1;
  }

  // Update the buffer.
  for (let i = 0; i < columns.length; ++i) {
    const column = columns[i];
    const {y, chars} = column;
    for (let j = 0; j < chars.length; ++j) buffer[(y + j) * width + i] = chars[j];
  }

  // Render the buffer.
  let output = "";
  for (let i = 0; i < height; ++i) {
    for (let j = 0; j < width; ++j) output += buffer[i * width + j];
    output += i === height - 1 ? "" : "\n";
  }
  output = output.split("\n").map((d) => "  " + d).join("\n");

  echo(output);
}

function createColumn(height) {
  const lifespan = d3.randomInt(height)();
  const length = d3.randomInt(lifespan)();
  const chars = d3.range(length).map(randomChar);
  const y = d3.randomInt(0, 10)();
  return {lifespan, chars, y};
}

function randomChar() {
  return String.fromCharCode(d3.randomInt(32, 127)());
}

const frame = recho.interval(1000 / 15);

const d3 = recho.require("d3");
Bairui Su
Created 2025-08-22
//โžœ          โ–ˆ
//โžœ       โ–ˆ  โ–ˆ          โ–ˆ  โ–ˆ                    โ–ˆโ–ˆ
//โžœ       โ–ˆ  โ–ˆ  โ–ˆ โ–ˆ     โ–ˆ  โ–ˆ          โ–ˆ         โ–ˆโ–ˆ
//โžœ   โ–ˆ โ–ˆ โ–ˆโ–ˆ โ–ˆ  โ–ˆ โ–ˆโ–ˆ    โ–ˆ  โ–ˆ  โ–ˆโ–ˆโ–ˆ     โ–ˆ       โ–ˆ โ–ˆโ–ˆ
//โžœ  โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆ โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆ    โ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆ โ–ˆโ–ˆ  โ–ˆโ–ˆ
//โžœ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ
//โžœ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ
//โžœ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
{
  let output = "";
  for (let i = 0; i < height; i++) {
    for (let j = 0; j < width; j++) {
      const bin = bins[j];
      const h = bin ? (bin * height) / d3.max(bins) : 0;
      output += h >= height - i ? "โ–ˆ" : " ";
    }
    output += i === height - 1 ? "" : "\n";
  }
  echo(output);
}
Bairui Su
Bairui Su/Mandelbrot Set
Created 2025-08-21
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*OoO@@@@@@@@@@@@@@@@@@@*ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@@@@@@@@@@@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@@@@@@@@@@@@@@@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@ยทO@**ยทยทยทยท*@@@@@@@@@@@@@@@@@@@@@@@@Oยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*@@@@@@@@ยทยท@@@@@@@@@@@@@@@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@@@@oยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*o*@@@@@@@@@@@o@@@@@@@@@@@@@@@@@@@@@@@@oยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยท@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*o*@@@@@@@@@@@o@@@@@@@@@@@@@@@@@@@@@@@@oยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@@@@oยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*@@@@@@@@ยทยท@@@@@@@@@@@@@@@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@ยทO@**ยทยทยทยท*@@@@@@@@@@@@@@@@@@@@@@@@Oยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@@@@@@@@@@@@@@@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@@@@@@@@@@@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท*OoO@@@@@@@@@@@@@@@@@@@*ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@@@@@@@@@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@@ยท*@@@@@@@@@@@@ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท@ยทยทยทยทยทยทยท@@@*ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทO@@@@*ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทo@@@@*ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทO@ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
//โžœ ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท
{
  let output = "";
  for (let y = 0; y < rows; y++) {
    for (let x = 0; x < cols; x++) {
      const re = map(x, 0, cols, -2.5, 1);
      const im = map(y, 0, rows, -1, 1);
      let [a, b, i] = [0, 0, 0];
      while (i < maxIter) {
        [a, b] = [a * a - b * b + re, 2 * a * b + im];
        if (a * a + b * b > 4) break;
        i++;
      }
      const index = ~~((i / maxIter) * (colors.length - 1));
      output += colors[index];
    }
    output += y === rows - 1 ? "" : "\n";
  }
  echo(output);
}

function map(x, d0, d1, r0, r1) {
  return r0 + ((r1 - r0) * (x - d0)) / (d1 - d0);
}

/**
 * Again, you don't need to completely understand the code above for now. If
 * you find textual outputs can be interesting and creative by this example,
 * that's the point!
 *
 * If you're really curious about Mandelbrot set, here are some examples that
 * I made with Charming.js[2] you may find interesting:
 *
 * - Multibrot Set: https://observablehq.com/d/fc2cfd9ae9e7524c
 * - Multibrot Set Table: https://observablehq.com/d/3028c0d5655345e3
 * - Multibrot Set Transition: https://observablehq.com/d/c040d3db33c0033e
 * - Zoomable Mandelbrot Set (Canvas): https://observablehq.com/d/2e5bdd2365236c2d
 * - Zoomable Mandelbrot Set (WebGL): https://observablehq.com/d/cfe263c1213334e3
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *                              References
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * [1] https://en.wikipedia.org/wiki/Mandelbrot_set
 * [2] https://charmingjs.org/
 */