I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Cistercian numerals

Cistercian numerals
You are encouraged to solve this task according to the task description, using any language you may know.

Cistercian numerals were used across Europe by Cistercian monks during the Late Medieval Period as an alternative to Roman numerals. They were used to represent base 10 integers from 0 to 9999.

How they work

All Cistercian numerals begin with a vertical line segment, which by itself represents the number 0. Then, glyphs representing the digits 1 through 9 are optionally added to the four quadrants surrounding the vertical line segment. These glyphs are drawn with vertical and horizontal symmetry about the initial line segment. Each quadrant corresponds to a digit place in the number:

• The upper-right quadrant represents the ones place.
• The upper-left quadrant represents the tens place.
• The lower-right quadrant represents the hundreds place.
• The lower-left quadrant represents the thousands place.

Please consult the following image for examples of Cistercian numerals showing each glyph: [1]

• Write a function/procedure/routine to display any given Cistercian numeral. This could be done by drawing to the display, creating an image, or even as text (as long as it is a reasonable facsimile).
• Use the routine to show the following Cistercian numerals:
• 0
• 1
• 20
• 300
• 4000
• 5555
• 6789
• And a number of your choice!
Notes

Due to the inability to upload images to Rosetta Code as of this task's creation, showing output here on this page is not required. However, it is welcomed — especially for text output.

## AWK

` # syntax: GAWK -f CISTERCIAN_NUMERALS.AWK [-v debug={0|1}] [-v xc=anychar] numbers 0-9999 ...## example: GAWK -f CISTERCIAN_NUMERALS.AWK 0 1 20 300 4000 5555 6789 1995 10000## sorting:#   PROCINFO["sorted_in"] is used by GAWK#   SORTTYPE is used by Thompson Automation's TAWK#BEGIN {    cistercian_init()    for (i=1; i<=ARGC-1; i++) {      cistercian1(ARGV[i])    }    exit(0)}function cistercian1(n,  i) {    printf("\n%6s\n",n)    if (!(n ~ /^[0-9]+\$/ && length(n) <= 4)) {      print("invalid")      return    }    n = sprintf("%04d",n)    cistercian2(2,1,substr(n,3,1),substr(n,4,1))    for (i=1; i<=5; i++) { # separator between upper and lower parts      printf("%5s%1s%5s\n","",xc,"")    }    cistercian2(4,3,substr(n,1,1),substr(n,2,1))}function cistercian2(i1,i2,n1,n2,  i,L,R) {    for (i=1; i<=5; i++) {      L = substr(cn_arr[i1][i],n1*6+2,5)      R = substr(cn_arr[i2][i],n2*6+2,5)      printf("%5s%1s%5s\n",L,xc,R)    }}function cistercian_init(  header,i,j,LL,LR,UL,UR) {# 1-9 upper-right    cn_arr[1][++UR] = ":xxxxx:     :x    :    x:xxxxx:    x:xxxxx:    x:xxxxx:"    cn_arr[1][++UR] = ":     :     : x   :   x :   x :    x:    x:    x:    x:"    cn_arr[1][++UR] = ":     :     :  x  :  x  :  x  :    x:    x:    x:    x:"    cn_arr[1][++UR] = ":     :     :   x : x   : x   :    x:    x:    x:    x:"    cn_arr[1][++UR] = ":     :xxxxx:    x:x    :x    :    x:    x:xxxxx:xxxxx:"# 10-90 upper-left    cn_arr[2][++UL] = ":xxxxx:     :    x:x    :xxxxx:x    :xxxxx:x    :xxxxx:"    cn_arr[2][++UL] = ":     :     :   x : x   : x   :x    :x    :x    :x    :"    cn_arr[2][++UL] = ":     :     :  x  :  x  :  x  :x    :x    :x    :x    :"    cn_arr[2][++UL] = ":     :     : x   :   x :   x :x    :x    :x    :x    :"    cn_arr[2][++UL] = ":     :xxxxx:x    :    x:    x:x    :x    :xxxxx:xxxxx:"# 100-900 lower-right    cn_arr[3][++LR] = ":     :xxxxx:    x:x    :x    :    x:    x:xxxxx:xxxxx:"    cn_arr[3][++LR] = ":     :     :   x : x   : x   :    x:    x:    x:    x:"    cn_arr[3][++LR] = ":     :     :  x  :  x  :  x  :    x:    x:    x:    x:"    cn_arr[3][++LR] = ":     :     : x   :   x :   x :    x:    x:    x:    x:"    cn_arr[3][++LR] = ":xxxxx:     :x    :    x:xxxxx:    x:xxxxx:    x:xxxxx:"# 1000-9000 lower-left    cn_arr[4][++LL] = ":     :xxxxx:x    :    x:    x:x    :x    :xxxxx:xxxxx:"    cn_arr[4][++LL] = ":     :     : x   :   x :   x :x    :x    :x    :x    :"    cn_arr[4][++LL] = ":     :     :  x  :  x  :  x  :x    :x    :x    :x    :"    cn_arr[4][++LL] = ":     :     :   x : x   : x   :x    :x    :x    :x    :"    cn_arr[4][++LL] = ":xxxxx:     :    x:x    :xxxxx:x    :xxxxx:x    :xxxxx:"    header =    ":00000:11111:22222:33333:44444:55555:66666:77777:88888:99999:"    PROCINFO["sorted_in"] = "@ind_str_asc" ; SORTTYPE = 1    sub(/^ +/,"",xc)    xc = (xc == "") ? "x" : substr(xc,1,1) # substitution character    for (i in cn_arr) {      for (j in cn_arr[i]) {        gsub(/x/,xc,cn_arr[i][j]) # change "x" to substitution character        cn_arr[i][j] = sprintf(":%5s%s","",cn_arr[i][j]) # add zero column to table        if (debug == 1) { printf("%s %2s %d.%d\n",cn_arr[i][j],substr("URULLRLL",i*2-1,2),i,j) }      }    }    if (debug == 1) { printf("%s\n",header) }} `
Output:
```     0
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x
x    xxxxxx

1995
xxxxxxxxxxx
x    x   x
x    x  x
x    x x
xxxxxxx
x
x
x
x
x
xxxxxx
x    x
x    x
x    x
xxxxxxxxxxx

10000
invalid
```

## C

Translation of: C#
`#include <stdio.h> #define GRID_SIZE 15char canvas[GRID_SIZE][GRID_SIZE]; void initN() {    int i, j;    for (i = 0; i < GRID_SIZE; i++) {        for (j = 0; j < GRID_SIZE; j++) {            canvas[i][j] = ' ';        }        canvas[i][5] = 'x';    }} void horizontal(size_t c1, size_t c2, size_t r) {    size_t c;    for (c = c1; c <= c2; c++) {        canvas[r][c] = 'x';    }} void vertical(size_t r1, size_t r2, size_t c) {    size_t r;    for (r = r1; r <= r2; r++) {        canvas[r][c] = 'x';    }} void diagd(size_t c1, size_t c2, size_t r) {    size_t c;    for (c = c1; c <= c2; c++) {        canvas[r + c - c1][c] = 'x';    }} void diagu(size_t c1, size_t c2, size_t r) {    size_t c;    for (c = c1; c <= c2; c++) {        canvas[r - c + c1][c] = 'x';    }} void drawOnes(int v) {    switch (v) {    case 1:        horizontal(6, 10, 0);        break;    case 2:        horizontal(6, 10, 4);        break;    case 3:        diagd(6, 10, 0);        break;    case 4:        diagu(6, 10, 4);        break;    case 5:        drawOnes(1);        drawOnes(4);        break;    case 6:        vertical(0, 4, 10);        break;    case 7:        drawOnes(1);        drawOnes(6);        break;    case 8:        drawOnes(2);        drawOnes(6);        break;    case 9:        drawOnes(1);        drawOnes(8);        break;    default:        break;    }} void drawTens(int v) {    switch (v) {    case 1:        horizontal(0, 4, 0);        break;    case 2:        horizontal(0, 4, 4);        break;    case 3:        diagu(0, 4, 4);        break;    case 4:        diagd(0, 4, 0);        break;    case 5:        drawTens(1);        drawTens(4);        break;    case 6:        vertical(0, 4, 0);        break;    case 7:        drawTens(1);        drawTens(6);        break;    case 8:        drawTens(2);        drawTens(6);        break;    case 9:        drawTens(1);        drawTens(8);        break;    default:        break;    }} void drawHundreds(int hundreds) {    switch (hundreds) {    case 1:        horizontal(6, 10, 14);        break;    case 2:        horizontal(6, 10, 10);        break;    case 3:        diagu(6, 10, 14);        break;    case 4:        diagd(6, 10, 10);        break;    case 5:        drawHundreds(1);        drawHundreds(4);        break;    case 6:        vertical(10, 14, 10);        break;    case 7:        drawHundreds(1);        drawHundreds(6);        break;    case 8:        drawHundreds(2);        drawHundreds(6);        break;    case 9:        drawHundreds(1);        drawHundreds(8);        break;    default:        break;    }} void drawThousands(int thousands) {    switch (thousands) {    case 1:        horizontal(0, 4, 14);        break;    case 2:        horizontal(0, 4, 10);        break;    case 3:        diagd(0, 4, 10);        break;    case 4:        diagu(0, 4, 14);        break;    case 5:        drawThousands(1);        drawThousands(4);        break;    case 6:        vertical(10, 14, 0);        break;    case 7:        drawThousands(1);        drawThousands(6);        break;    case 8:        drawThousands(2);        drawThousands(6);        break;    case 9:        drawThousands(1);        drawThousands(8);        break;    default:        break;    }} void draw(int v) {    int thousands = v / 1000;    v %= 1000;     int hundreds = v / 100;    v %= 100;     int tens = v / 10;    int ones = v % 10;     if (thousands > 0) {        drawThousands(thousands);    }    if (hundreds > 0) {        drawHundreds(hundreds);    }    if (tens > 0) {        drawTens(tens);    }    if (ones > 0) {        drawOnes(ones);    }} void write(FILE *out) {    int i;    for (i = 0; i < GRID_SIZE; i++) {        fprintf(out, "%-.*s", GRID_SIZE, canvas[i]);        putc('\n', out);    }} void test(int n) {    printf("%d:\n", n);    initN();    draw(n);    write(stdout);    printf("\n\n");} int main() {    test(0);    test(1);    test(20);    test(300);    test(4000);    test(5555);    test(6789);    test(9999);     return 0;}`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000:
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555:
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789:
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x
x    xxxxxx

9999:
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx```

## C++

Translation of: Go
`#include <array>#include <iostream> template<typename T, size_t S>using FixedSquareGrid = std::array<std::array<T, S>, S>; struct Cistercian {public:    Cistercian() {        initN();    }     Cistercian(int v) {        initN();        draw(v);    }     Cistercian &operator=(int v) {        initN();        draw(v);    }     friend std::ostream &operator<<(std::ostream &, const Cistercian &); private:    FixedSquareGrid<char, 15> canvas;     void initN() {        for (auto &row : canvas) {            row.fill(' ');            row[5] = 'x';        }    }     void horizontal(size_t c1, size_t c2, size_t r) {        for (size_t c = c1; c <= c2; c++) {            canvas[r][c] = 'x';        }    }     void vertical(size_t r1, size_t r2, size_t c) {        for (size_t r = r1; r <= r2; r++) {            canvas[r][c] = 'x';        }    }     void diagd(size_t c1, size_t c2, size_t r) {        for (size_t c = c1; c <= c2; c++) {            canvas[r + c - c1][c] = 'x';        }    }     void diagu(size_t c1, size_t c2, size_t r) {        for (size_t c = c1; c <= c2; c++) {            canvas[r - c + c1][c] = 'x';        }    }     void drawOnes(int v) {        switch (v) {        case 1:            horizontal(6, 10, 0);            break;        case 2:            horizontal(6, 10, 4);            break;        case 3:            diagd(6, 10, 0);            break;        case 4:            diagu(6, 10, 4);            break;        case 5:            drawOnes(1);            drawOnes(4);            break;        case 6:            vertical(0, 4, 10);            break;        case 7:            drawOnes(1);            drawOnes(6);            break;        case 8:            drawOnes(2);            drawOnes(6);            break;        case 9:            drawOnes(1);            drawOnes(8);            break;        default:            break;        }    }     void drawTens(int v) {        switch (v) {        case 1:            horizontal(0, 4, 0);            break;        case 2:            horizontal(0, 4, 4);            break;        case 3:            diagu(0, 4, 4);            break;        case 4:            diagd(0, 4, 0);            break;        case 5:            drawTens(1);            drawTens(4);            break;        case 6:            vertical(0, 4, 0);            break;        case 7:            drawTens(1);            drawTens(6);            break;        case 8:            drawTens(2);            drawTens(6);            break;        case 9:            drawTens(1);            drawTens(8);            break;        default:            break;        }    }     void drawHundreds(int hundreds) {        switch (hundreds) {        case 1:            horizontal(6, 10, 14);            break;        case 2:            horizontal(6, 10, 10);            break;        case 3:            diagu(6, 10, 14);            break;        case 4:            diagd(6, 10, 10);            break;        case 5:            drawHundreds(1);            drawHundreds(4);            break;        case 6:            vertical(10, 14, 10);            break;        case 7:            drawHundreds(1);            drawHundreds(6);            break;        case 8:            drawHundreds(2);            drawHundreds(6);            break;        case 9:            drawHundreds(1);            drawHundreds(8);            break;        default:            break;        }    }     void drawThousands(int thousands) {        switch (thousands) {        case 1:            horizontal(0, 4, 14);            break;        case 2:            horizontal(0, 4, 10);            break;        case 3:            diagd(0, 4, 10);            break;        case 4:            diagu(0, 4, 14);            break;        case 5:            drawThousands(1);            drawThousands(4);            break;        case 6:            vertical(10, 14, 0);            break;        case 7:            drawThousands(1);            drawThousands(6);            break;        case 8:            drawThousands(2);            drawThousands(6);            break;        case 9:            drawThousands(1);            drawThousands(8);            break;        default:            break;        }    }     void draw(int v) {        int thousands = v / 1000;        v %= 1000;         int hundreds = v / 100;        v %= 100;         int tens = v / 10;        int ones = v % 10;         if (thousands > 0) {            drawThousands(thousands);        }        if (hundreds > 0) {            drawHundreds(hundreds);        }        if (tens > 0) {            drawTens(tens);        }        if (ones > 0) {            drawOnes(ones);        }    }}; std::ostream &operator<<(std::ostream &os, const Cistercian &c) {    for (auto &row : c.canvas) {        for (auto cell : row) {            os << cell;        }        os << '\n';    }    return os;} int main() {    for (auto number : { 0, 1, 20, 300, 4000, 5555, 6789, 9999 }) {        std::cout << number << ":\n";         Cistercian c(number);        std::cout << c << '\n';    }     return 0;}`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000:
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555:
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789:
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x
x    xxxxxx

9999:
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx```

## D

Translation of: Java
`import std.stdio; class Cistercian {    private immutable SIZE = 15;    private char[SIZE][SIZE] canvas;     public this(int n) {        initN();        draw(n);    }     private void initN() {        foreach (ref row; canvas) {            row[] = ' ';            row[5] = 'x';        }    }     private void horizontal(int c1, int c2, int r) {        for (int c = c1; c <= c2; c++) {            canvas[r][c] = 'x';        }    }     private void vertical(int r1, int r2, int c) {        for (int r = r1; r <= r2; r++) {            canvas[r][c] = 'x';        }    }     private void diagd(int c1, int c2, int r) {        for (int c = c1; c <= c2; c++) {            canvas[r + c - c1][c] = 'x';        }    }     private void diagu(int c1, int c2, int r) {        for (int c = c1; c <= c2; c++) {            canvas[r - c + c1][c] = 'x';        }    }     private void draw(int v) {        auto thousands = v / 1000;        v %= 1000;         auto hundreds = v / 100;        v %= 100;         auto tens = v / 10;        auto ones = v % 10;         drawPart(1000 * thousands);        drawPart(100 * hundreds);        drawPart(10 * tens);        drawPart(ones);    }     private void drawPart(int v) {        switch(v) {            case 0:                break;             case 1:                horizontal(6, 10, 0);                break;            case 2:                horizontal(6, 10, 4);                break;            case 3:                diagd(6, 10, 0);                break;            case 4:                diagu(6, 10, 4);                break;            case 5:                drawPart(1);                drawPart(4);                break;            case 6:                vertical(0, 4, 10);                break;            case 7:                drawPart(1);                drawPart(6);                break;            case 8:                drawPart(2);                drawPart(6);                break;            case 9:                drawPart(1);                drawPart(8);                break;             case 10:                horizontal(0, 4, 0);                break;            case 20:                horizontal(0, 4, 4);                break;            case 30:                diagu(0, 4, 4);                break;            case 40:                diagd(0, 4, 0);                break;            case 50:                drawPart(10);                drawPart(40);                break;            case 60:                vertical(0, 4, 0);                break;            case 70:                drawPart(10);                drawPart(60);                break;            case 80:                drawPart(20);                drawPart(60);                break;            case 90:                drawPart(10);                drawPart(80);                break;             case 100:                horizontal(6, 10, 14);                break;            case 200:                horizontal(6, 10, 10);                break;            case 300:                diagu(6, 10, 14);                break;            case 400:                diagd(6, 10, 10);                break;            case 500:                drawPart(100);                drawPart(400);                break;            case 600:                vertical(10, 14, 10);                break;            case 700:                drawPart(100);                drawPart(600);                break;            case 800:                drawPart(200);                drawPart(600);                break;            case 900:                drawPart(100);                drawPart(800);                break;             case 1000:                horizontal(0, 4, 14);                break;            case 2000:                horizontal(0, 4, 10);                break;            case 3000:                diagd(0, 4, 10);                break;            case 4000:                diagu(0, 4, 14);                break;            case 5000:                drawPart(1000);                drawPart(4000);                break;            case 6000:                vertical(10, 14, 0);                break;            case 7000:                drawPart(1000);                drawPart(6000);                break;            case 8000:                drawPart(2000);                drawPart(6000);                break;            case 9000:                drawPart(1000);                drawPart(8000);                break;             default:                import std.conv;                assert(false, "Not handled: " ~ v.to!string);        }    }     public void toString(scope void delegate(const(char)[]) sink) const {        foreach (row; canvas) {            sink(row);            sink("\n");        }    }} void main() {    foreach (number; [0, 1, 20, 300, 4000, 5555, 6789, 9999]) {        writeln(number, ':');        auto c = new Cistercian(number);        writeln(c);    }}`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000:
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555:
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789:
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x

9999:
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx```

## F#

` // Cistercian numerals. Nigel Galloway: February 2nd., 2021let N=[|[[|' ';' ';' '|];[|' ';' ';' '|];[|' ';' ';' '|]];        [[|'#';'#';'#'|];[|' ';' ';' '|];[|' ';' ';' '|]];        [[|' ';' ';' '|];[|'#';'#';'#'|];[|' ';' ';' '|]];        [[|'#';' ';' '|];[|' ';'#';' '|];[|' ';' ';'#'|]];        [[|' ';' ';'#'|];[|' ';'#';' '|];[|'#';' ';' '|]];        [[|'#';'#';'#'|];[|' ';'#';' '|];[|'#';' ';' '|]];        [[|' ';' ';'#'|];[|' ';' ';'#'|];[|' ';' ';'#'|]];        [[|'#';'#';'#'|];[|' ';' ';'#'|];[|' ';' ';'#'|]];        [[|' ';' ';'#'|];[|' ';' ';'#'|];[|'#';'#';'#'|]];        [[|'#';'#';'#'|];[|' ';' ';'#'|];[|'#';'#';'#'|]];|] let fN i g e l=N.[l]|>List.iter2(fun n g->printfn "%sO%s" ((Array.rev>>System.String)n) (System.String g)) N.[e]               printfn "   O"               N.[g]|>List.rev|>List.iter2(fun n g->printfn "%sO%s" ((Array.rev>>System.String)n) (System.String g)) (N.[i]|>List.rev) [(0,0,0,0);(0,0,0,1);(0,0,2,0);(0,3,0,0);(4,0,0,0);(5,5,5,5);(6,7,8,9)]|>List.iter(fun(i,g,e,l)->printfn "\n%d%d%d%d\n____" i g e l; fN i g e l) `
Output:
```0000
____
O
O
O
O
O
O
O

0001
____
O###
O
O
O
O
O
O

0020
____
O
###O
O
O
O
O
O

0300
____
O
O
O
O
O  #
O #
O#

4000
____
O
O
O
O
#O
# O
#  O

5555
____
###O###
# O #
#O#
O
#O#
# O #
###O###

6789
____
#  O###
#  O  #
###O###
O
#  O  #
#  O  #
#  O###
```

## Factor

Works with: Factor version 0.99 2020-08-14
`USING: combinators continuations formatting grouping io kernelliterals math.order math.text.utils multiline sequencessplitting ; CONSTANT: numerals \$[HEREDOC: END  +    +-+  +    +    + +  +-+  + +  +-+  + +  +-+  |    |    |    |\   |/   |/   | |  | |  | |  | |  |    |    +-+  | +  +    +    | +  | +  +-+  +-+  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    +    +    +    +    +    +    +    +    +    +  END"\n" split harvest [ 5 group ] map flip] : precedence ( char char -- char )    2dup [ CHAR: + = ] either? [ 2drop CHAR: + ] [ max ] if ; : overwrite ( glyph glyph -- newglyph )    [ [ precedence ] 2map ] 2map ; : flip-slashes ( str -- new-str )    [        {            { CHAR: / [ CHAR: \ ] }            { CHAR: \ [ CHAR: / ] }            [ ]        } case    ] map ; : hflip ( seq -- newseq ) [ reverse flip-slashes ] map ;: vflip ( seq -- newseq ) reverse [ flip-slashes ] map ; : get-digits ( n -- seq ) 1 digit-groups 4 0 pad-tail ; : check-cistercian ( n -- )    0 9999 between? [ "Must be from 0 to 9999." throw ] unless ; : .cistercian ( n -- )    [ check-cistercian ] [ "%d:\n" printf ] [ get-digits ] tri    [ numerals nth ] map    [ { [ ] [ hflip ] [ vflip ] [ hflip vflip ] } spread ]    with-datastack [ ] [ overwrite ] map-reduce [ print ] each ; { 0 1 20 300 4000 5555 6789 8015 } [ .cistercian nl ] each`
Output:
```0:
+
|
|
|
|
|
+

1:
+-+
|
|
|
|
|
+

20:
+
|
+-+
|
|
|
+

300:
+
|
|
|
| +
|/
+

4000:
+
|
|
|
+
/|
+ +

5555:
+-+-+
\|/
+
|
+
/|\
+-+-+

6789:
+ +-+
| | |
+-+-+
|
+ | +
| | |
+ +-+

8015:
+-+-+
|/
+
|
+-+
| |
+ +
```

## Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.

## Go

Translation of: Wren
`package main import "fmt" var n = make([][]string, 15) func initN() {    for i := 0; i < 15; i++ {        n[i] = make([]string, 11)        for j := 0; j < 11; j++ {            n[i][j] = " "        }        n[i][5] = "x"    }} func horiz(c1, c2, r int) {    for c := c1; c <= c2; c++ {        n[r][c] = "x"    }} func verti(r1, r2, c int) {    for r := r1; r <= r2; r++ {        n[r][c] = "x"    }} func diagd(c1, c2, r int) {    for c := c1; c <= c2; c++ {        n[r+c-c1][c] = "x"    }} func diagu(c1, c2, r int) {    for c := c1; c <= c2; c++ {        n[r-c+c1][c] = "x"    }} var draw map[int]func() // map contains recursive closures func initDraw() {    draw = map[int]func(){        1: func() { horiz(6, 10, 0) },        2: func() { horiz(6, 10, 4) },        3: func() { diagd(6, 10, 0) },        4: func() { diagu(6, 10, 4) },        5: func() { draw[1](); draw[4]() },        6: func() { verti(0, 4, 10) },        7: func() { draw[1](); draw[6]() },        8: func() { draw[2](); draw[6]() },        9: func() { draw[1](); draw[8]() },         10: func() { horiz(0, 4, 0) },        20: func() { horiz(0, 4, 4) },        30: func() { diagu(0, 4, 4) },        40: func() { diagd(0, 4, 0) },        50: func() { draw[10](); draw[40]() },        60: func() { verti(0, 4, 0) },        70: func() { draw[10](); draw[60]() },        80: func() { draw[20](); draw[60]() },        90: func() { draw[10](); draw[80]() },         100: func() { horiz(6, 10, 14) },        200: func() { horiz(6, 10, 10) },        300: func() { diagu(6, 10, 14) },        400: func() { diagd(6, 10, 10) },        500: func() { draw[100](); draw[400]() },        600: func() { verti(10, 14, 10) },        700: func() { draw[100](); draw[600]() },        800: func() { draw[200](); draw[600]() },        900: func() { draw[100](); draw[800]() },         1000: func() { horiz(0, 4, 14) },        2000: func() { horiz(0, 4, 10) },        3000: func() { diagd(0, 4, 10) },        4000: func() { diagu(0, 4, 14) },        5000: func() { draw[1000](); draw[4000]() },        6000: func() { verti(10, 14, 0) },        7000: func() { draw[1000](); draw[6000]() },        8000: func() { draw[2000](); draw[6000]() },        9000: func() { draw[1000](); draw[8000]() },    }} func printNumeral() {    for i := 0; i < 15; i++ {        for j := 0; j < 11; j++ {            fmt.Printf("%s ", n[i][j])        }        fmt.Println()    }    fmt.Println()} func main() {    initDraw()    numbers := []int{0, 1, 20, 300, 4000, 5555, 6789, 9999}    for _, number := range numbers {        initN()        fmt.Printf("%d:\n", number)        thousands := number / 1000        number %= 1000        hundreds := number / 100        number %= 100        tens := number / 10        ones := number % 10        if thousands > 0 {            draw[thousands*1000]()        }        if hundreds > 0 {            draw[hundreds*100]()        }        if tens > 0 {            draw[tens*10]()        }        if ones > 0 {            draw[ones]()        }        printNumeral()    }}`
Output:
```Same as Wren example.
```

## J

Program writes a scalable vector graphics file containing all composable numbers. J code is alongside the original python source. Save as file jc.ijs, then invoke in a j session

```   main'jc.svg'[load'jc.ijs'
open browser to /tmp/jc.svg
```

The rc verb writes RC=. 0 1 20 300 666 4000 5555 6789

` NB. http://rosettacode.org/wiki/Cistercian_numeralsNB. converted fromNB. https://scipython.com/blog/cistercian-numerals/ Dyad=: [: : NB. numeric_vector format 'python {} string'format=: ''&\$: :([: ; (a: , [: ":&.> [) ,. '{}' ([ (E. <@}.;._1 ]) ,) ])  NB. literals x should be boxed pwd=:1!:43rm=: 1!:55@boxopen ::emptyprint=: [email protected][ NB. debugprint=: (1!:3~,&LF)~ Dyadopen=: 1!:21close=: 1!:22 NB.# http://en.kpartner.kr/data/warrant-check-pzmwqyk/qrf56.php?3fff1d=cistercian-numbers-unicodeNB.NB.# The paths to create the digits 1–9 in the "units" position.NB.d_paths = {NB.(0, 1): ((1, 0), (2, 0)),NB.(0, 2): ((1, 1), (2, 1)),NB.(0, 3): ((1, 0), (2, 1)),NB.(0, 4): ((1, 1), (2, 0)),NB.(0, 5): ((1, 1), (2, 0), (1, 0)),NB.(0, 6): ((2, 0), (2, 1)),NB.(0, 7): ((1, 0), (2, 0), (2, 1)),NB.(0, 8): ((1, 1), (2, 1), (2, 0)),NB.(0, 9): ((1, 1), (2, 1), (2, 0), (1, 0)),NB.}NB.# Generate the paths for the digits in the 10s, 100s and 1000s position byNB.# reflection.NB.for i in range(1, 10):NB.    d_paths[(1, i)] = [(2-x, y) for x, y in d_paths[(0, i)]]NB.    d_paths[(2, i)] = [(x, 3-y) for x, y in d_paths[(0, i)]]NB.    d_paths[(3, i)] = [(2-x, 3-y) for x, y in d_paths[(0, i)]]NB.d_paths=: _2[\L:0]((1, 0), (2, 0));((1, 1), (2, 1));((1, 0), (2, 1));((1, 1), (2, 0));((1, 1), (2, 0), (1, 0));((2, 0), (2, 1));((1, 0), (2, 0), (2, 1));((1, 1), (2, 1), (2, 0));((1, 1), (2, 1), (2, 0), (1, 0))d_paths=: (, ((2-[),])/"1 L:0 , (,3&-)/"1 L:0 , ((2-[),(3-]))/"1 L:0) d_pathsd_paths=: , a: ,. _9]\ d_paths  NB. adjust indexingNB.echo d_paths NB. test NB.def transform(x, y, dx, dy, sc):NB.    """Transform the coordinates (x, y) into the scaled, displaced system."""NB.    return x*sc + dx, y*sc + dyNB.transform=: (] p.~ [: (2&{. (,.) 2 \$ 2&}.) [) Dyad  NB. (dx dy sx [sy]) transform (x y) NB.def get_path(i, d):NB.    """Return the SVG path to render the digit d in decimal position i."""NB.    if d == 0:NB.        returnNB.    path = d_paths[(i, d)]NB.    return 'M{},{} '.format(*transform(*path[0], *tprms)) + ' '.join(NB.                ['L{},{}'.format(*transform(*xy, *tprms)) for xy in path[1:]])NB.get_path=: 3 :0 'i d'=. y if. d do.  path=. d_paths {::~ 10 #. y  result=. 'M{},{} 'format~ TPRMS transform {. path  result=. result , }: , ' ' ,.~ 'L{},{}'format"1~TPRMS transform"1 }. path else.  '' end.)  NB.def make_digit(i, d):NB.    """Output the SVG path element for digit d in decimal position i."""NB.    print('<path d="{}"/>'.format(get_path(i, d)), file=fo)NB.make_digit=: (print~ (('<path d="{}"/>') (format~ <) get_path)) Dyad NB. fo make_digit n NB.def make_stave():NB.    """Output the SVG line element for the vertical stave."""NB.    x1, y1 = transform(1, 0, *tprms)NB.    x2, y2 = transform(1, 3, *tprms)NB.    print('<line x1="{}" y1="{}" x2="{}" y2="{}"/>'.format(x1, y1, x2, y2),NB.          file=fo)make_stave=: 3 :'y print~ ''<line x1="{}" y1="{}" x2="{}" y2="{}"/>'' format~ , TPRMS (transform"1) 1 0,:1 3' NB.def svg_preamble(fo):NB.    """Write the SVG preamble, including the styles."""NB.NB.    # Set the path stroke-width appropriate to the scale.NB.    stroke_width = max(1.5, tprms[2] / 5)NB.    print("""<?xml version="1.0" encoding="utf-8"?>NB.<svg xmlns="http://www.w3.org/2000/svg"NB.     xmlns:xlink="http://www.w3.org/1999/xlink" width="2000" height="2005" >NB.<defs>NB.<style type="text/css"><![CDATA[NB.line, path {NB.  stroke: black;NB.  stroke-width: %d;NB.  stroke-linecap: square;NB.}NB.path {NB.  fill: none;NB.}NB.]]>NB.</style>NB.</defs>NB.""" % stroke_width, file=fo)NB.PREAMBLE=: 0 :0<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg"     xmlns:xlink="http://www.w3.org/1999/xlink" width="2000" height="2005" ><defs><style type="text/css"><![CDATA[line, path {  stroke: black;  stroke-width: {};  stroke-linecap: square;}path {  fill: none;}]]></style></defs>) svg_preamble=: 3 :'(PREAMBLE format~ 1.5 >. 5 *inv 2 { TPRMS) print y' NB.def make_numeral(n, fo):NB.    """Output the SVG for the number n using the current transform."""NB.    make_stave()NB.    for i, s_d in enumerate(str(n)[::-1]):NB.        make_digit(i, int(s_d))NB.make_numeral=: 4 :0 fo=. x n=. y make_stave fo if. y do.  fo make_digit"1 (,.~ [email protected]#) |. 10 #.inv n end.) NB.# Transform parameters: dx, dy, scale.NB.tprms = [5, 5, 5]NB.NB.with open('all_cistercian_numerals.svg', 'w') as fo:NB.    svg_preamble(fo)NB.    for i in range(10000):NB.        # Locate this number at the position dx, dy = tprms[:2].NB.        tprms[0] = 15 * (i % 125) + 5NB.        tprms[1] = 25 * (i // 125) + 5NB.        make_numeral(i, fo)NB.    print("""</svg>""", file=fo)main=: 3 :0 ::('Use: main ''filename.svg'''"_) TPRMS=: 5 5 5 rm<y fo=. open<y svg_preamble fo for_i. i. 10000 do.  TPRMS=: (5 ,~ (5 + 15 * 125 | ]) , 5 + 25 * [: (<.) 125 *^:_1 ]) i  fo make_numeral i end. '</svg>' print fo empty close fo 'open browser to {}/{}' format~ (pwd'') ; y)rc=: 3 :0 ::('Use: rc ''filename.svg'''"_) scale=. 5 TPRMS=: 5 5 , scale rm<y fo=. open<y svg_preamble fo RC=. 0 1 20 300 666 4000 5555 6789 echo 'writing {}' format~ < RC  for_k. (,.~ [email protected]#) RC do.  'j i'=. k  TPRMS=: (scale ,~ (5 + scale * 15 * 125 | ]) , 5 + scale * 25 * [: (<.) 125 *^:_1 ]) j  fo make_numeral i end. '</svg>' print fo empty close fo 'open browser to {}{}{}' format~ (pwd'') ; PATHJSEP_j_ ; y) `

## Java

Translation of: Kotlin
`import java.util.Arrays;import java.util.List; public class Cistercian {    private static final int SIZE = 15;    private final char[][] canvas = new char[SIZE][SIZE];     public Cistercian(int n) {        initN();        draw(n);    }     public void initN() {        for (var row : canvas) {            Arrays.fill(row, ' ');            row[5] = 'x';        }    }     private void horizontal(int c1, int c2, int r) {        for (int c = c1; c <= c2; c++) {            canvas[r][c] = 'x';        }    }     private void vertical(int r1, int r2, int c) {        for (int r = r1; r <= r2; r++) {            canvas[r][c] = 'x';        }    }     private void diagd(int c1, int c2, int r) {        for (int c = c1; c <= c2; c++) {            canvas[r + c - c1][c] = 'x';        }    }     private void diagu(int c1, int c2, int r) {        for (int c = c1; c <= c2; c++) {            canvas[r - c + c1][c] = 'x';        }    }     private void draw(int v) {        var thousands = v / 1000;        v %= 1000;         var hundreds = v / 100;        v %= 100;         var tens = v / 10;        var ones = v % 10;         drawPart(1000 * thousands);        drawPart(100 * hundreds);        drawPart(10 * tens);        drawPart(ones);    }     private void drawPart(int v) {        switch (v) {            case 1:                horizontal(6, 10, 0);                break;            case 2:                horizontal(6, 10, 4);                break;            case 3:                diagd(6, 10, 0);                break;            case 4:                diagu(6, 10, 4);                break;            case 5:                drawPart(1);                drawPart(4);                break;            case 6:                vertical(0, 4, 10);                break;            case 7:                drawPart(1);                drawPart(6);                break;            case 8:                drawPart(2);                drawPart(6);                break;            case 9:                drawPart(1);                drawPart(8);                break;             case 10:                horizontal(0, 4, 0);                break;            case 20:                horizontal(0, 4, 4);                break;            case 30:                diagu(0, 4, 4);                break;            case 40:                diagd(0, 4, 0);                break;            case 50:                drawPart(10);                drawPart(40);                break;            case 60:                vertical(0, 4, 0);                break;            case 70:                drawPart(10);                drawPart(60);                break;            case 80:                drawPart(20);                drawPart(60);                break;            case 90:                drawPart(10);                drawPart(80);                break;             case 100:                horizontal(6, 10, 14);                break;            case 200:                horizontal(6, 10, 10);                break;            case 300:                diagu(6, 10, 14);                break;            case 400:                diagd(6, 10, 10);                break;            case 500:                drawPart(100);                drawPart(400);                break;            case 600:                vertical(10, 14, 10);                break;            case 700:                drawPart(100);                drawPart(600);                break;            case 800:                drawPart(200);                drawPart(600);                break;            case 900:                drawPart(100);                drawPart(800);                break;             case 1000:                horizontal(0, 4, 14);                break;            case 2000:                horizontal(0, 4, 10);                break;            case 3000:                diagd(0, 4, 10);                break;            case 4000:                diagu(0, 4, 14);                break;            case 5000:                drawPart(1000);                drawPart(4000);                break;            case 6000:                vertical(10, 14, 0);                break;            case 7000:                drawPart(1000);                drawPart(6000);                break;            case 8000:                drawPart(2000);                drawPart(6000);                break;            case 9000:                drawPart(1000);                drawPart(8000);                break;         }    }     @Override    public String toString() {        StringBuilder builder = new StringBuilder();        for (var row : canvas) {            builder.append(row);            builder.append('\n');        }        return builder.toString();    }     public static void main(String[] args) {        for (int number : List.of(0, 1, 20, 300, 4000, 5555, 6789, 9999)) {            System.out.printf("%d:\n", number);            var c = new Cistercian(number);            System.out.println(c);        }    }}`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000:
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555:
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789:
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x
x    xxxxxx

9999:
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx    ```

## JavaScript

Using a canvas.

` // htmldocument.write(`  <p><input id="num" type="number" min="0" max="9999" value="0" onchange="showCist()"></p>  <p><canvas id="cist" width="200" height="300"></canvas></p>  <p> <!-- EXAMPLES (can be deleted for normal use) -->    <button onclick="set(0)">0</button>    <button onclick="set(1)">1</button>    <button onclick="set(20)">20</button>    <button onclick="set(300)">300</button>    <button onclick="set(4000)">4000</button>    <button onclick="set(5555)">5555</button>    <button onclick="set(6789)">6789</button>    <button onclick="set(Math.floor(Math.random()*1e4))">Random</button>  </p>`); // to show given examples// can be deleted for normal usefunction set(num) {  document.getElementById('num').value = num;  showCist();} const SW = 10; // stroke widthlet canvas = document.getElementById('cist'),    cx = canvas.getContext('2d'); function showCist() {  // reset canvas  cx.clearRect(0, 0, canvas.width, canvas.height);  cx.lineWidth = SW;  cx.beginPath();  cx.moveTo(100, 0+.5*SW);  cx.lineTo(100, 300-.5*SW);  cx.stroke();   let num = document.getElementById('num').value;  while (num.length < 4) num = '0' + num;  // fills leading zeros to \$num   /***********************\  |        POINTS:        |  | ********************* |  |                       |  |     a --- b --- c     |  |     |     |     |     |  |     d --- e --- f     |  |     |     |     |     |  |     g --- h --- i     |  |     |     |     |     |  |     j --- k --- l     |  |                       |  \***********************/  let  a = [0+SW,   0+SW],   b = [100,   0+SW],   c = [200-SW,   0+SW],  d = [0+SW,    100],   e = [100,    100],   f = [200-SW,    100],  g = [0+SW,    200],   h = [100,    200],   i = [200-SW,    200],  j = [0+SW, 300-SW],   k = [100, 300-SW],   l = [200-SW, 300-SW];   function draw() {    let x = 1;    cx.beginPath();    cx.moveTo(arguments[0][0], arguments[0][1]);    while (x < arguments.length) {      cx.lineTo(arguments[x][0], arguments[x][1]);      x++;    }    cx.stroke();  }   // 1000s  switch (num[0]) {    case '1': draw(j, k);       break;       case '2': draw(g, h);    break;    case '3': draw(g, k);       break;       case '4': draw(j, h);    break;    case '5': draw(k, j, h);    break;       case '6': draw(g, j);    break;    case '7': draw(g, j, k);    break;       case '8': draw(j, g, h); break;    case '9': draw(h, g, j, k); break;  }  // 100s  switch (num[1]) {    case '1': draw(k, l);       break;       case '2': draw(h, i);    break;    case '3': draw(k, i);       break;       case '4': draw(h, l);    break;    case '5': draw(h, l, k);    break;       case '6': draw(i, l);    break;    case '7': draw(k, l, i);    break;       case '8': draw(h, i, l); break;    case '9': draw(h, i, l, k); break;  }  // 10s  switch (num[2]) {    case '1': draw(a, b);       break;       case '2': draw(d, e);    break;    case '3': draw(d, b);       break;       case '4': draw(a, e);    break;    case '5': draw(b, a, e);    break;       case '6': draw(a, d);    break;    case '7': draw(d, a, b);    break;       case '8': draw(a, d, e); break;    case '9': draw(b, a, d, e); break;  }  // 1s  switch (num[3]) {    case '1': draw(b, c);       break;       case '2': draw(e, f);    break;    case '3': draw(b, f);       break;       case '4': draw(e, c);    break;    case '5': draw(b, c, e);    break;       case '6': draw(c, f);    break;    case '7': draw(b, c, f);    break;       case '8': draw(e, f, c); break;    case '9': draw(b, c, f, e); break;  }} `
Output:
```
https://jsfiddle.net/43tsmn9z```

## Julia

Gtk graphic version.

`using Gtk, Cairo const can = GtkCanvas(800, 100)const win = GtkWindow(can, "Canvas")const numbers = [0, 1, 20, 300, 4000, 5555, 6789, 8123] function drawcnum(ctx, xypairs)    move_to(ctx, xypairs[1][1], xypairs[1][2])    for p in xypairs[2:end]        line_to(ctx, p[1], p[2])    end    stroke(ctx)end @guarded draw(can) do widget    ctx = getgc(can)    hlen, wlen, len = height(can), width(can), length(numbers)    halfwspan, thirdcolspan, voffset = wlen ÷ (len * 2), wlen ÷ (len * 3), hlen ÷ 8    set_source_rgb(ctx, 0, 0, 2550)    for (i, n) in enumerate(numbers)        # paint vertical as width 2 rectangle        x = halfwspan * (2 * i - 1)        rectangle(ctx, x, voffset, 2, hlen - 2 * voffset)        stroke(ctx)        # determine quadrant and draw numeral lines there        dig = [(10^(i - 1), m) for (i, m) in enumerate(digits(n))]        for (d, m) in dig            y, dx, dy = (d == 1) ? (voffset, thirdcolspan, thirdcolspan) :                (d == 10) ? (voffset, -thirdcolspan, thirdcolspan) :                (d == 100) ? (hlen - voffset, thirdcolspan, -thirdcolspan) :                (hlen - voffset, -thirdcolspan, -thirdcolspan)            m == 1 && drawcnum(ctx, [[x, y], [x + dx, y]])            m == 2 && drawcnum(ctx, [[x, y + dy], [x + dx, y + dy]])            m == 3 && drawcnum(ctx, [[x, y], [x + dx, y + dy]])            m == 4 && drawcnum(ctx, [[x, y + dy], [x + dx, y]])            m == 5 && drawcnum(ctx, [[x, y + dy], [x + dx, y], [x, y]])            m == 6 && drawcnum(ctx, [[x + dx, y], [x + dx, y + dy]])            m == 7 && drawcnum(ctx, [[x, y], [x + dx, y], [x + dx, y + dy]])            m == 8 && drawcnum(ctx, [[x, y + dy], [x + dx, y + dy], [x + dx, y]])            m == 9 && drawcnum(ctx, [[x, y], [x + dx, y], [x + dx, y + dy], [x, y + dy]])        end        move_to(ctx, x - halfwspan ÷ 6, hlen - 4)        Cairo.show_text(ctx, string(n))        stroke(ctx)    endend function mooncipher()    draw(can)    cond = Condition()    endit(w) = notify(cond)    signal_connect(endit, win, :destroy)    show(can)    wait(cond)end mooncipher() `

## Kotlin

Translation of: C++
`import java.io.StringWriter class Cistercian() {    constructor(number: Int) : this() {        draw(number)    }     private val size = 15    private var canvas = Array(size) { Array(size) { ' ' } }     init {        initN()    }     private fun initN() {        for (row in canvas) {            row.fill(' ')            row[5] = 'x'        }    }     private fun horizontal(c1: Int, c2: Int, r: Int) {        for (c in c1..c2) {            canvas[r][c] = 'x'        }    }     private fun vertical(r1: Int, r2: Int, c: Int) {        for (r in r1..r2) {            canvas[r][c] = 'x'        }    }     private fun diagd(c1: Int, c2: Int, r: Int) {        for (c in c1..c2) {            canvas[r + c - c1][c] = 'x'        }    }     private fun diagu(c1: Int, c2: Int, r: Int) {        for (c in c1..c2) {            canvas[r - c + c1][c] = 'x'        }    }     private fun drawPart(v: Int) {        when (v) {            1 -> {                horizontal(6, 10, 0)            }            2 -> {                horizontal(6, 10, 4)            }            3 -> {                diagd(6, 10, 0)            }            4 -> {                diagu(6, 10, 4)            }            5 -> {                drawPart(1)                drawPart(4)            }            6 -> {                vertical(0, 4, 10)            }            7 -> {                drawPart(1)                drawPart(6)            }            8 -> {                drawPart(2)                drawPart(6)            }            9 -> {                drawPart(1)                drawPart(8)            }             10 -> {                horizontal(0, 4, 0)            }            20 -> {                horizontal(0, 4, 4)            }            30 -> {                diagu(0, 4, 4)            }            40 -> {                diagd(0, 4, 0)            }            50 -> {                drawPart(10)                drawPart(40)            }            60 -> {                vertical(0, 4, 0)            }            70 -> {                drawPart(10)                drawPart(60)            }            80 -> {                drawPart(20)                drawPart(60)            }            90 -> {                drawPart(10)                drawPart(80)            }             100 -> {                horizontal(6, 10, 14)            }            200 -> {                horizontal(6, 10, 10)            }            300 -> {                diagu(6, 10, 14)            }            400 -> {                diagd(6, 10, 10)            }            500 -> {                drawPart(100)                drawPart(400)            }            600 -> {                vertical(10, 14, 10)            }            700 -> {                drawPart(100)                drawPart(600)            }            800 -> {                drawPart(200)                drawPart(600)            }            900 -> {                drawPart(100)                drawPart(800)            }             1000 -> {                horizontal(0, 4, 14)            }            2000 -> {                horizontal(0, 4, 10)            }            3000 -> {                diagd(0, 4, 10)            }            4000 -> {                diagu(0, 4, 14)            }            5000 -> {                drawPart(1000)                drawPart(4000)            }            6000 -> {                vertical(10, 14, 0)            }            7000 -> {                drawPart(1000)                drawPart(6000)            }            8000 -> {                drawPart(2000)                drawPart(6000)            }            9000 -> {                drawPart(1000)                drawPart(8000)            }        }    }     private fun draw(v: Int) {        var v2 = v         val thousands = v2 / 1000        v2 %= 1000         val hundreds = v2 / 100        v2 %= 100         val tens = v2 / 10        val ones = v % 10         if (thousands > 0) {            drawPart(1000 * thousands)        }        if (hundreds > 0) {            drawPart(100 * hundreds)        }        if (tens > 0) {            drawPart(10 * tens)        }        if (ones > 0) {            drawPart(ones)        }    }     override fun toString(): String {        val sw = StringWriter()        for (row in canvas) {            for (cell in row) {                sw.append(cell)            }            sw.appendLine()        }        return sw.toString()    }} fun main() {    for (number in arrayOf(0, 1, 20, 300, 4000, 5555, 6789, 9999)) {        println("\$number:")         val c = Cistercian(number)        println(c)    } }`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000:
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555:
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789:
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x
x    xxxxxx

9999:
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx    ```

## Lua

Translation of: Go
`function initN()    local n = {}    for i=1,15 do        n[i] = {}        for j=1,11 do            n[i][j] = " "        end        n[i][6] = "x"    end    return nend function horiz(n, c1, c2, r)    for c=c1,c2 do        n[r+1][c+1] = "x"    endend function verti(n, r1, r2, c)    for r=r1,r2 do        n[r+1][c+1] = "x"    endend function diagd(n, c1, c2, r)    for c=c1,c2 do        n[r+c-c1+1][c+1] = "x"    endend function diagu(n, c1, c2, r)    for c=c1,c2 do        n[r-c+c1+1][c+1] = "x"    endend function initDraw()    local draw = {}     draw[1] = function(n) horiz(n, 6, 10, 0) end    draw[2] = function(n) horiz(n, 6, 10, 4) end    draw[3] = function(n) diagd(n, 6, 10, 0) end    draw[4] = function(n) diagu(n, 6, 10, 4) end    draw[5] = function(n) draw[1](n) draw[4](n) end    draw[6] = function(n) verti(n, 0, 4, 10) end    draw[7] = function(n) draw[1](n) draw[6](n) end    draw[8] = function(n) draw[2](n) draw[6](n) end    draw[9] = function(n) draw[1](n) draw[8](n) end     draw[10] = function(n) horiz(n, 0, 4, 0) end    draw[20] = function(n) horiz(n, 0, 4, 4) end    draw[30] = function(n) diagu(n, 0, 4, 4) end    draw[40] = function(n) diagd(n, 0, 4, 0) end    draw[50] = function(n) draw[10](n) draw[40](n) end    draw[60] = function(n) verti(n, 0, 4, 0) end    draw[70] = function(n) draw[10](n) draw[60](n) end    draw[80] = function(n) draw[20](n) draw[60](n) end    draw[90] = function(n) draw[10](n) draw[80](n) end     draw[100] = function(n) horiz(n, 6, 10, 14) end    draw[200] = function(n) horiz(n, 6, 10, 10) end    draw[300] = function(n) diagu(n, 6, 10, 14) end    draw[400] = function(n) diagd(n, 6, 10, 10) end    draw[500] = function(n) draw[100](n) draw[400](n) end    draw[600] = function(n) verti(n, 10, 14, 10) end    draw[700] = function(n) draw[100](n) draw[600](n) end    draw[800] = function(n) draw[200](n) draw[600](n) end    draw[900] = function(n) draw[100](n) draw[800](n) end     draw[1000] = function(n) horiz(n, 0, 4, 14) end    draw[2000] = function(n) horiz(n, 0, 4, 10) end    draw[3000] = function(n) diagd(n, 0, 4, 10) end    draw[4000] = function(n) diagu(n, 0, 4, 14) end    draw[5000] = function(n) draw[1000](n) draw[4000](n) end    draw[6000] = function(n) verti(n, 10, 14, 0) end    draw[7000] = function(n) draw[1000](n) draw[6000](n) end    draw[8000] = function(n) draw[2000](n) draw[6000](n) end    draw[9000] = function(n) draw[1000](n) draw[8000](n) end     return drawend function printNumeral(n)    for i,v in pairs(n) do        for j,w in pairs(v) do            io.write(w .. " ")        end        print()    end    print()end function main()    local draw = initDraw()    for i,number in pairs({0, 1, 20, 300, 4000, 5555, 6789, 9999}) do        local n = initN()        print(number..":")        local thousands = math.floor(number / 1000)        number = number % 1000        local hundreds = math.floor(number / 100)        number = number % 100        local tens = math.floor(number / 10)        local ones = number % 10        if thousands > 0 then            draw[thousands * 1000](n)        end        if hundreds > 0 then            draw[hundreds * 100](n)        end        if tens > 0 then            draw[tens * 10](n)        end        if ones > 0 then            draw[ones](n)        end        printNumeral(n)    endend main()`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
x x x x x x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
x x x x x x
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x         x
x       x
x     x
x   x
x x

4000:
x
x
x
x
x
x
x
x
x
x
x x
x   x
x     x
x       x
x         x

5555:
x x x x x x x x x x x
x       x       x
x     x     x
x   x   x
x x x
x
x
x
x
x
x x x
x   x   x
x     x     x
x       x       x
x x x x x x x x x x x

6789:
x         x x x x x x
x         x         x
x         x         x
x         x         x
x x x x x x x x x x x
x
x
x
x
x
x         x         x
x         x         x
x         x         x
x         x         x
x         x x x x x x

9999:
x x x x x x x x x x x
x         x         x
x         x         x
x         x         x
x x x x x x x x x x x
x
x
x
x
x
x x x x x x x x x x x
x         x         x
x         x         x
x         x         x
x x x x x x x x x x x```

## Mathematica/Wolfram Language

`ClearAll[CistercianNumberEncodeHelper, CistercianNumberEncode]\[Delta] = 0.25;CistercianNumberEncodeHelper[0] := {}CistercianNumberEncodeHelper[1] := Line[{{0, 1}, {\[Delta], 1}}]CistercianNumberEncodeHelper[2] := Line[{{0, 1 - \[Delta]}, {\[Delta], 1 - \[Delta]}}]CistercianNumberEncodeHelper[3] := Line[{{0, 1}, {\[Delta], 1 - \[Delta]}}]CistercianNumberEncodeHelper[4] := Line[{{0, 1 - \[Delta]}, {\[Delta], 1}}]CistercianNumberEncodeHelper[5] := Line[{{0, 1 - \[Delta]}, {\[Delta], 1}, {0, 1}}]CistercianNumberEncodeHelper[6] := Line[{{\[Delta], 1 - \[Delta]}, {\[Delta], 1}}]CistercianNumberEncodeHelper[7] := Line[{{\[Delta], 1 - \[Delta]}, {\[Delta], 1}, {0, 1}}]CistercianNumberEncodeHelper[8] := Line[{{0, 1 - \[Delta]}, {\[Delta], 1 - \[Delta]}, {\[Delta], 1}}]CistercianNumberEncodeHelper[9] := Line[{{0, 1}, {\[Delta], 1}, {\[Delta], 1 - \[Delta]}, {0, 1 - \[Delta]}}]CistercianNumberEncode::nnarg = "The argument `1` should be an integer between 0 and 9999 (inclusive).";CistercianNumberEncode[n_Integer] := Module[{digs},  If[0 <= n <= 9999,   digs = IntegerDigits[n, 10, 4];   Graphics[{Line[{{0, 0}, {0, 1}}],     CistercianNumberEncodeHelper[digs[[4]]],     GeometricTransformation[CistercianNumberEncodeHelper[digs[[3]]],       ReflectionTransform[{1, 0}]],     GeometricTransformation[CistercianNumberEncodeHelper[digs[[2]]],       ReflectionTransform[{0, 1}, {0, 1/2}]],     GeometricTransformation[CistercianNumberEncodeHelper[digs[[1]]],       RotationTransform[Pi, {0, 1/2}]]     },    PlotRange -> {{-1.5 \[Delta], 1.5 \[Delta]}, {0 - 0.5 \[Delta],        1 + 0.5 \[Delta]}},    ImageSize -> 50    ]   ,   Message[CistercianNumberEncode::nnarg, n]   ]  ]CistercianNumberEncode[0]CistercianNumberEncode[1]CistercianNumberEncode[20]CistercianNumberEncode[300]CistercianNumberEncode[4000]CistercianNumberEncode[5555]CistercianNumberEncode[6789]CistercianNumberEncode[1337]`
Output:

A set of Graphics is shown for each of the numerals.

## Nim

Translation of: Kotlin
`const Size = 15 type Canvas = array[Size, array[Size, char]]  func horizontal(canvas: var Canvas; col1, col2, row: Natural) =  for col in col1..col2:    canvas[row][col] = 'x'  func vertical(canvas: var Canvas; row1, row2, col: Natural) =  for row in row1..row2:    canvas[row][col] = 'x'  func diagd(canvas: var Canvas; col1, col2, row: Natural) =  for col in col1..col2:    canvas[row + col - col1][col] = 'x'  func diagu(canvas: var Canvas; col1, col2, row: Natural) =  for col in col1..col2:    canvas[row - col + col1][col] = 'x'  func drawPart(canvas: var Canvas; value: Natural) =   case value  of 1:    canvas.horizontal(6, 10, 0)  of 2:    canvas.horizontal(6, 10, 4)  of 3:    canvas.diagd(6, 10, 0)  of 4:    canvas.diagu(6, 10, 4)  of 5:    canvas.drawPart(1)    canvas.drawPart(4)  of 6:    canvas.vertical(0, 4, 10)  of 7:    canvas.drawPart(1)    canvas.drawPart(6)  of 8:    canvas.drawPart(2)    canvas.drawPart(6)  of 9:    canvas.drawPart(1)    canvas.drawPart(8)  of 10:    canvas.horizontal(0, 4, 0)  of 20:    canvas.horizontal(0, 4, 4)  of 30:    canvas.diagu(0, 4, 4)  of 40:    canvas.diagd(0, 4, 0)  of 50:    canvas.drawPart(10)    canvas.drawPart(40)  of 60:    canvas.vertical(0, 4, 0)  of 70:    canvas.drawPart(10)    canvas.drawPart(60)  of 80:    canvas.drawPart(20)    canvas.drawPart(60)  of 90:    canvas.drawPart(10)    canvas.drawPart(80)  of 100:    canvas.horizontal(6, 10, 14)  of 200:    canvas.horizontal(6, 10, 10)  of 300:    canvas.diagu(6, 10, 14)  of 400:    canvas.diagd(6, 10, 10)  of 500:    canvas.drawPart(100)    canvas.drawPart(400)  of 600:    canvas.vertical(10, 14, 10)  of 700:    canvas.drawPart(100)    canvas.drawPart(600)  of 800:    canvas.drawPart(200)    canvas.drawPart(600)  of 900:    canvas.drawPart(100)    canvas.drawPart(800)  of 1000:    canvas.horizontal(0, 4, 14)  of 2000:    canvas.horizontal(0, 4, 10)  of 3000:    canvas.diagd(0, 4, 10)  of 4000:    canvas.diagu(0, 4, 14)  of 5000:    canvas.drawPart(1000)    canvas.drawPart(4000)  of 6000:    canvas.vertical(10, 14, 0)  of 7000:    canvas.drawPart(1000)    canvas.drawPart(6000)  of 8000:    canvas.drawPart(2000)    canvas.drawPart(6000)  of 9000:    canvas.drawPart(1000)    canvas.drawPart(8000)  else:    raise newException(ValueError, "wrong value for 'drawPart'")  func draw(canvas: var Canvas; value: Natural) =   var val = value  let thousands = val div 1000  val = val mod 1000  let hundreds = val div 100  val = val mod 100  let tens = val div 10  let ones = val mod 10   if thousands != 0:    canvas.drawPart(1000 * thousands)  if hundreds != 0:    canvas.drawPart(100 * hundreds)  if tens != 0:    canvas.drawPart(10 * tens)  if ones != 0:    canvas.drawPart(ones)  func cistercian(n: Natural): Canvas =  for row in result.mitems:    for cell in row.mitems: cell = ' '    row[5] = 'x'  result.draw(n)  proc `\$`(canvas: Canvas): string =  for row in canvas:    for cell in row:      result.add cell    result.add '\n'  when isMainModule:   for number in [0, 1, 20, 300, 4000, 5555, 6789, 9999]:    echo number, ':'    echo cistercian(number)`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000:
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555:
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789:
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x
x    xxxxxx

9999:
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
```

## Phix

`---- Define each digit as {up-down multiplier, left-right multiplier, char},--              that is starting each drawing from line 1 or 7, column 3,--              and with `/` and `\` being flipped below when necessary.--constant ds = {{{0,0,'+'},{0,1,'-'},{0,2,'-'}},     -- 1               {{2,0,'+'},{2,1,'-'},{2,2,'-'}},     -- 2               {{0,0,'+'},{1,1,'\\'},{2,2,'\\'}},   -- 3               {{2,0,'+'},{1,1,'/'},{0,2,'/'}},     -- 4               {{2,0,'+'},{1,1,'/'},{0,2,'+'},                          {0,0,'+'},{0,1,'-'}},     -- 5               {{0,2,'|'},{1,2,'|'},{2,2,'|'}},     -- 6               {{0,0,'+'},{0,1,'-'},{0,2,'+'},                          {1,2,'|'},{2,2,'|'}},     -- 7               {{2,0,'+'},{2,1,'-'},{2,2,'+'},                          {1,2,'|'},{0,2,'|'}},     -- 8               {{2,0,'+'},{2,1,'-'},{2,2,'+'},                          {1,2,'|'},{0,2,'+'},                          {0,1,'-'},{0,0,'+'}}}     -- 9 function cdigit(sequence s, integer d, pos)---- s is our canvas, 7 lines of 5 characters-- d is the digit, 0..9-- pos is 4..1 for bl,br,tl,tr (easier to say/see 'backwards')--    if d then        integer ud = {+1,+1,-1,-1}[pos],                lr = {+1,-1,+1,-1}[pos],                l = {1,1,7,7}[pos]        sequence dset = ds[d]        for i=1 to length(dset) do            integer {udm, lrm, ch} = dset[i],                    tf = find(ch,`/\`)            if tf and ud!=lr then ch=`\/`[tf] end if            s[l+ud*udm][3+lr*lrm] = ch        end for    end if    return send function procedure cisterian(sequence n)    sequence res = {}    for i=1 to length(n) do        integer cn = n[i]        res = append(res,sprintf("%4d:",cn))        sequence s = repeat("  |  ",7)        integer pos = 1        while cn do            s = cdigit(s, remainder(cn,10), pos)            pos += 1            cn = floor(cn/10)        end while        res &= s    end for    puts(1,join_by(res,8,10))end procedure cisterian({0,1,2,3,4,5,6,7,8,9,20, 300, 4000, 5555, 6789, 9394, 7922, 9999})`
Output:
```   0:      1:      2:      3:      4:      5:      6:      7:      8:      9:
|       +--     |       +       | /     +-+     | |     +-+     | |     +-+
|       |       |       |\      |/      |/      | |     | |     | |     | |
|       |       +--     | \     +       +       | |     | |     +-+     +-+
|       |       |       |       |       |       |       |       |       |
|       |       |       |       |       |       |       |       |       |
|       |       |       |       |       |       |       |       |       |
|       |       |       |       |       |       |       |       |       |

20:    300:   4000:   5555:   6789:   9394:   7922:   9999:
|       |       |     +-+-+   | +-+   +-+ /     |     +-+-+
|       |       |      \|/    | | |   | |/      |     | | |
--+       |       |       +     +-+-+   +-+     --+--   +-+-+
|       |       |       |       |       |       |       |
|       | /     +       +     | | |   +-+ /   | +-+   +-+-+
|       |/     /|      /|\    | | |   | |/    | | |   | | |
|       +     / |     +-+-+   | +-+   +-+     +-+-+   +-+-+
```

## Plain English

`To run:Start up.Show some example Cistercian numbers.Wait for the escape key.Shut down. To show some example Cistercian numbers:Put the screen's left plus 1 inch into the context's spot's x.Clear the screen to the lightest gray color.Use the black color.Use the fat pen.Draw 0.Draw 1.Draw 20.Draw 300.Draw 4000.Draw 5555.Draw 6789.Draw 9394.Refresh the screen. The mirror flag is a flag. To draw a Cistercian number:Split the Cistercian number into some thousands and some hundreds and some tens and some ones.Stroke zero.Set the mirror flag.Stroke the ones.Clear the mirror flag.Stroke the tens.Turn around.Stroke the hundreds.Set the mirror flag.Stroke the thousands.Turn around.Label the Cistercian number.Move the context's spot right 1 inch. To label a Cistercian number:Save the context.Move down the half stem plus the small stem.Imagine a box with the context's spot and the context's spot.Draw "" then the Cistercian number in the center of the box with the dark gray color.Restore the context. Some tens are a number. Some ones are a number. To split a number into some thousands and some hundreds and some tens and some ones:Divide the number by 10 giving a quotient and a remainder.Put the remainder into the ones.Divide the quotient by 10 giving another quotient and another remainder.Put the other remainder into the tens.Divide the other quotient by 10 giving a third quotient and a third remainder.Put the third remainder into the hundreds.Divide the third quotient by 10 giving a fourth quotient and a fourth remainder.Put the fourth remainder into the thousands. The small stem is a length equal to 1/6 inch. The half stem is a length equal to 1/2 inch. The tail is a length equal to 1/3 inch. The slanted tail is a length equal to 6/13 inch. To stroke a number:Save the context.If the number is 1, stroke one.If the number is 2, stroke two.If the number is 3, stroke three.If the number is 4, stroke four.If the number is 5, stroke five.If the number is 6, stroke six.If the number is 7, stroke seven.If the number is 8, stroke eight.If the number is 9, stroke nine.Restore the context. To turn home:If the mirror flag is set, turn right; exit.Turn left. To turn home some fraction of the way:If the mirror flag is set, turn right the fraction; exit.Turn left the fraction. To stroke zero:Save the context.Stroke the half stem.Turn around.Move the half stem.Stroke the half stem.Restore the context. To stroke one:Move the half stem.Turn home.Stroke the tail. To stroke two:Move the small stem.Turn home.Stroke the tail. To stroke three:Move the half stem.Turn home 3/8 of the way.Stroke the slanted tail. To stroke four:Move the small stem.Turn home 1/8 of the way.Stroke the slanted tail. To stroke five:Stroke 1.Stroke 4. To stroke six:Move the half stem.Turn home.Move the tail.Turn home.Stroke the tail. To stroke seven:Stroke 1.Stroke 6. To stroke eight:Stroke 2.Stroke 6. To stroke nine:Stroke 1.Stroke 8.`
Output:

## Python

I tried to create a three-line font from UTF8 characters taking three lines per Cistercian number.

`# -*- coding: utf-8 -*-"""Some UTF-8 chars used: ‾	8254	203E	&oline;	OVERLINE┃	9475	2503	 	BOX DRAWINGS HEAVY VERTICAL╱	9585	2571	 	BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT╲	9586	2572	 	BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT◸	9720	25F8	 	UPPER LEFT TRIANGLE◹	9721	25F9	 	UPPER RIGHT TRIANGLE◺	9722	25FA	 	LOWER LEFT TRIANGLE◻	9723	25FB	 	WHITE MEDIUM SQUARE◿	9727	25FF	 	LOWER RIGHT TRIANGLE """ #%% digit sections def _init():    "digit sections for forming numbers"    digi_bits = """#0  1   2  3  4  5  6   7   8   9# .  ‾   _  ╲  ╱  ◸  .|  ‾|  _|  ◻# .  ‾   _  ╱  ╲  ◹  |.  |‾  |_  ◻# .  _  ‾   ╱  ╲  ◺  .|  _|  ‾|  ◻# .  _  ‾   ╲  ╱  ◿  |.  |_  |‾  ◻ """.strip()     lines = [[d.replace('.', ' ') for d in ln.strip().split()]             for ln in digi_bits.strip().split('\n')             if '#' not in ln]    formats = '<2 >2 <2 >2'.split()    digits = [[f"{dig:{f}}" for dig in line]              for f, line in zip(formats, lines)]     return digits _digits = _init()  #%% int to 3-line stringsdef _to_digits(n):    assert 0 <= n < 10_000 and int(n) == n     return [int(digit) for digit in f"{int(n):04}"][::-1] def num_to_lines(n):    global _digits    d = _to_digits(n)    lines = [        ''.join((_digits[1][d[1]], '┃',  _digits[0][d[0]])),        ''.join((_digits[0][   0], '┃',  _digits[0][   0])),        ''.join((_digits[3][d[3]], '┃',  _digits[2][d[2]])),        ]     return lines def cjoin(c1, c2, spaces='   '):    return [spaces.join(by_row) for by_row in zip(c1, c2)] #%% mainif __name__ == '__main__':    #n = 6666    #print(f"Arabic {n} to Cistercian:\n")    #print('\n'.join(num_to_lines(n)))     for pow10 in range(4):            step = 10 ** pow10        print(f'\nArabic {step}-to-{9*step} by {step} in Cistercian:\n')        lines = num_to_lines(step)        for n in range(step*2, step*10, step):            lines = cjoin(lines, num_to_lines(n))        print('\n'.join(lines))      numbers = [0, 5555, 6789, 6666]    print(f'\nArabic {str(numbers)[1:-1]} in Cistercian:\n')    lines = num_to_lines(numbers[0])    for n in numbers[1:]:        lines = cjoin(lines, num_to_lines(n))    print('\n'.join(lines))`
Output:
```Arabic 1-to-9 by 1 in Cistercian:

┃‾      ┃_      ┃╲      ┃╱      ┃◸      ┃ |     ┃‾|     ┃_|     ┃◻
┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃
┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃

Arabic 10-to-90 by 10 in Cistercian:

‾┃      _┃      ╱┃      ╲┃      ◹┃     | ┃     |‾┃     |_┃      ◻┃
┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃
┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃

Arabic 100-to-900 by 100 in Cistercian:

┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃
┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃
┃_      ┃‾      ┃╱      ┃╲      ┃◺      ┃ |     ┃_|     ┃‾|     ┃◻

Arabic 1000-to-9000 by 1000 in Cistercian:

┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃
┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃       ┃
_┃      ‾┃      ╲┃      ╱┃      ◿┃     | ┃     |_┃     |‾┃      ◻┃

Arabic 0, 5555, 6789, 6666 in Cistercian:

┃      ◹┃◸    |_┃◻    | ┃ |
┃       ┃       ┃       ┃
┃      ◿┃◺    | ┃_|   | ┃ |```

Note: There may be some horizontal placement issues evident in the HTML rendering between pre tags that may not be shown in the monospace rendering of a terminal (or the edit pane in firefox).
The pre tag may have to shift from one monospace font to a second that contains a character missing from the first. Those two individually monospaced fonts may have differing character widths between fonts (although consistent within individual monospaced fonts).
Paste the output into a monospace code editor and the stems of each number might well align!

## Raku

Handles 0 through 9999 only. No error trapping. If you feed it an unsupported number it will truncate to maximum 4 digits.

`my @line-segments = (0, 0, 0, 100),    (0,  0, 35,  0), (0, 35, 35, 35), (0,  0, 35, 35), (0, 35, 35,  0), ( 35,  0, 35, 35),    (0,  0,-35,  0), (0, 35,-35, 35), (0,  0,-35, 35), (0, 35,-35,  0), (-35,  0,-35, 35),    (0,100, 35,100), (0, 65, 35, 65), (0,100, 35, 65), (0, 65, 35,100), ( 35, 65, 35,100),    (0,100,-35,100), (0, 65,-35, 65), (0,100,-35, 65), (0, 65,-35,100), (-35, 65,-35,100); my @components = map {@line-segments[\$_]}, |((0, 5, 10, 15).map: -> \$m {    |((0,), (1,), (2,), (3,), (4,), (1,4), (5,), (1,5), (2,5), (1,2,5)).map: {\$_ »+» \$m}}); my \$out = 'Cistercian-raku.svg'.IO.open(:w); \$out.say: # insert headerq|<svg  width="875" height="470" style="stroke:black;" version="1.1" xmlns="http://www.w3.org/2000/svg"> <rect width="100%" height="100%" style="fill:white;"/>|; my \$hs = 50; # horizontal spacingmy \$vs = 25; # vertical spacing for flat ^10, 20, 300, 4000, 5555, 6789, 9394, (^10000).pick(14) -> \$cistercian {     \$out.say: |@components[0].map: { # draw zero / base vertical bar        qq|<line x1="{.[0] + \$hs}" y1="{.[1] + \$vs}" x2="{.[2] + \$hs}" y2="{.[3] + \$vs}"/>|    };     my @orders-of-magnitude = \$cistercian.polymod(10 xx *);     for @orders-of-magnitude.kv -> \$order, \$value {        next unless \$value; # skip zeros, already drew zero bar        last if \$order > 3; # truncate too large integers         # draw the component line segments        \$out.say: join "\n", @components[\$order * 10 + \$value].map: {            qq|<line x1="{.[0] + \$hs}" y1="{.[1] + \$vs}" x2="{.[2] + \$hs}" y2="{.[3] + \$vs}"/>|        }    }     # insert the decimal number below    \$out.say: qq|<text x="{\$hs - 5}" y="{\$vs + 120}">{\$cistercian}</text>|;     if ++\$ %% 10 { # next row        \$hs = -35;        \$vs += 150;    }     \$hs += 85; # increment horizontal spacing  }\$out.say: q|</svg>|; # insert footer`

## REXX

A fair amount of code dealt with displaying multiple Cistercian numerals on the terminal,   and also trying to present
ASCII characters that tried mimicking what a scribe might draw.

Comprehensive error checking was also included.

`/*REXX program displays a (non-negative 4-digit) integer in  Cistercian (monk) numerals.*/parse arg m                                      /*obtain optional arguments from the CL*/if m='' | m=","  then m= 0 1 20 300 4000 5555 6789 9393  /*Not specified?  Use defaults.*/\$.=;                     nnn= words(m)             do j=1  for nnn;   z= word(m, j)            /*process each of the numbers. */             if \datatype(z, 'W')  then call serr  "number isn't numeric: "           z             if \datatype(z, 'N')  then call serr  "number isn't an integer: "        z             z= z / 1                            /*normalize the number:  006  5.0  +4  */             if z<0                then call serr  "number can't be negative: "       z             if z>9999             then call serr  "number is too large (>9,999): "   z             call monk z / 1                     /*create the Cistercian quad numeral.  */             end   /*j*/call show                                        /*display   "      "       "     "     */exit 0                                           /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/@:    parse arg @x,@y;  return @.@x.@y           /*return a value from the point (@x,@y)*/quad: parse arg #;   if #\==0  then interpret 'call' #;  return       /*build a numeral.*/serr: say '***error*** '  arg(1);    exit 13                          /*issue error msg.*/app:   do r= 9 for 10 by -1; do c=-5 for 11; \$.r= \$.r||@.c.r; end; \$.r=\$.r b5; end; returneye:   do a=0  for 10; @.0.a= '│';   end; return /*build an "eye" glyph (vertical axis).*/p:     do k=1  by 3  until k>arg(); x= arg(k); y= arg(k+1); @.x.y= arg(k+2); end;   returnsect:  do q=1  for 4; call quad s.q; end; return /*build a Cistercian numeral character.*//*──────────────────────────────────────────────────────────────────────────────────────*/monk: parse arg n; n= right(n, 4, 0);  @.= ' '   /*zero─fill N;  blank─out numeral grid.*/      b4= left('', 4);  b5= b4" ";   \$.11= \$.11  ||  b4  ||  n  ||  b4  ||  b5;   call eye      parse var n s.4 2 s.3 3 s.2 4 s.1;    call sect;    call nice;    call app;   return/*──────────────────────────────────────────────────────────────────────────────────────*/nice: if @(-1, 9)=='─'     then call p 0, 9, "┐";    if @(1,9)=='─'  then call p 0, 9, "┌"      if @(-1, 9)=='─'  &  @(1,9)=='─'                               then call p 0, 9, "┬"      if @(-1, 0)=='─'     then call p 0, 0, "┘";    if @(1,0)=='─'  then call p 0, 0, "└"      if @(-1, 0)=='─'  &  @(1,0)=='─'                               then call p 0, 0, "┴"         do i=4  to 5         if @(-1, i)=='─'  then call p 0, i, "┤";    if @(1,i)=='─'  then call p 0, i, "├"         if @(-1, i)=='─'  &  @(1,i)=="─"                            then call p 0, i, "┼"         end   /*i*/;                                                               return/*──────────────────────────────────────────────────────────────────────────────────────*/show:    do jj= 11  for 10+2  by -1;    say strip(\$.jj, 'T')  /*display 1 row at a time.*/         if jj==5  then do 3;           say strip( copies(b5'│'b5 b5, nnn), 'T');     end         end   /*r*/;                   return/*──────────────────────────────────────────────────────────────────────────────────────*/1: ?= '─';  if q==1  then call p  1, 9, ?,  2, 9, ?,  3, 9, ?,  4, 9, ?,  5, 9, ?            if q==2  then call p -1, 9, ?, -2, 9, ?, -3, 9, ?, -4, 9, ?, -5, 9, ?            if q==3  then call p  1, 0, ?,  2, 0, ?,  3, 0, ?,  4, 0, ?,  5, 0, ?            if q==4  then call p -1, 0, ?, -2, 0, ?, -3, 0, ?, -4, 0, ?, -5, 0, ?;  return/*──────────────────────────────────────────────────────────────────────────────────────*/2: ?= '─';  if q==1  then call p  1, 5, ?,  2, 5, ?,  3, 5, ?,  4, 5, ?,  5, 5, ?            if q==2  then call p -1, 5, ?, -2, 5, ?, -3, 5, ?, -4, 5, ?, -5, 5, ?            if q==3  then call p  1, 4, ?,  2, 4, ?,  3, 4, ?,  4, 4, ?,  5, 4, ?            if q==4  then call p -1, 4, ?, -2, 4, ?, -3, 4, ?, -4, 4, ?, -5, 4, ?;  return/*──────────────────────────────────────────────────────────────────────────────────────*/3: ?= '\';  if q==1  then call p  1, 9, ?,  2, 8, ?,  3, 7, ?,  4, 6, ?,  5, 5, ?   ?= '/';  if q==2  then call p -1, 9, ?, -2, 8, ?, -3, 7, ?, -4, 6, ?, -5, 5, ?   ?= '/';  if q==3  then call p  1, 0, ?,  2, 1, ?,  3, 2, ?,  4, 3, ?,  5, 4, ?   ?= '\';  if q==4  then call p -5, 4, ?, -4, 3, ?, -3, 2, ?, -2, 1, ?, -1, 0, ?;  return/*──────────────────────────────────────────────────────────────────────────────────────*/4: ?= '/';  if q==1  then call p  1, 5, ?,  2, 6, ?,  3, 7, ?,  4, 8, ?,  5, 9, ?   ?= '\';  if q==2  then call p -5, 9, ?, -4, 8, ?, -3, 7, ?, -2, 6, ?, -1, 5, ?   ?= '\';  if q==3  then call p  1, 4, ?,  2, 3, ?,  3, 2, ?,  4, 1, ?,  5, 0, ?   ?= '/';  if q==4  then call p -5, 0, ?, -4, 1, ?, -3, 2, ?, -2, 3, ?, -1, 4, ?;  return/*──────────────────────────────────────────────────────────────────────────────────────*/5: ?= '/';  if q==1  then call p  1, 5, ?,  2, 6, ?,  3, 7, ?,  4, 8, ?   ?= '\';  if q==2  then call p -4, 8, ?, -3, 7, ?, -2, 6, ?, -1, 5, ?   ?= '\';  if q==3  then call p  1, 4, ?,  2, 3, ?,  3, 2, ?,  4, 1, ?   ?= '/';  if q==4  then call p -4, 1, ?, -3, 2, ?, -2, 3, ?, -1, 4, ?;  call 1;   return/*──────────────────────────────────────────────────────────────────────────────────────*/6: ?= '│';  if q==1  then call p  5, 9, ?,  5, 8, ?,  5, 7, ?,  5, 6, ?,  5, 5, ?            if q==2  then call p -5, 9, ?, -5, 8, ?, -5, 7, ?, -5, 6, ?, -5, 5, ?            if q==3  then call p  5, 0, ?,  5, 1, ?,  5, 2, ?,  5, 3, ?,  5, 4, ?            if q==4  then call p -5, 0, ?, -5, 1, ?, -5, 2, ?, -5, 3, ?, -5, 4, ?;  return/*──────────────────────────────────────────────────────────────────────────────────────*/7:          call 1;  call 6;         if q==1  then call p  5, 9, '┐'                                     if q==2  then call p -5, 9, '┌'                                     if q==3  then call p  5, 0, '┘'                                     if q==4  then call p -5, 0, '└';               return/*──────────────────────────────────────────────────────────────────────────────────────*/8:          call 2;  call 6;         if q==1  then call p  5, 5, '┘'                                     if q==2  then call p -5, 5, '└'                                     if q==3  then call p  5, 4, '┐'                                     if q==4  then call p -5, 4, '┌';               return/*──────────────────────────────────────────────────────────────────────────────────────*/9:          call 1; call 2; call 6;  if q==1  then call p  5, 5, '┘',  5, 9, "┐"                                     if q==2  then call p -5, 5, '└', -5, 9, "┌"                                     if q==3  then call p  5, 0, '┘',  5, 4, "┐"                                     if q==4  then call p -5, 0, '└', -5, 4, "┌";   return`
output   when using the default inputs:

(Shown at three-quarter size.)

```    0000             0001             0020             0300             4000             5555             6789             9393

│                ┌─────           │                │                │           ─────┬─────      │    ┌────┐      ┌────┐\
│                │                │                │                │            \   │   /       │    │    │      │    │ \
│                │                │                │                │             \  │  /        │    │    │      │    │  \
│                │                │                │                │              \ │ /         │    │    │      │    │   \
│                │           ─────┤                │                │               \│/          └────┼────┘      └────┤    \
│                │                │                │                │                │                │                │
│                │                │                │                │                │                │                │
│                │                │                │                │                │                │                │
│                │                │                │    /          /│               /│\          │    │    │      ┌────┤    /
│                │                │                │   /          / │              / │ \         │    │    │      │    │   /
│                │                │                │  /          /  │             /  │  \        │    │    │      │    │  /
│                │                │                │ /          /   │            /   │   \       │    │    │      │    │ /
│                │                │                │/          /    │           ─────┴─────      │    └────┘      └────┘/
```

## Ruby

Translation of: Lua
`def initN    n = Array.new(15){Array.new(11, ' ')}    for i in 1..15        n[i - 1][5] = 'x'    end    return nend def horiz(n, c1, c2, r)    for c in c1..c2        n[r][c] = 'x'    endend def verti(n, r1, r2, c)    for r in r1..r2        n[r][c] = 'x'    endend def diagd(n, c1, c2, r)    for c in c1..c2        n[r+c-c1][c] = 'x'    endend def diagu(n, c1, c2, r)    for c in c1..c2        n[r-c+c1][c] = 'x'    endend def initDraw    draw = []     draw[1] = lambda do |n| horiz(n, 6, 10, 0) end    draw[2] = lambda do |n| horiz(n, 6, 10, 4) end    draw[3] = lambda do |n| diagd(n, 6, 10, 0) end    draw[4] = lambda do |n| diagu(n, 6, 10, 4) end    draw[5] = lambda do |n|        draw[1].call(n)        draw[4].call(n)    end    draw[6] = lambda do |n| verti(n, 0, 4, 10) end    draw[7] = lambda do |n|        draw[1].call(n)        draw[6].call(n)    end    draw[8] = lambda do |n|        draw[2].call(n)        draw[6].call(n)    end    draw[9] = lambda do |n|        draw[1].call(n)        draw[8].call(n)    end     draw[10] = lambda do |n| horiz(n, 0, 4, 0) end    draw[20] = lambda do |n| horiz(n, 0, 4, 4) end    draw[30] = lambda do |n| diagu(n, 0, 4, 4) end    draw[40] = lambda do |n| diagd(n, 0, 4, 0) end    draw[50] = lambda do |n|        draw[10].call(n)        draw[40].call(n)    end    draw[60] = lambda do |n| verti(n, 0, 4, 0) end    draw[70] = lambda do |n|        draw[10].call(n)        draw[60].call(n)    end    draw[80] = lambda do |n|        draw[20].call(n)        draw[60].call(n)    end    draw[90] = lambda do |n|        draw[10].call(n)        draw[80].call(n)    end     draw[100] = lambda do |n| horiz(n, 6, 10, 14) end    draw[200] = lambda do |n| horiz(n, 6, 10, 10) end    draw[300] = lambda do |n| diagu(n, 6, 10, 14) end    draw[400] = lambda do |n| diagd(n, 6, 10, 10) end    draw[500] = lambda do |n|        draw[100].call(n)        draw[400].call(n)    end    draw[600] = lambda do |n| verti(n, 10, 14, 10) end    draw[700] = lambda do |n|        draw[100].call(n)        draw[600].call(n)    end    draw[800] = lambda do |n|        draw[200].call(n)        draw[600].call(n)    end    draw[900] = lambda do |n|        draw[100].call(n)        draw[800].call(n)    end     draw[1000] = lambda do |n| horiz(n, 0, 4, 14) end    draw[2000] = lambda do |n| horiz(n, 0, 4, 10) end    draw[3000] = lambda do |n| diagd(n, 0, 4, 10) end    draw[4000] = lambda do |n| diagu(n, 0, 4, 14) end    draw[5000] = lambda do |n|        draw[1000].call(n)        draw[4000].call(n)    end    draw[6000] = lambda do |n| verti(n, 10, 14, 0) end    draw[7000] = lambda do |n|        draw[1000].call(n)        draw[6000].call(n)    end    draw[8000] = lambda do |n|        draw[2000].call(n)        draw[6000].call(n)    end    draw[9000] = lambda do |n|        draw[1000].call(n)        draw[8000].call(n)    end     return drawend def printNumeral(n)    for a in n        for b in a            print b        end        print "\n"    end    print "\n"end draw = initDraw()for number in [0, 1, 20, 300, 4000, 5555, 6789, 9999]    n = initN()    print number, ":\n"     thousands = (number / 1000).floor    number = number % 1000     hundreds = (number / 100).floor    number = number % 100     tens = (number / 10).floor    ones = number % 10     if thousands > 0 then        draw[thousands * 1000].call(n)    end    if hundreds > 0 then        draw[hundreds * 100].call(n)    end    if tens > 0 then        draw[tens * 10].call(n)    end    if ones > 0 then        draw[ones].call(n)    end    printNumeral(n)end`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
xxxxxx
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
xxxxxx
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x    x
x   x
x  x
x x
xx

4000:
x
x
x
x
x
x
x
x
x
x
xx
x x
x  x
x   x
x    x

5555:
xxxxxxxxxxx
x   x   x
x  x  x
x x x
xxx
x
x
x
x
x
xxx
x x x
x  x  x
x   x   x
xxxxxxxxxxx

6789:
x    xxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
x    x    x
x    x    x
x    x    x
x    x    x
x    xxxxxx

9999:
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx
x
x
x
x
x
xxxxxxxxxxx
x    x    x
x    x    x
x    x    x
xxxxxxxxxxx```

## Wren

Library: Wren-fmt

This draws each Cistercian numeral on the terminal within a grid of 15 rows by 11 columns. The vertical line segment is drawn at column 5 (zero indexed) so there are 5 columns at either side.

`import "/fmt" for Fmt var n   var init = Fn.new {    n = List.filled(15, null)    for (i in 0..14) {        n[i] = List.filled(11, " ")        n[i][5] = "x"    }} var horiz = Fn.new { |c1, c2, r| (c1..c2).each { |c| n[r][c] = "x" } }var verti = Fn.new { |r1, r2, c| (r1..r2).each { |r| n[r][c] = "x" } }var diagd = Fn.new { |c1, c2, r| (c1..c2).each { |c| n[r+c-c1][c] = "x" } }var diagu = Fn.new { |c1, c2, r| (c1..c2).each { |c| n[r-c+c1][c] = "x" } } var draw // map contains recursive closuresdraw = {    1: Fn.new { horiz.call(6, 10, 0) },    2: Fn.new { horiz.call(6, 10, 4) },    3: Fn.new { diagd.call(6, 10, 0) },    4: Fn.new { diagu.call(6, 10, 4) },    5: Fn.new {           draw[1].call()           draw[4].call()       },    6: Fn.new { verti.call(0, 4, 10) },    7: Fn.new {           draw[1].call()           draw[6].call()       },    8: Fn.new {           draw[2].call()           draw[6].call()       },    9: Fn.new {           draw[1].call()           draw[8].call()       },    10: Fn.new { horiz.call(0, 4, 0) },    20: Fn.new { horiz.call(0, 4, 4) },    30: Fn.new { diagu.call(0, 4, 4) },    40: Fn.new { diagd.call(0, 4, 0) },    50: Fn.new {           draw[10].call()           draw[40].call()        },    60: Fn.new { verti.call(0, 4, 0) },    70: Fn.new {           draw[10].call()           draw[60].call()        },    80: Fn.new {           draw[20].call()           draw[60].call()        },    90: Fn.new {           draw[10].call()           draw[80].call()        },    100: Fn.new { horiz.call(6, 10, 14) },    200: Fn.new { horiz.call(6, 10, 10) },    300: Fn.new { diagu.call(6, 10, 14) },    400: Fn.new { diagd.call(6, 10, 10) },    500: Fn.new {            draw[100].call()            draw[400].call()         },    600: Fn.new { verti.call(10, 14, 10) },    700: Fn.new {            draw[100].call()            draw[600].call()         },    800: Fn.new {            draw[200].call()            draw[600].call()         },    900: Fn.new {            draw[100].call()            draw[800].call()         },    1000: Fn.new { horiz.call(0, 4, 14) },    2000: Fn.new { horiz.call(0, 4, 10) },    3000: Fn.new { diagd.call(0, 4, 10) },    4000: Fn.new { diagu.call(0, 4, 14) },    5000: Fn.new {             draw[1000].call()             draw[4000].call()          },    6000: Fn.new { verti.call(10, 14, 0) },    7000: Fn.new {             draw[1000].call()             draw[6000].call()          },    8000: Fn.new {             draw[2000].call()             draw[6000].call()          },    9000: Fn.new {             draw[1000].call()             draw[8000].call()          }} var numbers = [0, 1, 20, 300, 4000, 5555, 6789, 9999]for (number in numbers) {    init.call()    System.print("%(number):")    var thousands = (number/1000).floor    number = number % 1000    var hundreds  = (number/100).floor    number = number % 100    var tens = (number/10).floor    var ones = number % 10    if (thousands > 0) draw[thousands*1000].call()    if (hundreds > 0) draw[hundreds*100].call()    if (tens > 0) draw[tens*10].call()    if (ones > 0) draw[ones].call()    Fmt.mprint(n, 1, 0, "")    System.print()}`
Output:
```0:
x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

1:
x x x x x x
x
x
x
x
x
x
x
x
x
x
x
x
x
x

20:
x
x
x
x
x x x x x x
x
x
x
x
x
x
x
x
x
x

300:
x
x
x
x
x
x
x
x
x
x
x         x
x       x
x     x
x   x
x x

4000:
x
x
x
x
x
x
x
x
x
x
x x
x   x
x     x
x       x
x         x

5555:
x x x x x x x x x x x
x       x       x
x     x     x
x   x   x
x x x
x
x
x
x
x
x x x
x   x   x
x     x     x
x       x       x
x x x x x x x x x x x

6789:
x         x x x x x x
x         x         x
x         x         x
x         x         x
x x x x x x x x x x x
x
x
x
x
x
x         x         x
x         x         x
x         x         x
x         x         x
x         x x x x x x

9999:
x x x x x x x x x x x
x         x         x
x         x         x
x         x         x
x x x x x x x x x x x
x
x
x
x
x
x x x x x x x x x x x
x         x         x
x         x         x
x         x         x
x x x x x x x x x x x
```