Mayan numerals

From Rosetta Code
Task
Mayan numerals
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Present numbers using the Mayan numbering system   (displaying the Mayan numerals in a cartouche).


Mayan numbers

Normally, Mayan numbers are written vertically   (top─to─bottom)   with the most significant numeral at the top   (in the sense that decimal numbers are written left─to─right with the most significant digit at the left).   This task will be using a left─to─right (horizontal) format,   mostly for familiarity and readability,   and to conserve screen space (when showing the output) on this task page.


Mayan numerals

Mayan numerals   (a base─20 "digit" or glyph)   are written in two orientations,   this task will be using the "vertical" format   (as displayed below).   Using the vertical format makes it much easier to draw/construct the Mayan numerals (glyphs) with simple dots (.) and hyphen (-);     (however, round bullets () and long dashes () make a better presentation on Rosetta Code).


Furthermore, each Mayan numeral   (for this task)   is to be displayed as a cartouche   (enclosed in a box)   to make it easier to parse (read);   the box may be drawn with any suitable (ASCII or Unicode) characters that are presentable/visible in all web browsers.


Mayan numerals added to Unicode

Mayan numerals (glyphs) were added to the Unicode Standard in June of 2018   (this corresponds with version 11.0).   But since most web browsers don't support them at this time,   this Rosetta Code task will be constructing the glyphs with "simple" characters and/or ASCII art.


The "zero" glyph

The Mayan numbering system has the concept of   zero,   and should be shown by a glyph that represents an upside─down (sea) shell,   or an egg.   The Greek letter theta   (Θ)   can be used   (which more─or─less, looks like an egg).   A   commercial at   symbol   (@)   could make a poor substitute.


Mayan glyphs (constructed)

The Mayan numbering system is a   [vigesimal (base 20)]   positional numeral system.


The Mayan numerals   (and some random numbers)   shown in the   vertical   format would be shown as
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║    ║                            ║    ║    ║
      ║    ║                      ║ ∙  ║                            ║    ║    ║
 1──► ║    ║                11──► ║────║                      21──► ║    ║    ║
      ║ ∙  ║                      ║────║                            ║ ∙  ║ ∙  ║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║    ║                            ║    ║    ║
      ║    ║                      ║ ∙∙ ║                            ║    ║    ║
 2──► ║    ║                12──► ║────║                      22──► ║    ║    ║
      ║ ∙∙ ║                      ║────║                            ║ ∙  ║ ∙∙ ║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║    ║                            ║    ║    ║
      ║    ║                      ║∙∙∙ ║                            ║    ║    ║
 3──► ║    ║                13──► ║────║                      40──► ║    ║    ║
      ║∙∙∙ ║                      ║────║                            ║ ∙∙ ║ Θ  ║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║    ║                            ║    ║    ║
      ║    ║                      ║∙∙∙∙║                            ║    ║    ║
 4──► ║    ║                14──► ║────║                      80──► ║    ║    ║
      ║∙∙∙∙║                      ║────║                            ║∙∙∙∙║ Θ  ║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║    ║                            ║    ║    ║
      ║    ║                      ║────║                            ║    ║    ║
 5──► ║    ║                15──► ║────║                      90──► ║    ║────║
      ║────║                      ║────║                            ║∙∙∙∙║────║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║ ∙  ║                            ║    ║    ║
      ║    ║                      ║────║                            ║    ║    ║
 6──► ║ ∙  ║                16──► ║────║                     100──► ║    ║    ║
      ║────║                      ║────║                            ║────║ Θ  ║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║ ∙∙ ║                            ║    ║    ║
      ║    ║                      ║────║                            ║    ║    ║
 7──► ║ ∙∙ ║                17──► ║────║                     200──► ║────║    ║
      ║────║                      ║────║                            ║────║ Θ  ║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╗
      ║    ║                      ║∙∙∙ ║                            ║    ║    ║
      ║    ║                      ║────║                     300──► ║────║    ║
 8──► ║∙∙∙ ║                18──► ║────║                            ║────║    ║
      ║────║                      ║────║                            ║────║ Θ  ║
      ╚════╝                      ╚════╝                            ╚════╩════╝
      ╔════╗                      ╔════╗                            ╔════╦════╦════╗
      ║    ║                      ║∙∙∙∙║                            ║    ║    ║    ║
      ║    ║                      ║────║                     400──► ║    ║    ║    ║
 9──► ║∙∙∙∙║                19──► ║────║                            ║    ║    ║    ║
      ║────║                      ║────║                            ║ ∙  ║ Θ  ║ Θ  ║
      ╚════╝                      ╚════╝                            ╚════╩════╩════╝
      ╔════╗                      ╔════╦════╗                       ╔════╦════╦════╦════╗
      ║    ║                      ║    ║    ║                       ║    ║    ║    ║    ║
      ║    ║                      ║    ║    ║                       ║    ║    ║    ║    ║
10──► ║────║                20──► ║    ║    ║             16,000──► ║    ║    ║    ║    ║
      ║────║                      ║ ∙  ║ Θ  ║                       ║ ∙∙ ║ Θ  ║ Θ  ║ Θ  ║
      ╚════╝                      ╚════╩════╝                       ╚════╩════╩════╩════╝


Note that the Mayan numeral   13   in   horizontal   format would be shown as:

                                  ╔════╗
                                  ║  ││║
                                  ║ ∙││║
                            13──► ║ ∙││║        ◄─── this glyph form won't be used in this Rosetta Code task.
                                  ║ ∙││║
                                  ╚════╝


Other forms of cartouches (boxes) can be used for this task.


Task requirements
  •   convert the following decimal numbers to Mayan numbers:
  •       4,005
  •       8,017
  •   326,205
  •   886,205
  •   show a   unique   interesting/pretty/unusual/intriguing/odd/amusing/weird   Mayan number
  •   show all output here


Related tasks


See also



11l

Translation of: Nim
-V
   UL = ‘╔’
   UC = ‘╦’
   UR = ‘╗’
   LL = ‘╚’
   LC = ‘╩’
   LR = ‘╝’
   HB = ‘═’
   VB = ‘║’

   Mayan = [‘    ’,
            ‘ ∙  ’,
            ‘ ∙∙ ’,
            ‘∙∙∙ ’,
            ‘∙∙∙∙’]

   M0 = ‘ @  ’
   M5 = ‘────’

F toBase20(=n)
   V result = [n % 20]
   n I/= 20
   L n != 0
      result [+]= n % 20
      n I/= 20
   R reversed(result)

F toMayanNumeral(=d)
   V result = [Mayan[0], Mayan[0], Mayan[0], Mayan[0]]
   I d == 0
      result[3] = :M0
      R result

   L(i) (3..0).step(-1)
      I d >= 5
         result[i] = :M5
         d -= 5
      E
         result[i] = Mayan[d]
         L.break

   R result

F draw(mayans)
   V idx = mayans.len - 1

   print(:UL, end' ‘’)
   L(i) 0 .. idx
      print(:HB * 4, end' ‘’)
      I i < idx
         print(:UC, end' ‘’)
      E
         print(:UR)

   L(i) 1..4
      print(:VB, end' ‘’)
      L(j) 0 .. idx
         print(mayans[j][i - 1]‘’:VB, end' ‘’)
      print()

   print(:LL, end' ‘’)
   L(i) 0 .. idx
      print(:HB * 4, end' ‘’)
      I i < idx
         print(:LC, end' ‘’)
      E
         print(:LR)

L(n) [4005, 8017, 326205, 886205, 1081439556]
   print(‘Converting ’n‘ to Mayan:’)
   V digits = toBase20(n)
   V mayans = digits.map(d -> toMayanNumeral(d))
   draw(mayans)
   print()
Output:
Converting 4005 to Mayan:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ @  ║────║
╚════╩════╩════╝

Converting 8017 to Mayan:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ @  ║ @  ║────║
╚════╩════╩════╩════╝

Converting 326205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ @  ║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 886205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 1081439556 to Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

8080 Assembly

putch:	equ	2
puts:	equ	9
	org	100h
	lxi	h,80h	; Get length of command line input
	mov	a,m
	cpi	2
	rc		; If no input, stop
	add	l
	mov	l,a	; Go to end of numbers
	mov	c,l	; C = end of numbers
	inx	h
	mvi	m,0FFh	; Terminate digit sequence with FFh
	dcx	h
sub0:	mov	a,m
	cpi	32	; When space reached, we're at the beginning
	jz	to20
	sui	'0'	; Subtract '0' from each digit and make sure
	rc		; they are all valid
	cpi	10	
	rnc	 
	mov	m,a
	dcx 	h
	jmp	sub0
to20:	mov	a,c	; Calculate amount of numbers
	sui	81h
	mov	c,a
to20l:	mov	e,c	; E = digit counter
	mvi	l,82h	; Start at beginning
div2:	mov	a,m	; Grab digit
	jnc	$+5	; If carry, add ten
	adi	10
	rar		; Divide by two
	mov	m,a	; Write back
	inx	h
	dcr	e
	jnz	div2	; Keep going
	dcx	h	; For the last number we want
	ral		; to keep the carry
	mov	m,a	; This digit is now base-20
	dcr	c	; One fewer digit left to do
	jnz	to20l
	mvi	l,81h	; Find start and end of numbers
start:	inx	h
	mov	a,m
	ana	a
	jz	start
	mov	b,l	; B = start
	inr	a	; If number is zero, output nothing
	rz 
nend:	inx	h
	mov	a,m
	inr	a
	jnz	nend
	mov	a,l	; A = end
	sub	b
	mov	c,a	; C = amount
	call	edge
	mvi	d,3	; D=line
line:	push	b	; Save start and amount
	mov	l,b	; HL = first digit
	mvi	h,0
num:	call	dline	; Print line for digit
	inx	h	; Next digit
	dcr	c
	jnz	num
	push	d	; Save line number
	lxi	d,dn	; Print end of line
	call	print
	pop 	d	; Restore variables
	pop 	b
	dcr	d
	jp	line	; Print next line
edge:	push	b	; Print edge (top or bottom)
edge_l:	push	b	; Keep counter
	lxi	d,edges	
	call 	print
	pop	b
	dcr 	c
	jnz	edge_l
	lxi	d,edgen	
	call	print
	pop	b
	ret	
dline:	push	h	; Print line for digit (D'th from bottom)
	push	d
	push	b
	mov	a,m
	ora	d	; Line and number both 0?
	jnz	$+9
	lxi	d,dz	; Then print line with @
	jmp	dnum
	mov	a,d	; 5 * line
	add	a
	add	a
	add	d
	mov	e,a
	mov	a,m	; A -= 5 * line
	sub	e
	lxi	d,d0	; If <0, empty
	jm	dnum
	cpi	5
	jc	$+9
	lxi	d,d5	; If >=5, ----
	jmp	dnum
	add	a	; Otherwise, d[n]
	mov	l,a
	add	a
	add	l
	mov	l,a
	mvi	h,0
	dad	d
	xchg
dnum:	call	print
	pop	b
	pop	d
	pop	h
	ret		
print:	mvi	c,puts
	jmp	5
edges:	db	'+----$'
edgen:	db	'+',13,10,'$'
dz:	db	'| @  $'
d0:	db	'|    $| .  $| .. $|... $|....$'
d5:	db	'|----$'
dn:	db	'|',13,10,'$'
Output:
A>mayan 4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+

A>mayan 8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+

A>mayan 326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+

A>mayan 886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+

A>mayan 18380658207197784
+----+----+----+----+----+----+----+----+----+----+----+----+----+
|    |    |    |....|    |    |    |    |    |....|    |    |    |
|    |    |....|----|....|    |    |    |....|----|....|    |    |
|    |....|----|----|----|....|    |....|----|----|----|....|    |
|....|----|----|----|----|----|....|----|----|----|----|----|....|
+----+----+----+----+----+----+----+----+----+----+----+----+----+

Amazing Hopper

Translation of: BASIC
#include <basico.h>

algoritmo
    
    muestra=""
    obtener total argumentos
    cuando ' sea distinto a( 2 ) '{ terminar }
    obtener parámetro alfanumérico (2), guardar en 'muestra'

    lsimb={}, '"    "," .  "," .. ","... ","...."'#(utf8("────")), enlistar en 'lsimb'

    largo=0, #( largo = len(muestra))
    sdígitos={}, separar( muestra, sdígitos, "")
    ndígitos=0, #( ndígitos = number(sdígitos) )

    m=0, t=0
    #( m = largo-1)

   // convertir dígitos a base 20,la base de los mayas:
    iterar para( j=m, #(j>=1), --j )
         iterar para( i=1, #(i<=j), ++i )
              bit.and( #(ndígitos[i]), 1 ), por '10',
              guardar en 't'
              #( ndígitos[i+1] += t ) 
              #( ndígitos[i] = int(ndígitos[i]/2) )
         siguiente
    siguiente

    s=1
    iterar mientras ( #( ndígitos[s]==0 && s<largo) ) 
        ++s
    reiterar
    
    
   // armar los cartuchos: 
    imprimir ( #(utf8("╔═════")),#(replicate( utf8("═════"), largo-s) ), #(utf8("═╗")), NL,\
               #(utf8("║┌────")),#(replicate( utf8("┬────"), largo-s) ), #(utf8("┐║")), NL )
    
    n=0
    iterar para ( l=3, #(l>=0), --l )

        imprimir (#(utf8("║")))
        iterar para ( i=s, #(i<=largo), ++i )
             si ( bit.or ( #(ndígitos[i]), l ), es igual a '0' )
                 imprimir ( #(utf8("│ Θ  ")) )
                 
             sino
                 guardar ' #(ndígitos[i]-5*l) ' en 'n'
                 si ( #(n>5) )
                     n=5
                 sino si ( n, es negativo? )
                     n=0
                 fin si
                 imprimir( #(utf8("│")), #(lsimb[n+1]) )
                 
             fin si
        siguiente
        imprimir (#(utf8("│║")),NL)
        
    siguiente

    imprimir ( #(utf8("║└────")),#(replicate( utf8("┴────"), largo-s) ), #(utf8("┘║")), NL,\ 
               #(utf8("╚═════")),#(replicate( utf8("═════"), largo-s) ), #(utf8("═╝")), NL )
    saltar

terminar
Output:
$ hopper3 basica/nummaya.bas 4005
╔════════════════╗
║┌────┬────┬────┐║
║│    │    │    │║
║│    │    │    │║
║│────│    │    │║
║│────│ Θ  │────│║
║└────┴────┴────┘║
╚════════════════╝

$ hopper3 basica/nummaya.bas 8017
╔═════════════════════╗
║┌────┬────┬────┬────┐║
║│    │    │    │ .. │║
║│    │    │    │────│║
║│    │    │    │────│║
║│ .  │ Θ  │ Θ  │────│║
║└────┴────┴────┴────┘║
╚═════════════════════╝

$ hopper3 basica/nummaya.bas 326205
╔══════════════════════════╗
║┌────┬────┬────┬────┬────┐║
║│    │    │    │    │    │║
║│    │    │────│    │    │║
║│    │    │────│────│    │║
║│ .. │ Θ  │────│────│────│║
║└────┴────┴────┴────┴────┘║
╚══════════════════════════╝

$ hopper3 basica/nummaya.bas 886205
╔══════════════════════════╗
║┌────┬────┬────┬────┬────┐║
║│    │    │    │    │    │║
║│    │    │────│    │    │║
║│    │────│────│────│    │║
║│────│────│────│────│────│║
║└────┴────┴────┴────┴────┘║
╚══════════════════════════╝

$ hopper3 basica/nummaya.bas 98380658201233422
╔═══════════════════════════════════════════════════════════════════════╗
║┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐║
║│    │    │    │    │    │    │    │    │    │ .. │    │    │    │    │║
║│    │    │    │    │    │....│    │    │    │────│....│    │ .  │    │║
║│    │    │    │ .. │....│────│....│    │ .. │────│────│    │────│    │║
║│ .  │....│ Θ  │────│────│────│────│....│────│────│────│... │────│ .. │║
║└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘║
╚═══════════════════════════════════════════════════════════════════════╝

APL

Works with: Dyalog APL
mayan{
    ds6 4'     .   .. ... ....────'
    d{ =0:4 4¯14'Θ'
        ds[1+50-15 10 5 0;]
    }¨20(¯1)
    top'╔',(1↓∊(d)⍴⊂'╦════'),'╗'
    btm'╚',(1↓∊(d)⍴⊂'╩════'),'╝'
    top((⊃,/'║',¨d),'║')btm
}
Output:
      mayan 4005
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝
      mayan 8017
╔════╦════╦════╦════╗
║    ║    ║    ║ .. ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ .  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝
      mayan 326205
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ .. ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝
      mayan 886205
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝
      mayan 717784
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║....║    ║    ║
║    ║....║────║....║    ║
║....║────║────║────║....║
╚════╩════╩════╩════╩════╝
      mayan 2080000 ⍝ It's not the end of the world
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║... ║    ║    ║    ║    ║
║────║    ║    ║    ║    ║
║────║ Θ  ║ Θ  ║ Θ  ║ Θ  ║
╚════╩════╩════╩════╩════╝

AppleScript

Applescript supports only small integers (up to (2^29)-1 = 536870911).

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

-- MAYAN NUMBERS ------------------------------------------

-- mayanNumber:: Int -> [[String]]
on mayanNumber(n)
    showIntAtBase(20, my mayanDigit, n, {})
end mayanNumber

-- mayanDigit :: Int -> String
on mayanDigit(n)
    if 0 < n then
        set r to n mod 5
        bool({}, {concat(replicate(r, "●"))}, 0 < r) & ¬
            replicate(n div 5, "━━")
    else
        {"Θ"}
    end if
end mayanDigit

-- mayanFrame :: Int -> String
on mayanFrame(n)
    "Mayan " & (n as string) & ":\n" & wikiTable({|class|:¬
        "wikitable", colwidth:¬
        "3em", cell:¬
        "vertical-align:bottom;", |style|:¬
        "text-align:center;background-color:#F0EDDE;" & ¬
        "color:#605B4B;border:2px solid silver"})'s ¬
        |λ|({map(intercalateS("<br>"), mayanNumber(n))}) & "\n"
end mayanFrame

-- TEST ---------------------------------------------------

on run
    set str to unlines(map(mayanFrame, ¬
        {4005, 8017, 326205, 886205, 2978480}))
    
    set the clipboard to (str)
    return str
end run

-- GENERIC ------------------------------------------------

-- Just :: a -> Maybe a
on Just(x)
    {type:"Maybe", Nothing:false, Just:x}
end Just

-- Nothing :: Maybe a
on Nothing()
    {type:"Maybe", Nothing:true}
end Nothing

-- Tuple (,) :: a -> b -> (a, b)
on Tuple(a, b)
    {type:"Tuple", |1|:a, |2|:b, length:2}
end Tuple

-- bool :: a -> a -> Bool -> a
on bool(f, t, p)
    if p then
        t
    else
        f
    end if
end bool

-- concat :: [[a]] -> [a]
-- concat :: [String] -> String
on concat(xs)
    set lng to length of xs
    if 0 < lng and string is class of (item 1 of xs) then
        set acc to ""
    else
        set acc to {}
    end if
    repeat with i from 1 to lng
        set acc to acc & item i of xs
    end repeat
    acc
end concat

-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from 1 to lng
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldl

-- intercalateS :: String -> [String] -> String
on intercalateS(sep)
    script
        on |λ|(xs)
            set {dlm, my text item delimiters} to {my text item delimiters, sep}
            set s to xs as text
            set my text item delimiters to dlm
            return s
        end |λ|
    end script
end intercalateS

-- lookupDict :: a -> Dict -> Maybe b
on lookupDict(k, dct)
    set ca to current application
    set v to (ca's NSDictionary's dictionaryWithDictionary:dct)'s objectForKey:k
    if missing value  v then
        Just(item 1 of ((ca's NSArray's arrayWithObject:v) as list))
    else
        Nothing()
    end if
end lookupDict

-- Lift 2nd class handler function into 1st class script wrapper 
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map


-- | The 'maybe' function takes a default value, a function, and a 'Maybe'
-- value.  If the 'Maybe' value is 'Nothing', the function returns the
-- default value.  Otherwise, it applies the function to the value inside
-- the 'Just' and returns the result.
-- maybe :: b -> (a -> b) -> Maybe a -> b
on maybe(v, f, mb)
    if Nothing of mb then
        v
    else
        tell mReturn(f) to |λ|(Just of mb)
    end if
end maybe

-- quotRem :: Int -> Int -> (Int, Int)
on quotRem(m, n)
    Tuple(m div n, m mod n)
end quotRem

-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary 
-- assembly of a target length
-- replicate :: Int -> a -> [a]
on replicate(n, a)
    set out to {}
    if n < 1 then return out
    set dbl to {a}
    
    repeat while (n > 1)
        if (n mod 2) > 0 then set out to out & dbl
        set n to (n div 2)
        set dbl to (dbl & dbl)
    end repeat
    return out & dbl
end replicate

-- showIntAtBase :: Int -> (Int -> [String]) -> Int -> String -> String
on showIntAtBase(base, toDigit, n, rs)
    script showIt
        property f : mReturn(toDigit)
        on |λ|(nd_, r)
            set {n, d} to ({|1|, |2|} of nd_)
            set r_ to {f's |λ|(d)} & r
            if n > 0 then
                |λ|(quotRem(n, base), r_)
            else
                r_
            end if
        end |λ|
    end script
    showIt's |λ|(quotRem(n, base), rs)
end showIntAtBase

-- unlines :: [String] -> String
on unlines(xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set str to xs as text
    set my text item delimiters to dlm
    str
end unlines

-- unwords :: [String] -> String
on unwords(xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, space}
    set s to xs as text
    set my text item delimiters to dlm
    return s
end unwords

-- wikiTable :: Dict -> [[String]] -> String
on wikiTable(opts)
    script ksv
        on |λ|(k)
            script
                on |λ|(s)
                    script
                        on |λ|(v)
                            k & v & s
                        end |λ|
                    end script
                end |λ|
            end script
        end |λ|
    end script
    script
        on |λ|(rows)
            script boxStyle
                on |λ|(a, k)
                    maybe(a, ksv's |λ|(a & k & "=\"")'s |λ|("\" "), ¬
                        lookupDict(k, opts))
                end |λ|
            end script
            script rowText
                on |λ|(row, iRow)
                    script cellText
                        on |λ|(cell)
                            if 1 = iRow then
                                set w to maybe("", ksv's |λ|("width:")'s |λ|(";"), ¬
                                    lookupDict("colwidth", opts))
                            else
                                set w to ""
                            end if
                            set s to maybe(w, ksv's |λ|(w)'s |λ|(""), ¬
                                lookupDict("cell", opts))
                            if 0 < length of s then
                                "style=\"" & s & "\"|" & cell
                            else
                                cell
                            end if
                        end |λ|
                    end script
                    intercalateS("\n|")'s |λ|(map(cellText, row))
                end |λ|
            end script
            "{| " & unwords(foldl(boxStyle, "", {"class", "style"})) & "\n|" & ¬
                intercalateS("\n|-\n")'s |λ|(map(rowText, rows)) & "\n|}"
        end |λ|
    end script
end wikiTable
Output:

Mayan 4005:

━━
━━
Θ ━━

Mayan 8017:

Θ Θ ●●
━━
━━
━━

Mayan 326205:

●● Θ ━━
━━
━━
━━
━━
━━

Mayan 886205:

━━ ━━
━━
━━
━━
━━
━━
━━
━━

Mayan 2978480:

●●●
━━
━━
━━
●●
━━
━━

━━
●●●● Θ

Arturo

UL: ""
UC: ""
UR: ""
LL: ""
LC: ""
LR: ""
HB: ""
VB: ""

Mayan: ["    ", "", " ∙∙ ", "∙∙∙ ", "∙∙∙∙"]

M0: " Θ  "
M5: "────"

toMayan: function [digit][
    result: array.of:4 Mayan\0
    if digit = 0 [
        result\3: M0
        return result
    ]

    d: digit
    loop 3..0 'i [
        if? d >= 5 [
            result\[i]: M5
            d: d - 5
        ] 
        else [
            result\[i]: Mayan\[d]
            break
        ]
    ]
    return result
]

draw: function [mayans][
    idx: dec size mayans

    prints UL

    loop 0..idx 'i [
        loop 0..3 'j [
            prints HB
        ]
        prints (i < idx)? -> UC -> UR ++ `\n`
    ]

    loop 1..4 'i [
        prints VB
        loop 0..idx 'j ->
            prints mayans\[j]\[dec i] ++ VB
        print ""
    ]

    prints LL

    loop 0..idx 'i [
        loop 0..3 'j ->
            prints HB
        prints (i < idx)? -> LC -> LR ++ `\n`
    ]
]

loop [4005, 8017, 326205, 886205, 1081439556] 'n [
    print ["Converting" n "to Mayan:"]
    digs: digits.base:20 n
    mayans: map digs => toMayan
    draw mayans
    print ""
]
Output:
Converting 4005 to Mayan: 
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝

Converting 8017 to Mayan: 
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝

Converting 326205 to Mayan: 
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 886205 to Mayan: 
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 1081439556 to Mayan: 
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

AutoHotkey

MayanNumerals(num){
	pwr:=1, obj:=[], grid:=[]
	while (num // 20**pwr)
		pwr++	
	while --pwr
	{
		obj.Push(num // 20**pwr)
		num := Mod(num, 20**pwr)
	}
	obj.Push(num)
	cols := obj.count()
	loop % cols
	{
		c := A_Index
		loop 4
			grid[c, A_Index] := "    "
		grid[c, 4] := " Θ  "
	}
	
	for i, v in obj
	{
		j := 5
		loop % v//5
		{
			j := 5 - A_Index
			grid[i, j] := "————"
		}
		rem := ""
		loop % Mod(v, 5)
			rem .= "●"
		rem := rem = "●" ? " ●  " : rem = "●●" ? " ●● " : rem = "●●●" ? "●●● " : rem
		if Mod(v, 5)
			grid[i, j-1] := rem
	}
	return grid2table(grid, cols)
}

grid2table(grid, cols){
	loop, % cols-1
		topRow .= "════╦", bottomRow .= "════╩"
	topRow := "╔" topRow "════╗"
	bottomRow := "╚" bottomRow "════╝"
	loop % 4
	{
		r := A_Index
		loop % cols
			result .= "║" grid[A_Index, r]
		result .= "║`n"
	}
	result := topRow "`n" result . bottomRow
	return % result
}
Examples:
for i, n in [4005, 8017, 326205, 886205, 194481]
{
	x := MayanNumerals(n)
	Gui, Font, S12, Consolas
	Gui, Add, Text, , % n
	Gui, Add, Text, y+0, % x
	Gui, Show, y100
	MsgBox, 262180, , continue with next number?
	IfMsgBox, No
		ExitApp
	Gui, Destroy
}
Output:
4005			8017			326205				886205				194481
╔════╦════╦════╗	╔════╦════╦════╦════╗	╔════╦════╦════╦════╦════╗	╔════╦════╦════╦════╦════╗	╔════╦════╦════╦════╦════╗
║    ║    ║    ║	║    ║    ║    ║ ●● ║	║    ║    ║    ║    ║    ║	║    ║    ║    ║    ║    ║	║    ║    ║    ║    ║    ║
║    ║    ║    ║	║    ║    ║    ║————║	║    ║    ║————║    ║    ║	║    ║    ║————║    ║    ║	║    ║    ║    ║    ║    ║
║————║    ║    ║	║    ║    ║    ║————║	║    ║    ║————║————║    ║	║    ║————║————║————║    ║	║    ║    ║ ●  ║    ║    ║
║————║ Θ  ║————║	║ ●  ║ Θ  ║ Θ  ║————║	║ ●● ║ Θ  ║————║————║————║	║————║————║————║————║————║	║ ●  ║●●●●║————║●●●●║ ●  ║
╚════╩════╩════╝	╚════╩════╩════╩════╝	╚════╩════╩════╩════╩════╝	╚════╩════╩════╩════╩════╝	╚════╩════╩════╩════╩════╝

BASIC

10 DEFINT A-Z: DIM L$(5)
15 FOR I=0 TO 5: READ L$(I): NEXT I
20 LINE INPUT I$
30 M=LEN(I$): DIM D(M)
40 FOR I=1 TO M: D(I)=VAL(MID$(I$,I,1)): NEXT I
50 FOR J=M-1 TO 1 STEP -1
60 FOR I=1 TO J
70 D(I+1) = D(I+1) + 10*(D(I) AND 1)
80 D(I) = D(I)\2
90 NEXT I,J
100 S=1
110 IF D(S)=0 AND S<M THEN S=S+1: GOTO 110
120 FOR I=S TO M: PRINT "+----";: NEXT I: PRINT "+"
130 FOR L=3 TO 0 STEP -1
140 FOR I=S TO M
150 IF (D(I) OR L)=0 THEN PRINT "| @  ";: GOTO 180
160 N=D(I)-5*L: IF N>5 THEN N=5 ELSE IF N<0 THEN N=0
170 PRINT "|";L$(N);
180 NEXT I
190 PRINT "|"
200 NEXT L
210 FOR I=S TO M: PRINT "+----";: NEXT I: PRINT "+"
220 END
230 DATA "    "," .  "," .. ","... ","....","----"
Output:
run
4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+
Ok
run
8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+
Ok
run
326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+
Ok
run
886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+
Ok
run
18380658207197784
+----+----+----+----+----+----+----+----+----+----+----+----+----+
|    |    |    |....|    |    |    |    |    |....|    |    |    |
|    |    |....|----|....|    |    |    |....|----|....|    |    |
|    |....|----|----|----|....|    |....|----|----|----|....|    |
|....|----|----|----|----|----|....|----|----|----|----|----|....|
+----+----+----+----+----+----+----+----+----+----+----+----+----+
Ok

BCPL

get "libhdr"

let reads(v) be
$(  v%0 := 0
    $(  let ch = rdch()
        if ch = '*N' | ch = endstreamch break
        v%0 := v%0 + 1
        v%(v%0) := ch
    $) repeat
$)

let digits(v) = valof
$(  for i=1 to v%0 
    $(  unless '0' <= v%i <= '9' resultis false
        v%i := v%i - '0'
    $)
    resultis true
$)

let base20(v) be
$(  let i = ?
    for j=v%0-1 to 1 by -1
        for i=1 to j
        $(  v%(i+1) := v%(i+1) + 10*(v%i & 1)
            v%i := v%i >> 1
        $)
    i := 1
    while v%i=0 & i<v%0 do i := i+1
    for j=i to v%0 do v%(j-i+1) := v%j
    v%0 := v%0-i+1
$)

let mayan(v) be
$(  let border(n) be
    $(  for i=1 to n do writes("+----")
        writes("+*N")
    $)
    let part(num, line) be
        test num=0 do
            writes(line=0 -> " @  ", "    ")
        or
        $(  num := num - line*5
            writes(num<=0 -> "    ",
                   num =1 -> " .  ",
                   num =2 -> " .. ",
                   num =3 -> "... ",
                   num =4 -> "....",
                             "----")
        $)
    border(v%0)
    for l=3 to 0 by -1
    $(  for d=1 to v%0
        $(  wrch('|')
            part(v%d, l)
        $)
        writes("|*N")
    $)
    border(v%0)
$)

let start() be
$(  let v = vec 1+255/BYTESPERWORD
    $(  writes("Number? ")
        reads(v)
        if v%0=0 finish
        unless digits(v) loop
        base20(v)
        mayan(v)
    $) repeat
$)
Output:
Number? 4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+
Number? 8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+
Number? 326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+
Number? 886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+
Number? 114847197784
+----+----+----+----+----+----+----+----+----+
|    |    |    |    |    |....|    |    |    |
|    |    |....|    |....|----|....|    |    |
|    |....|----|....|----|----|----|....|    |
|....|----|----|----|----|----|----|----|....|
+----+----+----+----+----+----+----+----+----+

C

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define MIN(x,y) ((x) < (y) ? (x) : (y)) 

/* Find base-20 digits. */
size_t base20(unsigned int n, uint8_t *out) {
    /* generate digits */
    uint8_t *start = out;
    do {*out++ = n % 20;} while (n /= 20);
    size_t length = out - start;
    
    /* put digits in high-endian order */
    while (out > start) {
        uint8_t x = *--out;
        *out = *start;
        *start++ = x;
    }
    return length;
}

/* Write a Mayan digit */
void make_digit(int n, char *place, size_t line_length) {
    static const char *parts[] = {"    "," .  "," .. ","... ","....","----"};
    int i;

    /* write 4-part digit */
    for (i=4; i>0; i--, n -= 5)
        memcpy(place + i*line_length, parts[MAX(0, MIN(5, n))], 4);
        
    /* if digit was 0 we should put '@' in 2nd position of last line */
    if (n == -20) place[4 * line_length + 1] = '@';
}

/* Make a Mayan numeral */
char *mayan(unsigned int n) {
    if (n == 0) return NULL; 
    
    uint8_t digits[15]; /* 2**64 is 15 Mayan digits long */
    size_t n_digits = base20(n, digits);
    
    /* a digit is 4 chars wide, plus N+1 divider lines, plus a newline
       makes for a length of 5*n+2 */
    size_t line_length = n_digits*5 + 2;
    
    /* we need 6 lines - four for the digits, plus top and bottom row */
    char *str = malloc(line_length * 6 + 1);
    if (str == NULL) return NULL;
    str[line_length * 6] = 0;
    
    /* make the cartouche divider lines */
    char *ptr;
    unsigned int i;
    /* top and bottom row */
    for (ptr=str, i=0; i<line_length; i+=5, ptr+=5) 
        memcpy(ptr, "+----", 5);
    memcpy(ptr-5, "+\n", 2);
    memcpy(str+5*line_length, str, line_length);
    /* middle rows */
    for (ptr=str+line_length, i=0; i<line_length; i+=5, ptr+=5)
        memcpy(ptr, "|    ", 5);
    memcpy(ptr-5, "|\n", 2);
    memcpy(str+2*line_length, str+line_length, line_length);
    memcpy(str+3*line_length, str+line_length, 2*line_length);

    /* copy in the digits */
    for (i=0; i<n_digits; i++)
        make_digit(digits[i], str+1+5*i, line_length);

    return str;
}
        
int main(int argc, char **argv) {
    if (argc != 2) {
        fprintf(stderr, "usage: mayan <number>\n");
        return 1;
    }
    int i = atoi(argv[1]);
    if (i <= 0) {
        fprintf(stderr, "number must be positive\n");
        return 1;
    }
    char *m = mayan(i);
    printf("%s",m);
    free(m);
    return 0;
}
Output:
$ ./mayan 4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+
$ ./mayan 8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+
$ ./mayan 326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+
$ ./mayan 886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+
$ ./mayan 287959784
+----+----+----+----+----+----+----+
|    |    |....|    |....|    |    |
|    |    |----|....|----|    |    |
|    |....|----|----|----|....|    |
|....|----|----|----|----|----|....|
+----+----+----+----+----+----+----+

C++

#include <algorithm>
#include <cstdint>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

const std::vector<std::string> MAYAN_DIGITS = { " Θ  ", " ∙  ", " ∙∙ ", "∙∙∙ ", "∙∙∙∙", "────" };
const std::string BLANK = "    ";

std::unordered_map<std::string, std::string> BORDER { { "horizontal_beam", "═" }, { "vertical_beam", "║" },
	{ "lower_left", "╚" }, { "lower_central", "╩" }, { "lower_right", "╝" },
	{ "upper_left", "╔" }, { "upper_central", "╦" }, { "upper_right", "╗" }	};

std::vector<int32_t> to_base20(const int32_t& number) {
	std::vector<int32_t> result;
	result.emplace_back(number % 20);
	int32_t n = number / 20;
	while ( n != 0 ) {
		result.emplace_back(n % 20);
		n /= 20;
	}
	std::reverse(result.begin(), result.end());
	return result;
}

std::vector<std::string> to_mayan_numeral(int32_t digit) {
	std::vector<std::string> result(4, BLANK);
	if ( digit == 0 ) {
		result[3] = MAYAN_DIGITS[0];
		return result;
	}

	for ( int32_t i = 3; i >= 0; --i ) {
		if ( digit >= 5 ) {
			result[i] = MAYAN_DIGITS[5];
			digit -= 5;
		} else {
			result[i] = ( digit == 0 ) ? BLANK : MAYAN_DIGITS[digit];
			break;
		}
	}
	return result;
}

void display(const std::vector<std::vector<std::string>>& numerals) {
		const int32_t index = numerals.size() - 1;

		std::cout << BORDER["upper_left"];
		for ( int32_t i = 0; i <= index; ++i ) {
			for ( int32_t j = 0; j <= 3; ++j ) {
				std::cout << BORDER["horizontal_beam"];
			}
			if ( i < index ) {
				std::cout << BORDER["upper_central"];
			} else {
				std::cout << BORDER["upper_right"] << std::endl;
			}
		}

		for ( int32_t i = 1; i <= 4; ++i ) {
			std::cout << BORDER["vertical_beam"];
			for ( int32_t j = 0; j <= index; ++j ) {
				std::cout << numerals[j][i - 1] + BORDER["vertical_beam"];
			}
			std::cout << std::endl;
		}

		std::cout << BORDER["lower_left"];
		for ( int32_t i = 0; i <= index; ++i ) {
			for ( int32_t j = 0; j <= 3; ++j ) {
				std::cout << BORDER["horizontal_beam"];
			}
			if ( i < index ) {
				std::cout << BORDER["lower_central"];
			} else {
				std::cout << BORDER["lower_right"] << std::endl;
			}
		}
	}

int main() {
	for ( const int32_t& base10 : { 4'005, 8'017, 326'205, 886'205, 1'081'439'556 } ) {
		std::cout << "Base 10 number, " << base10 << " to Mayan:" << std::endl;
		std::vector<int32_t> digits = to_base20(base10);
		std::vector<std::vector<std::string>> mayans;
		for ( const int32_t& digit : digits ) {
			std::vector<std::string> mayan = to_mayan_numeral(digit);
			mayans.push_back(mayan);
		}
		display(mayans);
		std::cout << std::endl;
	}
}
Output:
Base 10 number, 4005 to Mayan:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝

Base 10 number, 8017 to Mayan:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝

Base 10 number, 326205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝

Base 10 number, 886205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

Base 10 number, 1081439556 to Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

CLU

% This program must be linked with PCLU's "misc.lib" and "useful.lib"

base20 = proc (n: bigint) returns (sequence[int])
    own zero: bigint := bigint$i2bi(0)
    own twenty: bigint := bigint$i2bi(20)    
    if n=zero then return(sequence[int]$[0]) end
    
    digits: array[int] := array[int]$[]
    while n>zero do
        array[int]$addl(digits, bigint$bi2i(n//twenty))
        n := n/twenty
    end
    return(sequence[int]$a2s(digits))
end base20

mayan = proc (digits: sequence[int]) returns (string)
    own parts: array[string] := array[string]$[0:
        "    ", " .  ", " .. ", "... ", "....", "----"
    ]
    % generate edges
    edge: stream := stream$create_output()
    for i: int in int$from_to(1, sequence[int]$size(digits)) do
        stream$puts(edge, "+----")
    end
    stream$putl(edge, "+")

    % generate digits
    lines: stream := stream$create_output()
    for i: int in int$from_to_by(15, 0, -5) do
        for d: int in sequence[int]$elements(digits) do
            p: int := d-i
            if p<0 then p:=0 end
            if p>5 then p:=5 end
            if i=0 & p=0
                then stream$puts(lines, "| @  ")
                else stream$puts(lines, "|" || parts[p])
            end
        end
        stream$putl(lines, "|")
    end
    
    s_edge: string := stream$get_contents(edge)
    return(s_edge || stream$get_contents(lines) || s_edge)
end mayan

start_up = proc ()
    po: stream := stream$primary_output()
    n: bigint := bigint$parse(sequence[string]$bottom(get_argv()))
    stream$puts(po, mayan(base20(n)))
end start_up
Output:
$ ./mayan 4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+

$ ./mayan 8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+

$ ./mayan 326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+

$ ./mayan 886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+

$ ./mayan 18380658207197784
+----+----+----+----+----+----+----+----+----+----+----+----+----+
|    |    |    |....|    |    |    |    |    |....|    |    |    |
|    |    |....|----|....|    |    |    |....|----|....|    |    |
|    |....|----|----|----|....|    |....|----|----|----|....|    |
|....|----|----|----|----|----|....|----|----|----|----|----|....|
+----+----+----+----+----+----+----+----+----+----+----+----+----+

Cowgol

include "cowgol.coh";
include "argv.coh";

# convert number to base 20
sub base20(n: uint32, out: [uint8]): (n_digits: uint8) is
    n_digits := 0;
    loop
        [out] := (n % 20) as uint8;
        n := n / 20;
        out := @next out;
        n_digits := n_digits + 1;
        if n == 0 then break; end if;
    end loop;
end sub;

# get the N'th line (from the top) for a Mayan digit
sub digit_line(n: uint8, line: uint8): (s: [uint8]) is
    var parts: [uint8][] := {"    "," .  "," .. ","... ","....","----"};
    if n == 0 then
        if line == 3 then s := " @  ";
        else s := parts[0];
        end if;
    else
        var nn := n - 5*(3-line);
        if nn > 128 then s := parts[0];
        elseif nn > 5 then s := parts[5];
        else s := parts[nn];
        end if;
    end if;
end sub;

# print Mayan number
sub print_mayan(n: uint32) is
    sub edge(n: uint8) is
        while n>0 loop
            print("+----");
            n := n-1;
        end loop;
        print_char('+');
        print_nl();
    end sub;
    
    var digits: uint8[8]; # 8 digits is enough for 2**32
    var size := base20(n, &digits[0]);
    
    edge(size);
    var line: uint8 := 0;
    while line < 4 loop 
        var d: uint8 := size-1;
        loop
            print_char('|');
            print(digit_line(digits[d], line));
            if d==0 then break; end if;
            d := d - 1;
        end loop;
        print_char('|');
        print_nl();
        line := line + 1;
    end loop;
    edge(size);
end sub;

sub Error() is
    print("usage: mayan <number>. number must be positive");
    print_nl();
    ExitWithError();
end sub;

# read number from command line
ArgvInit();
var arg := ArgvNext();
if arg == 0 as [uint8] then Error(); end if;
var n: int32;
(n, arg) := AToI(arg);
if n <= 0 then Error(); end if;
print_mayan(n as uint32);
Output:
$ ./mayan.386 4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+
$ ./mayan.386 8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+
$ ./mayan.386 326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+
$ ./mayan.386 886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+
$ ./mayan.386 287959784
+----+----+----+----+----+----+----+
|    |    |....|    |....|    |    |
|    |    |----|....|----|    |    |
|    |....|----|----|----|....|    |
|....|----|----|----|----|----|....|
+----+----+----+----+----+----+----+

F#

// Mayan numerals. Nigel Galloway: February 19th., 2021
let N=[|"│    ";"│.   ";"│..  ";"│... ";"│....";"│~~~~"|]
let     fN g=(fun(n)->if g=0 && n=0 then "│ Θ  " else N.[let g=g-5*n in if g>4 then 5 else if g<0 then 0 else g])
let rec fG n g=match n/20L,n%20L with (0L,0L)->(g,List.length g) |(i,n)->fG i ((fN(int n))::g)
let mayan n=let n,g=fG n []
            printf "┌────"; for _ in 2..g do printf "┬────"
            printfn "┐"; for g in 3.. -1 ..0 do n|>List.iter(fun n->printf "%s" (n(g))); printfn "│"
            printf "└────"; for _ in 2..g do printf "┴────"
            printfn "┘"
[4005L;8017L;326205L;886205L]|>List.iter(fun n->printfn "%d" n; mayan n)
Output:
4005
┌────┬────┬────┐
│    │    │    │
│    │    │    │
│~~~~│    │    │
│~~~~│ Θ  │~~~~│
└────┴────┴────┘
8017
┌────┬────┬────┬────┐
│    │    │    │..  │
│    │    │    │~~~~│
│    │    │    │~~~~│
│.   │ Θ  │ Θ  │~~~~│
└────┴────┴────┴────┘
326205
┌────┬────┬────┬────┬────┐
│    │    │    │    │    │
│    │    │~~~~│    │    │
│    │    │~~~~│~~~~│    │
│..  │ Θ  │~~~~│~~~~│~~~~│
└────┴────┴────┴────┴────┘
886205
┌────┬────┬────┬────┬────┐
│    │    │    │    │    │
│    │    │~~~~│    │    │
│    │~~~~│~~~~│~~~~│    │
│~~~~│~~~~│~~~~│~~~~│~~~~│
└────┴────┴────┴────┴────┘

Factor

USING: arrays formatting io kernel make math math.extras
sequences ;
IN: rosetta-code.mayan-numerals

: mayan-digit ( n -- m pair ) 20 /mod 5 /mod swap 2array ;

: integer>mayan ( n -- seq )
    [ [ mayan-digit , ] until-zero ] { } make reverse ;

: ones ( n -- str ) [ CHAR:  ] "" replicate-as ;
: fives ( n -- str ) [ "——" ] replicate "<br>" join ;

: numeral ( pair -- str )
    dup sum zero? [ drop "Θ" ]
    [ first2 [ ones ] [ fives ] bi* 2array harvest "<br>" join ]
    if ;

: .table-row ( pair -- )
    "|style=\"width:3em;vertical-align:bottom;\"|" write numeral
    print ;

: .table-head ( -- )
    "class=\"wikitable\" style=\"text-align:center;\"" print ;

: .table-body ( n -- ) integer>mayan [ .table-row ] each ;

: .mayan ( n -- )
    [ "Mayan %d:\n" printf ]
    [ "{|" write .table-head .table-body "|}" print ] bi ;

: mayan-numerals ( -- )
    { 4005 8017 326205 886205 } [ .mayan ] each ;

MAIN: mayan-numerals
Output:

Mayan 4005:

——
——
Θ ——

Mayan 8017:

Θ Θ ●●
——
——
——

Mayan 326205:

●● Θ ——
——
——
——
——
——

Mayan 886205:

—— ——
——
——
——
——
——
——
——

Mayan 194481:

●●●●
——
●●●●

FreeBASIC

Dim As Integer i, j, m, n, s, v
Dim As String maya(5), num
For i = 0 To 5
    Read maya(i)
Next i
Const ul = Chr(201), uc = Chr(203), ur = Chr(187), ll = Chr(200)
Const lc = Chr(202), lr = Chr(188), hb = Chr(205), vb = Chr(186)

Dim As Longint numbers(0 To ...) = {4005, 8017, 326205, 886205, 1081439556, 18380658207197784}
For v = 0 To Ubound(numbers)
    num = Str(numbers(v))
    Print "Converting"; numbers(v); " to Mayan:"
    
    m = Len(num)
    Redim As Integer D(m)
    For i = 1 To m
        D(i) = Val(Mid(num,i,1))
    Next i
    
    For j = m-1 To 1 Step -1
        For i = 1 To j
            D(i+1) += 10*(D(i) And 1)
            D(i) \= 2
        Next i
    Next j
    
    s = 1
    Do While D(s) = 0 And s < m 
        s += 1
    Loop
    
    For i = s To m
        Print Iif(i < m-1, ul+hb+hb+hb+hb, uc+hb+hb+hb+hb);
    Next i
    Print ur
    For j = 3 To 0 Step -1
        For i = s To m
            If (D(i) Or j) = 0 Then 
                Print vb + " @  ";
            Else
                n = D(i)-5*j
                If n > 5 Then 
                    n = 5 
                Elseif n < 0 Then 
                    n = 0
                End If
                Print vb; maya(n);
            End If
        Next i
        Print vb
    Next j
    For i = s To m
        Print Iif(i < m-1, ll+hb+hb+hb+hb, lc+hb+hb+hb+hb);
    Next i
    Print lr + Chr(10) '"+"
Next v
Sleep
Data "    "," .  "," .. ","... ","....","----"
Output:
Same as BASIC entry.

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.

In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.

Go

package main

import (
    "fmt"
    "strconv"
)

const (
    ul = "╔"
    uc = "╦"
    ur = "╗"
    ll = "╚"
    lc = "╩"
    lr = "╝"
    hb = "═"
    vb = "║"
)

var mayan = [5]string{
    "    ",
    " ∙  ",
    " ∙∙ ",
    "∙∙∙ ",
    "∙∙∙∙",
}

const (
    m0 = " Θ  "
    m5 = "────"
)

func dec2vig(n uint64) []uint64 {
    vig := strconv.FormatUint(n, 20)
    res := make([]uint64, len(vig))
    for i, d := range vig {
        res[i], _ = strconv.ParseUint(string(d), 20, 64)
    }
    return res
}

func vig2quin(n uint64) [4]string {
    if n >= 20 {
        panic("Cant't convert a number >= 20")
    }
    res := [4]string{mayan[0], mayan[0], mayan[0], mayan[0]}
    if n == 0 {
        res[3] = m0
        return res
    }
    fives := n / 5
    rem := n % 5
    res[3-fives] = mayan[rem]
    for i := 3; i > 3-int(fives); i-- {
        res[i] = m5
    }
    return res
}

func draw(mayans [][4]string) {
    lm := len(mayans)
    fmt.Print(ul)
    for i := 0; i < lm; i++ {
        for j := 0; j < 4; j++ {
            fmt.Print(hb)
        }
        if i < lm-1 {
            fmt.Print(uc)
        } else {
            fmt.Println(ur)
        }
    }
    for i := 1; i < 5; i++ {
        fmt.Print(vb)
        for j := 0; j < lm; j++ {
            fmt.Print(mayans[j][i-1])
            fmt.Print(vb)
        }
        fmt.Println()
    }
    fmt.Print(ll)
    for i := 0; i < lm; i++ {
        for j := 0; j < 4; j++ {
            fmt.Print(hb)
        }
        if i < lm-1 {
            fmt.Print(lc)
        } else {
            fmt.Println(lr)
        }
    }
}

func main() {
    numbers := []uint64{4005, 8017, 326205, 886205, 1081439556}
    for _, n := range numbers {
        fmt.Printf("Converting %d to Mayan:\n", n)
        vigs := dec2vig(n)
        lv := len(vigs)
        mayans := make([][4]string, lv)
        for i, vig := range vigs {
            mayans[i] = vig2quin(vig)
        }
        draw(mayans)
        fmt.Println()
    }
}
Output:
Converting 4005 to Mayan:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝

Converting 8017 to Mayan:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝

Converting 326205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 886205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 1081439556 to Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

Haskell

import Data.Bool (bool)
import Data.List (intercalate, transpose)
import qualified Data.Map.Strict as M
import Data.Maybe (maybe)

--------------------------- MAIN -------------------------
main :: IO ()
main =
  (putStrLn . unlines) $
    mayanFramed
      <$> [ 4005,
            8017,
            326205,
            886205,
            1081439556,
            1000000,
            1000000000
          ]

---------------------- MAYAN NUMBERS ---------------------
mayanGlyph :: Int -> [[String]]
mayanGlyph =
  filter (any (not . null))
    . transpose
    . leftPadded
    . flip (showIntAtBaseS 20 mayanDigit) []

mayanDigit :: Int -> [String]
mayanDigit n
  | 0 /= n =
    replicate (rem n 5) mayaOne :
    concat
      ( replicate (quot n 5) [mayaFive]
      )
  | otherwise = [[mayaZero]]

mayanFramed :: Int -> String
mayanFramed =
  ("Mayan " <>)
    . ( (<>) <$> show
          <*> ( (":\n\n" <>)
                  . wikiTable
                    ( M.fromList
                        [ ( "style",
                            concat
                              [ "text-align:center;",
                                "background-color:#F0EDDE;",
                                "color:#605B4B;",
                                "border:2px solid silver;"
                              ]
                          ),
                          ("colwidth", "3em;")
                        ]
                    )
                  . mayanGlyph
              )
      )

mayaZero, mayaOne :: Char
mayaZero = '\920'
mayaOne = '\9679'

mayaFive :: String
mayaFive = "\9473\9473"

---------------------- NUMERIC BASES ---------------------
-- Based on the Prelude showIntAtBase but uses an
-- (Int -> [String]) (rather than Int -> Char) function
-- as its second argument.
--
-- Shows a /non-negative/ 'Integral' number using the base
-- specified by the first argument, and the **String**
-- representation specified by the second.
showIntAtBaseS ::
  Integral a =>
  a ->
  (Int -> [String]) ->
  a ->
  [[String]] ->
  [[String]]
showIntAtBaseS base toStr n0 r0 =
  let go (n, d) r =
        seq s $
          case n of
            0 -> r_
            _ -> go (quotRem n base) r_
        where
          s = toStr (fromIntegral d)
          r_ = s : r
   in go (quotRem n0 base) r0

------------------------- DISPLAY ------------------------
wikiTable :: M.Map String String -> [[String]] -> String
wikiTable opts rows
  | null rows = []
  | otherwise =
    "{| "
      <> foldr
        ( \k a ->
            maybe
              a
              ( ((a <> k <> "=\"") <>)
                  . ( <> "\" "
                    )
              )
              (M.lookup k opts)
        )
        []
        ["class", "style"]
      <> ( '\n' :
           intercalate
             "|-\n"
             ( zipWith renderedRow rows [0 ..]
             )
         )
      <> "|}\n\n"
  where
    renderedRow row i =
      unlines
        ( fmap
            ( ( bool
                  []
                  ( maybe
                      "|"
                      (("|style=\"width:" <>) . (<> "\""))
                      (M.lookup "colwidth" opts)
                  )
                  (0 == i)
                  <>
              )
                . ('|' :)
            )
            row
        )

leftPadded :: [[String]] -> [[String]]
leftPadded xs =
  let w = maximum (length <$> xs)
   in ((<>) =<< flip replicate [] . (-) w . length) <$> xs
Output:

Mayan 4005:

━━
━━ Θ ━━


Mayan 8017:

●●
━━
━━
Θ Θ ━━


Mayan 326205:

━━
━━ ━━
●● Θ ━━ ━━ ━━


Mayan 886205:

━━
━━ ━━ ━━
━━ ━━ ━━ ━━ ━━


Mayan 1081439556:

●● ●●● ●●●● ●●● ●●
━━ ━━ ━━ ━━ ━━ ━━ ━━
━━ ━━ ━━ ━━ ━━ ━━ ━━
━━ ━━ ━━ ━━ ━━ ━━ ━━


Mayan 1000000:

━━ ━━ Θ Θ Θ


Mayan 1000000000:

━━ ●●
━━ ━━ ━━
━━ ━━ ━━ Θ Θ Θ Θ

J

elems =: 6 4$'     .   .. ... ....----'
digit =: (elems{~5:<.0:>.15 10 5 0-~])`((4 4$_14{.'@')&[)@.(0&=)
mayan =: ":@(digit each@(20&#.^:_1))
Output:
   mayan 4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+
   mayan 8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+
   mayan 326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+
   mayan 886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+
   mayan 717784
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |....|    |    |
|    |....|----|....|    |
|....|----|----|----|....|
+----+----+----+----+----+
   mayan 2080000
+----+----+----+----+----+
|    |    |    |    |    |
|... |    |    |    |    |
|----|    |    |    |    |
|----| @  | @  | @  | @  |
+----+----+----+----+----+
   mayan 12345678987654321
+----+----+----+----+----+----+----+----+----+----+----+----+----+
|    |    |    |    |    |    |    |    |    | .  |    | .  |    |
|    |    |    | .. |... |    |....|    | .. |----|----|----|    |
|    |    |    |----|----|    |----|    |----|----|----|----|    |
|... | @  |----|----|----| .  |----|... |----|----|----|----| .  |
+----+----+----+----+----+----+----+----+----+----+----+----+----+

Java

Unicode characters used. See Character.toChars.

import java.math.BigInteger;

public class MayanNumerals {

    public static void main(String[] args) {
        for ( long base10 : new long[] {4005, 8017, 326205, 886205, 1000000000, 1081439556L, 26960840421L, 503491211079L }) {
            displayMyan(BigInteger.valueOf(base10));
            System.out.printf("%n");
        }
    }
    
    private static char[] digits = "0123456789ABCDEFGHJK".toCharArray();
    private static BigInteger TWENTY = BigInteger.valueOf(20);
    
    private static void displayMyan(BigInteger numBase10) {
        System.out.printf("As base 10:  %s%n", numBase10);
        String numBase20 = "";
        while ( numBase10.compareTo(BigInteger.ZERO) > 0 ) {
            numBase20 = digits[numBase10.mod(TWENTY).intValue()] + numBase20;
            numBase10 = numBase10.divide(TWENTY);
        }
        System.out.printf("As base 20:  %s%nAs Mayan:%n", numBase20);
        displayMyanLine1(numBase20);
        displayMyanLine2(numBase20);
        displayMyanLine3(numBase20);
        displayMyanLine4(numBase20);
        displayMyanLine5(numBase20);
        displayMyanLine6(numBase20);
    }
 
    private static char boxUL = Character.toChars(9556)[0];
    private static char boxTeeUp = Character.toChars(9574)[0];
    private static char boxUR = Character.toChars(9559)[0];
    private static char boxHorz = Character.toChars(9552)[0];
    private static char boxVert = Character.toChars(9553)[0];
    private static char theta = Character.toChars(952)[0];
    private static char boxLL = Character.toChars(9562)[0];
    private static char boxLR = Character.toChars(9565)[0];
    private static char boxTeeLow = Character.toChars(9577)[0];
    private static char bullet = Character.toChars(8729)[0];
    private static char dash = Character.toChars(9472)[0];
    
    private static void displayMyanLine1(String base20) {
        char[] chars = base20.toCharArray();
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < chars.length ; i++ ) {
            if ( i == 0 ) {
                sb.append(boxUL);
            }
            for ( int j = 0 ; j < 4 ; j++ ) {
                sb.append(boxHorz);
            }
            sb.append(i < chars.length-1 ? boxTeeUp : boxUR);
        }
        System.out.println(sb.toString());
    }
    
    private static String getBullet(int count) {
        StringBuilder sb = new StringBuilder();
        switch ( count ) {
        case 1:  sb.append(" " + bullet + "  "); break;
        case 2:  sb.append(" " + bullet + bullet + " "); break;
        case 3:  sb.append("" + bullet + bullet + bullet + " "); break;
        case 4:  sb.append("" + bullet + bullet + bullet + bullet); break;
        default:  throw new IllegalArgumentException("Must be 1-4:  " + count);
        }
        return sb.toString();
    }

    private static void displayMyanLine2(String base20) {
        char[] chars = base20.toCharArray();
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < chars.length ; i++ ) {
            if ( i == 0 ) {
                sb.append(boxVert);
            }
            switch ( chars[i] ) {
            case 'G':  sb.append(getBullet(1)); break;
            case 'H':  sb.append(getBullet(2)); break;
            case 'J':  sb.append(getBullet(3)); break;
            case 'K':  sb.append(getBullet(4)); break;
            default :  sb.append("    ");
            }
            sb.append(boxVert);
        }
        System.out.println(sb.toString());
    }
    
    private static String DASH = getDash();
    
    private static String getDash() {
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < 4 ; i++ ) {
            sb.append(dash);
        }
        return sb.toString();
    }

    private static void displayMyanLine3(String base20) {
        char[] chars = base20.toCharArray();
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < chars.length ; i++ ) {
            if ( i == 0 ) {
                sb.append(boxVert);
            }
            switch ( chars[i] ) {
            case 'B':  sb.append(getBullet(1)); break;
            case 'C':  sb.append(getBullet(2)); break;
            case 'D':  sb.append(getBullet(3)); break;
            case 'E':  sb.append(getBullet(4)); break;
            case 'F': case 'G': case 'H': case 'J': case 'K':
                sb.append(DASH); break;
            default :  sb.append("    ");
            }
            sb.append(boxVert);
        }
        System.out.println(sb.toString());
    }

    private static void displayMyanLine4(String base20) {
        char[] chars = base20.toCharArray();
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < chars.length ; i++ ) {
            if ( i == 0 ) {
                sb.append(boxVert);
            }
            switch ( chars[i] ) {
            case '6':  sb.append(getBullet(1)); break;
            case '7':  sb.append(getBullet(2)); break;
            case '8':  sb.append(getBullet(3)); break;
            case '9':  sb.append(getBullet(4)); break;
            case 'A': case 'B': case 'C': case 'D': case 'E':
            case 'F': case 'G': case 'H': case 'J': case 'K':
                sb.append(DASH); break;
            default :  sb.append("    ");
            }
            sb.append(boxVert);
        }
        System.out.println(sb.toString());
    }

    private static void displayMyanLine5(String base20) {
        char[] chars = base20.toCharArray();
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < chars.length ; i++ ) {
            if ( i == 0 ) {
                sb.append(boxVert);
            }
            switch ( chars[i] ) {
            case '0':  sb.append(" " + theta + "  "); break;
            case '1':  sb.append(getBullet(1)); break;
            case '2':  sb.append(getBullet(2)); break;
            case '3':  sb.append(getBullet(3)); break;
            case '4':  sb.append(getBullet(4)); break;
            case '5': case '6': case '7': case '8': case '9': 
            case 'A': case 'B': case 'C': case 'D': case 'E':
            case 'F': case 'G': case 'H': case 'J': case 'K':
                sb.append(DASH); break;
            default :  sb.append("    ");
            }
            sb.append(boxVert);
        }
        System.out.println(sb.toString());
    }

    private static void displayMyanLine6(String base20) {
        char[] chars = base20.toCharArray();
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < chars.length ; i++ ) {
            if ( i == 0 ) {
                sb.append(boxLL);
            }
            for ( int j = 0 ; j < 4 ; j++ ) {
                sb.append(boxHorz);
            }
            sb.append(i < chars.length-1 ? boxTeeLow : boxLR);
        }
        System.out.println(sb.toString());
    }

}
Output:
As base 10:  4005
As base 20:  A05
As Mayan:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ θ  ║────║
╚════╩════╩════╝

As base 10:  8017
As base 20:  100H
As Mayan:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ θ  ║ θ  ║────║
╚════╩════╩════╩════╝

As base 10:  326205
As base 20:  20FA5
As Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ θ  ║────║────║────║
╚════╩════╩════╩════╩════╝

As base 10:  886205
As base 20:  5AFA5
As Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

As base 10:  1000000000
As base 20:  FCA0000
As Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║    ║    ║
║────║ ∙∙ ║    ║    ║    ║    ║    ║
║────║────║────║    ║    ║    ║    ║
║────║────║────║ θ  ║ θ  ║ θ  ║ θ  ║
╚════╩════╩════╩════╩════╩════╩════╝

As base 10:  1081439556
As base 20:  GHJKJHG
As Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

As base 10:  26960840421
As base 20:  111555111
As Mayan:
╔════╦════╦════╦════╦════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║    ║    ║    ║    ║
║    ║    ║    ║    ║    ║    ║    ║    ║    ║
║    ║    ║    ║    ║    ║    ║    ║    ║    ║
║ ∙  ║ ∙  ║ ∙  ║────║────║────║ ∙  ║ ∙  ║ ∙  ║
╚════╩════╩════╩════╩════╩════╩════╩════╩════╝

As base 10:  503491211079
As base 20:  KD71017DK
As Mayan:
╔════╦════╦════╦════╦════╦════╦════╦════╦════╗
║∙∙∙∙║    ║    ║    ║    ║    ║    ║    ║∙∙∙∙║
║────║∙∙∙ ║    ║    ║    ║    ║    ║∙∙∙ ║────║
║────║────║ ∙∙ ║    ║    ║    ║ ∙∙ ║────║────║
║────║────║────║ ∙  ║ θ  ║ ∙  ║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╩════╩════╝

JavaScript

(() => {
    'use strict';

    const main = () =>
        unlines(
            map(mayanFramed,
                [4005, 8017, 326205, 886205, 1081439556, 1000000, 1000000000]
            )
        );

    // MAYAN NUMBERS --------------------------------------

    // mayanFramed :: Int -> String
    const mayanFramed = n =>
        '\nMayan ' + n.toString() + ':\n\n' +
        wikiTable({
            style: 'text-align:center; background-color:#F0EDDE; ' +
            'color:#605B4B; border:2px solid silver',
            colwidth: '3em'
        })(
            mayanGlyph(n)
        );

    // mayanGlyph :: Int -> [[String]]
    const mayanGlyph = n =>
        filter(any(compose(not, isNull)),
            transpose(leftPadded(
                showIntAtBase(20, mayanDigit, n, [])
            ))
        );

    // mayanDigit :: Int -> [String]
    const mayanDigit = n =>
        0 !== n ? cons(
            replicateString(rem(n, 5), '●'),
            replicate(quot(n, 5), '━━')
        ) : ['Θ'];

    // FORMATTING -----------------------------------------

    // wikiTable :: Dict -> [[a]] -> String
    const wikiTable = opts => rows => {
        const colWidth = () =>
            'colwidth' in opts ? (
                '|style="width:' + opts.colwidth + ';"'
            ) : '';
        return 0 < rows.length ? (
            '{| ' + ['class', 'style'].reduce(
                (a, k) => k in opts ? (
                    a + k + '="' + opts[k] + '" '
                ) : a, ''
            ) + '\n' + rows.map(
                (row, i) => row.map(
                    x => (0 === i ? (
                        colWidth() + '| '
                    ) : '|') + (x.toString() || ' ')
                ).join('\n')
            ).join('\n|-\n') + '\n|}\n\n'
        ) : '';
    };

    // leftPadded :: [[String]] -> [[String]]
    const leftPadded = xs => {
        const w = maximum(map(length, xs));
        return map(
            x => replicate(w - x.length, '').concat(x),
            xs
        );
    };

    // GENERIC FUNCTIONS ----------------------------------

    // Tuple (,) :: a -> b -> (a, b)
    const Tuple = (a, b) => ({
        type: 'Tuple',
        '0': a,
        '1': b,
        length: 2
    });

    // any :: (a -> Bool) -> [a] -> Bool
    const any = p => xs => xs.some(p);

    // comparing :: (a -> b) -> (a -> a -> Ordering)
    const comparing = f =>
        (x, y) => {
            const
                a = f(x),
                b = f(y);
            return a < b ? -1 : (a > b ? 1 : 0);
        };

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (f, g) => x => f(g(x));

    // concatMap :: (a -> [b]) -> [a] -> [b]
    const concatMap = (f, xs) =>
        xs.reduce((a, x) => a.concat(f(x)), []);

    // cons :: a -> [a] -> [a]
    const cons = (x, xs) =>
        Array.isArray(xs) ? (
            [x].concat(xs)
        ) : 'GeneratorFunction' !== xs.constructor.constructor.name ? (
            x + xs
        ) : ( // Existing generator wrapped with one additional element
            function*() {
                yield x;
                let nxt = xs.next()
                while (!nxt.done) {
                    yield nxt.value;
                    nxt = xs.next();
                }
            }
        )();

    // filter :: (a -> Bool) -> [a] -> [a]
    const filter = (f, xs) => xs.filter(f);

    // foldl1 :: (a -> a -> a) -> [a] -> a
    const foldl1 = (f, xs) =>
        1 < xs.length ? xs.slice(1)
        .reduce(f, xs[0]) : xs[0];

    // isNull :: [a] -> Bool
    // isNull :: String -> Bool
    const isNull = xs =>
        Array.isArray(xs) || ('string' === typeof xs) ? (
            1 > xs.length
        ) : undefined;

    // Returns Infinity over objects without finite length.
    // This enables zip and zipWith to choose the shorter
    // argument when one is non-finite, like cycle, repeat etc

    // length :: [a] -> Int
    const length = xs =>
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // maximum :: Ord a => [a] -> a
    const maximum = xs =>
        0 < xs.length ? (
            foldl1((a, x) => x > a ? x : a, xs)
        ) : undefined;

    //  Ordering: (LT|EQ|GT):
    //  GT: 1 (or other positive n)
    //    EQ: 0
    //  LT: -1 (or other negative n)

    // maximumBy :: (a -> a -> Ordering) -> [a] -> a
    const maximumBy = (f, xs) =>
        0 < xs.length ? (
            xs.slice(1)
            .reduce((a, x) => 0 < f(x, a) ? x : a, xs[0])
        ) : undefined;

    // not :: Bool -> Bool
    const not = b => !b;

    // quot :: Int -> Int -> Int
    const quot = (n, m) => Math.floor(n / m);

    // quotRem :: Int -> Int -> (Int, Int)
    const quotRem = (m, n) =>
        Tuple(Math.floor(m / n), m % n);

    // rem :: Int -> Int -> Int
    const rem = (n, m) => n % m;

    // replicate :: Int -> a -> [a]
    const replicate = (n, x) =>
        Array.from({
            length: n
        }, () => x);

    // replicateString :: Int -> String -> String
    const replicateString = (n, s) => s.repeat(n);

    // showIntAtBase :: Int -> (Int -> [String])
    //               -> Int -> [[String]] -> [[String]]
    const showIntAtBase = (base, toStr, n, rs) => {
        const go = ([n, d], r) => {
            const r_ = cons(toStr(d), r);
            return 0 !== n ? (
                go(Array.from(quotRem(n, base)), r_)
            ) : r_;
        };
        return go(Array.from(quotRem(n, base)), rs);
    };

    // transpose :: [[a]] -> [[a]]
    const transpose = tbl => {
        const
            gaps = replicate(
                length(maximumBy(comparing(length), tbl)), []
            ),
            rows = map(xs => xs.concat(gaps.slice(xs.length)), tbl);
        return map(
            (_, col) => concatMap(row => [row[col]], rows),
            rows[0]
        );
    };

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // MAIN ---
    return main();
})();
Output:

Mayan 4005:

━━
━━ Θ ━━


Mayan 8017:

●●
━━
━━
Θ Θ ━━


Mayan 326205:

━━
━━ ━━
●● Θ ━━ ━━ ━━


Mayan 886205:

━━
━━ ━━ ━━
━━ ━━ ━━ ━━ ━━


Mayan 1081439556:

●● ●●● ●●●● ●●● ●●
━━ ━━ ━━ ━━ ━━ ━━ ━━
━━ ━━ ━━ ━━ ━━ ━━ ━━
━━ ━━ ━━ ━━ ━━ ━━ ━━


Mayan 1000000:

━━ ━━ Θ Θ Θ


Mayan 1000000000:

━━ ●●
━━ ━━ ━━
━━ ━━ ━━ Θ Θ Θ Θ

jq

Works with: jq

Works with gojq, the Go implementation of jq

Translation of: Wren
def m: 
{ ul: "╔",
  uc: "╦",
  ur: "╗",
  ll: "╚",
  lc: "╩",
  lr: "╝",
  hb: "═",
  vb: "║",

  m0: " Θ  ",
  m5: "────"
};
 
def mayan: [
    "    ",
    " ∙  ",
    " ∙∙ ",
    "∙∙∙ ",
    "∙∙∙∙"
];

# decimal number to base-20 array, most significant digit first
def dec2vig:
  [recurse(if . >= 20 then ./20|floor else empty end) | . % 20]
  | reverse;
  
def vig2quin:
  if . >= 20 then "Cannot convert a number >= 20." | error
  else . as $n
  | [mayan[0], mayan[0], mayan[0], mayan[0]]
  | if $n == 0
    then .[3] = m.m0
    else (($n/5)|floor) as $fives
    | ($n % 5) as $rem
    | .[3-$fives] = mayan[$rem]
    | reduce range(3; 3-$fives; -1) as $i (.; .[$i] = m.m5)
    end
  end;
 
def draw($mayans):
  ($mayans|length) as $lm
  | (reduce range(0; $lm) as $i (m.ul;
       . + m.hb * 4 + if $i < $lm - 1 then m.uc else m.ur + "\n" end ) )
    + (reduce range(1; 5) as $i ("";
         . + m.vb
         + (reduce range(0; $lm) as $j ("";
              . + $mayans[$j][$i-1] + m.vb)) + "\n" ) )
    + (reduce range(0; $lm) as $i (m.ll;
        . + (m.hb * 4) 
          + if ($i < $lm - 1) then m.lc else m.lr + "\n" end ) );

def decimal2mayan:
  "Converting \(.) to Mayan:",
  draw(dec2vig | map( vig2quin ) ),
  "" ;

4005, 8017, 326205, 886205, 1081439556
| decimal2mayan
Output:
Converting 4005 to Mayan:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝


Converting 8017 to Mayan:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝


Converting 326205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝


Converting 886205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝


Converting 1081439556 to Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

Julia

First version, using a style sheet, output to html, with the capability of proper style within the browser.

using Gumbo
 
mayan_glyphs(x, y) = (x == 0 && y == 0) ? "\n<td>Θ</td>\n" : "<td>\n" * "●" ^ x * "<br />\n───" ^ y * "</td>\n"
 
inttomayan(n) = (s = string(n, base=20); map(ch -> reverse(divrem(parse(Int, ch, base=20), 5)), split(s, "")))
 
function testmayan()
    startstring = """\n
<style>
table.roundedcorners { 
  border: 1px solid DarkOrange;
  border-radius: 13px; 
  border-spacing: 1;
  }
table.roundedcorners td, 
table.roundedcorners th { 
  border: 2px solid DarkOrange;
  border-radius: 13px; 
  border-bottom: 3px solid DarkOrange;
  vertical-align: bottom;
  text-align: center;
  padding: 10px; 
  }
</style>
\n"""
 
    txt = startstring
 
    for n in [4005, 8017, 326205, 886205, 70913241, 2147483647]
    txt *= "<h3>The Mayan representation for the integer $n is: </h3><table class=\"roundedcorners\"><tr>" *
            join(map(x -> mayan_glyphs(x[1], x[2]), inttomayan(n))) * "</tr></table>\n\n"
    end
 
    println(parsehtml(txt))
end

testmayan()

Version 2, using local wiki style table formatting: translation of style code from the Raku version.

mayan_glyphs(x, y) = (x == 0 && y == 0) ? "\n| style=$tdconfig | Θ" : "\n| style=$tdconfig | " * "●" ^ x * "<br>───" ^ y

inttomayan(n) = (s = string(n, base=20); map(ch -> reverse(divrem(parse(Int, ch, base=20), 5)), split(s, "")))

tableconfig = raw""" " border: 1px solid DarkOrange;   border-radius: 13px;   border-spacing: 1; " """
tdconfig = raw""" "border: 2px solid DarkOrange; border-radius: 13px; border-bottom: 2px solid DarkOrange; vertical-align: bottom; text-align: center; padding: 10px;" """

function testmayan()
    txt = ""
    for n in [4005, 8017, 326205, 886205, 70913241, 2147483647]
        txt *= "\n'''The Mayan representation for the integer $n is:'''\n" *
               "{| style=$tableconfig \n|- " *
               join(map(x -> mayan_glyphs(x[1], x[2]), inttomayan(n))) * "\n|}\n\n"
    end
    println(txt)
end

testmayan()
Output:

The Mayan representation for the integer 4005 is:


───
───
Θ
───


The Mayan representation for the integer 8017 is:

Θ Θ ●●
───
───
───


The Mayan representation for the integer 326205 is:

●● Θ
───
───
───

───
───

───


The Mayan representation for the integer 886205 is:


───

───
───

───
───
───

───
───

───


The Mayan representation for the integer 70913241 is:

●● ●●● ●●●● ●●● ●●


The Mayan representation for the integer 2147483647 is:

●●●
───
───

───
───

───
───
───
●●●●
───
●● ●●
───

Mathematica/Wolfram Language

ClearAll[MakeLengthFive, MayanNumeral]
MakeLengthFive[ci_String] := Module[{c},
  c = If[EvenQ[StringLength[ci]], ci <> " ", ci];
  While[StringLength[c] < 5, c = " " <> c <> " "];
  c
  ]
MayanNumeral[n_Integer?Positive] := Module[{nums, q, r, c},
  nums = IntegerDigits[n, 20];
  Row[Table[
    {q, r} = QuotientRemainder[m, 5];
    If[{q, r} =!= {0, 0},
     c = Prepend[ConstantArray["-----", q], StringJoin[ConstantArray[".", r]]];
     c = Join[ConstantArray["", 4 - Length[c]], c];
     c
     ,
     c = {"", "", "", "\[Theta]"}
     ];
    Column[MakeLengthFive /@ c, Frame -> True]
    ,
    {m, nums}
    ], Spacer[1]]
  ]
MayanNumeral[4005]
MayanNumeral[8017]
MayanNumeral[326205]
MayanNumeral[886205]
MayanNumeral[1337]
Output:

Outputs a graphical representation of the cartouches.

Nim

Translation of: Go

Free adaptation of the Go version.

import algorithm

type Border = enum UL = "╔", UC = "╦", UR = "╗", LL = "╚", LC = "╩", LR = "╝", HB = "═", VB = "║"

const

  Mayan = ["    ", " ∙  ", " ∙∙ ", "∙∙∙ ", "∙∙∙∙"]

  M0 = " Θ  "
  M5 = "────"

type
  Digit = range[0..19]
  Numeral = array[4, string]
  MayanNumber = seq[Numeral]


func toBase20(n: Natural): seq[Digit] =
  ## Return "n" expressed as a sequence of base 20 digits.
  result.add(n mod 20)
  var n = n div 20
  while n != 0:
    result.add n mod 20
    n = n div 20
  result.reverse()


func toMayanNumeral(d: Digit): Numeral =
  ## Return the Numeral representing a base 20 digits.

  result = [Mayan[0], Mayan[0], Mayan[0], Mayan[0]]
  if d == 0:
    result[3] = M0
    return

  var d = d
  for i in countdown(3, 0):
    if d >= 5:
      result[i] = M5
      dec d, 5
    else:
      result[i] = Mayan[d]
      break


proc draw(mayans: MayanNumber) =
  ## Draw the representation fo a mayan number.

  let idx = mayans.high

  stdout.write UL
  for i in 0..idx:
    for j in 0..3: stdout.write HB
    if i < idx: stdout.write UC else: echo UR

  for i in 1..4:
    stdout.write VB
    for j in 0..idx: stdout.write mayans[j][i-1], VB
    stdout.write '\n'

  stdout.write LL
  for i in 0..idx:
    for j in 0..3: stdout.write HB
    if i < idx: stdout.write LC else: echo LR


when isMainModule:

  import sequtils, strutils

  for n in [4005, 8017, 326205, 886205, 1081439556]:
    echo "Converting $1 to Mayan:".format(n)
    let digits = n.toBase20()
    let mayans = digits.mapIt(it.toMayanNumeral)
    mayans.draw()
    echo ""
Output:
Converting 4005 to Mayan:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝

Converting 8017 to Mayan:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝

Converting 326205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 886205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 1081439556 to Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

Perl

Translation of: Raku
Library: ntheory
use ntheory qw/fromdigits todigitstring/;

my $t_style = '"border-collapse: separate; text-align: center; border-spacing: 3px 0px;"';
my $c_style = '"border: solid black 2px;background-color: #fffff0;border-bottom: double 6px;'.
  'border-radius: 1em;-moz-border-radius: 1em;-webkit-border-radius: 1em;'.
  'vertical-align: bottom;width: 3.25em;"';

sub cartouches {
    my($num, @digits) = @_;
    my $render;
    for my $d (@digits) {
        $render .= "| style=$c_style | $_\n" for glyphs(@$d);
    }
    chomp $render;
    join "\n", "\{| style=$t_style", "|+ $num", '|-', $render, '|}'
}

sub glyphs {
    return 'Θ' unless $_[0] || $_[1];
    join '<br>', '●' x $_[0], ('───') x $_[1];
}

sub mmod {
    my($n,$b) = @_;
    my @nb;
    return 0 unless $n;
    push @nb, fromdigits($_, $b) for split '', todigitstring($n, $b);
    return @nb;
}

for $n (qw<4005 8017 326205 886205 26960840421>) {
    push @output, cartouches($n, map { [reverse mmod($_,5)] } mmod($n,20) );
}

print join "\n<br>\n", @output;
Output:
4005

───
───
Θ
───


8017
Θ Θ ●●
───
───
───


326205
●● Θ
───
───
───

───
───

───


886205

───

───
───

───
───
───

───
───

───


26960840421

───

───

───

PL/M

/* MAYAN NUMERALS IN PL/M
   
   THIS PROGRAM RUNS UNDER CP/M AND TAKES THE NUMBER ON THE COMMAND LINE */
100H:
/* CP/M CALLS */
BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;

/* CP/M COMMAND LINE */
DECLARE CL$PTR ADDRESS INITIAL (80H), CMD$LEN BASED CL$PTR BYTE;
DECLARE CMD$PTR ADDRESS INITIAL (81H), CMD$LINE BASED CMD$PTR BYTE;

/* THE PIPE AND AT SYMBOLS ARE NOT INCLUDED IN THE PL/M CHARSET */
DECLARE PIPE LITERALLY '7CH', AT LITERALLY '40H';

/* PRINT BORDER FOR N DIGITS */
BORDER: PROCEDURE (N);
    DECLARE (I, N) BYTE;
    DO I=1 TO N;
        CALL PRINT(.'+----$');
    END;
    CALL PRINT(.('+',13,10,'$'));
END BORDER;

/* PRINT LINE FOR GIVEN DIGIT */
DIGIT$LINE: PROCEDURE (LINE, DIGIT);
    DECLARE (I, LINE, DIGIT, UPB) BYTE;
    DECLARE PARTS (6) ADDRESS;
    PARTS(0) = .(PIPE,'    $'); PARTS(1) = .(PIPE,' .  $');
    PARTS(2) = .(PIPE,' .. $'); PARTS(3) = .(PIPE,'... $');
    PARTS(4) = .(PIPE,'....$'); PARTS(5) = .(PIPE,'----$');
    
    IF DIGIT = 0 THEN DO;
        IF LINE = 3 THEN CALL PRINT(.(PIPE,' ',AT,'  $'));
        ELSE CALL PRINT(PARTS(0));
    END;
    ELSE DO;
        UPB = 15-LINE*5;
        IF DIGIT < UPB THEN CALL PRINT(PARTS(0));
        ELSE IF DIGIT >= UPB+5 THEN CALL PRINT(PARTS(5));
        ELSE CALL PRINT(PARTS(DIGIT-UPB));
    END;
END DIGIT$LINE;

/* PRINT LINE GIVEN DIGITS */
LINE: PROCEDURE (L, DIGITS, NDIGITS);
    DECLARE DIGITS ADDRESS;
    DECLARE (L, I, D BASED DIGITS, NDIGITS) BYTE;
    DO I=0 TO NDIGITS-1;
        CALL DIGIT$LINE(L, D(I));
    END;
    CALL PRINT(.(PIPE,13,10,'$'));
END LINE;

/* CHECK FOR ARGUMENT */
IF CMD$LEN < 2 THEN DO;
    CALL PRINT(.'NO INPUT$');
    CALL EXIT;
END;

/* PREPROCESS COMMAND LINE - TURN EACH ASCII DIGIT INTO 0-9 */
DECLARE (I, J) BYTE;
DO I = 1 TO CMD$LEN-1;
    CMD$LINE(I) = CMD$LINE(I) - '0';
    IF CMD$LINE(I) > 9 THEN DO;
        /* ERROR MESSAGE FOR INVALID INPUT */
        CALL PRINT(.'INVALID DIGIT IN INPUT$');
        CALL EXIT;
    END;
END;

/* CONVERT TO BASE 20 DIGIT BY DIGIT */
J = CMD$LEN-2;
DO WHILE J > 0;
    DO I = 1 TO J;
        CMD$LINE(I+1) = CMD$LINE(I+1) + 10*(CMD$LINE(I) AND 1);
        CMD$LINE(I) = CMD$LINE(I) / 2;
    END;
    J = J - 1;
END;

/* FIND FIRST NONZERO DIGIT */
J = 1;
DO WHILE CMD$LINE(J) = 0 AND J < CMD$LEN-1;
    J = J + 1;
END;

/* PRINT CARTOUCHES */
DECLARE SIZE BYTE;
SIZE = CMD$LEN-J;
CALL BORDER(SIZE);
DO I=0 TO 3;
    CALL LINE(I, .CMD$LINE(J), SIZE);
END;
CALL BORDER(SIZE);

CALL EXIT;
EOF
Output:
A>MAYAN 4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+

A>MAYAN 8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+

A>MAYAN 326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+

A>MAYAN 886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+

A>MAYAN 18380658207197784
+----+----+----+----+----+----+----+----+----+----+----+----+----+
|    |    |    |....|    |    |    |    |    |....|    |    |    |
|    |    |....|----|....|    |    |    |....|----|....|    |    |
|    |....|----|----|----|....|    |....|----|----|----|....|    |
|....|----|----|----|----|----|....|----|----|----|----|----|....|
+----+----+----+----+----+----+----+----+----+----+----+----+----+

Phix

Translation of: Raku

Three-way output controlled by the first two constants.

-- demo\rosetta\Mayan_numerals.exw
without js -- (file i/o [when as_html is true])
constant as_html = true,        -- false == nasty ascii
         inline_css = true      -- also uses wiki tables ({| etc) if false

string html = ""

constant t_style = "border-collapse: separate; text-align: center; border-spacing: 3px 0px;",
         c_style = "border: solid black 2px;background-color: #fffff0;border-bottom: double 6px;"&
                   "border-radius: 1em;-moz-border-radius: 1em;-webkit-border-radius: 1em;"&
                   "vertical-align: bottom;width: 3.25em;",
         dot = "●",
         bar = "───",
         zero = "Θ",
         digits = {" 0  "," .  "," .. ","... ","...."} 

function to_seq(atom a)
    sequence s = {}
    while true do
        s = prepend(s,remainder(a,20))
        a = floor(a/20)
        if a=0 then exit end if
    end while
    return s
end function

procedure show_mayan(atom a)
    sequence s = to_seq(a)
    if not as_html then
        string tb = join(repeat('+',length(s)+1),"------"),
               ln = join(repeat('|',length(s)+1),"      ")
        sequence res = {tb,ln,ln,ln,ln,tb}
        for i=1 to length(s) do
            integer si = s[i], l = 5, m = i*7-4
            while true do
                res[l][m..m+3] = digits[min(si+1,5)]
                si -= 5
                if si<=0 then exit end if
                l -= 1
            end while
        end for
        printf(1,"%d\n%s\n\n",{a,join(res,"\n")})
    else
        for i=1 to length(s) do
            sequence res = repeat("",4)
            integer si = s[i], l = 4
            while true do
                res[l] = iff(si>=5?bar:iff(si?join(repeat(dot,si),""):zero))
                si -= 5
                if si<=0 then exit end if
                l -= 1
            end while
            s[i] = join(res,"<br>")
        end for
        if inline_css then
            html &= sprintf("  <table>\n   <caption>%d</caption>\n   <tr>\n",a)
            for i=1 to length(s) do
                html &= sprintf("    <td>%s</td>\n",{s[i]})
            end for
            html &= "   </tr>\n  </table>\n"
        else
            html &= sprintf("{| style=\"%s\"\n|+ %d\n|-\n",{t_style,a})
            for i=1 to length(s) do
                html &= sprintf("| style=\"%s\" | %s\n",{c_style,s[i]})
            end for
            html &= "|}\n"
        end if
    end if
end procedure

constant html_header = """
<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Mayan numerals</title>
  <style>
    table {%s}
    td { %s }
  </style>
 </head>
 <body>
  <h2>Mayan numerals</h2>
""",
wiki_header = """
The following is intended to be pasted into the rosettacode wiki, or similar<br>
""",
html_footer = """
 </body>
</html>
"""

constant tests = {4005, 8017, 326205, 886205, 26960840421, 126524984376952}

for i=1 to length(tests) do show_mayan(tests[i]) end for

if as_html then
    string filename = "Mayan_numerals.html"
    integer fn = open(filename,"w")
    if inline_css then
        printf(fn,html_header,{t_style,c_style})
    else
        printf(fn,wiki_header)
    end if
    puts(fn,html)
    if inline_css then
        puts(fn,html_footer)
    end if
    close(fn)
    if inline_css then
        system(filename)
    else
        printf(1,"See %s\n",{filename})
        {} = wait_key()
    end if
else
    ?"done"
    {} = wait_key()
end if
Output:

With inline_css set to false. Note these are always height-4.

4005


───
───



Θ



───
8017






Θ



Θ
●●
───
───
───
326205



●●



Θ

───
───
───


───
───



───
886205



───


───
───

───
───
───


───
───



───
26960840421












───



───



───









126524984376952

●●
───
───


●●
───



●●


●●
───

●●
───
───
●●
───
───
───

●●
───
───


●●
───



●●


●●
───

●●
───
───


Output:

With inline_css set to true. As noted on the Raku entry, this is much neater, but does not display nicely on this page.
(These captions are centred; to exactly match the above just add a simple caption {text-align: left;} in the style section.)

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8" />
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Mayan numerals</title>
  <style>
    table {border-collapse: separate; text-align: center; border-spacing: 3px 0px;}
    td { border: solid black 2px;background-color: #fffff0;border-bottom: double 6px;border-radius: 1em;
         -moz-border-radius: 1em;-webkit-border-radius: 1em;vertical-align: bottom;width: 3.25em; }
  </style>
 </head>
 <body>
  <h2>Mayan numerals</h2>
  <table>
   <caption>4005</caption>
   <tr>
    <td><br><br>───<br>───</td>
    <td><br><br><br>Θ</td>
    <td><br><br><br>───</td>
   </tr>
  </table>
  <table>
   <caption>8017</caption>
   <tr>
    <td><br><br><br>●</td>
    <td><br><br><br>Θ</td>
    <td><br><br><br>Θ</td>
    <td>●●<br>───<br>───<br>───</td>
   </tr>
  </table>
  <table>
   <caption>326205</caption>
   <tr>
    <td><br><br><br>●●</td>
    <td><br><br><br>Θ</td>
    <td><br>───<br>───<br>───</td>
    <td><br><br>───<br>───</td>
    <td><br><br><br>───</td>
   </tr>
  </table>
  <table>
   <caption>886205</caption>
   <tr>
    <td><br><br><br>───</td>
    <td><br><br>───<br>───</td>
    <td><br>───<br>───<br>───</td>
    <td><br><br>───<br>───</td>
    <td><br><br><br>───</td>
   </tr>
  </table>
  <table>
   <caption>26960840421</caption>
   <tr>
    <td><br><br><br>●</td>
    <td><br><br><br>●</td>
    <td><br><br><br>●</td>
    <td><br><br><br>───</td>
    <td><br><br><br>───</td>
    <td><br><br><br>───</td>
    <td><br><br><br>●</td>
    <td><br><br><br>●</td>
    <td><br><br><br>●</td>
   </tr>
  </table>
  <table>
   <caption>126524984376952</caption>
   <tr>
    <td><br>●●<br>───<br>───</td>
    <td><br><br>●●<br>───</td>
    <td><br><br><br>●●</td>
    <td><br><br>●●<br>───</td>
    <td><br>●●<br>───<br>───</td>
    <td>●●<br>───<br>───<br>───</td>
    <td><br>●●<br>───<br>───</td>
    <td><br><br>●●<br>───</td>
    <td><br><br><br>●●</td>
    <td><br><br>●●<br>───</td>
    <td><br>●●<br>───<br>───</td>
   </tr>
  </table>
 </body>
</html>
Output:

With output_html set to false.

4005
+------+------+------+
|      |      |      |
|      |      |      |
| .... |      |      |
| .... |  0   | .... |
+------+------+------+

8017
+------+------+------+------+
|      |      |      |  ..  |
|      |      |      | .... |
|      |      |      | .... |
|  .   |  0   |  0   | .... |
+------+------+------+------+

326205
+------+------+------+------+------+
|      |      |      |      |      |
|      |      | .... |      |      |
|      |      | .... | .... |      |
|  ..  |  0   | .... | .... | .... |
+------+------+------+------+------+

886205
+------+------+------+------+------+
|      |      |      |      |      |
|      |      | .... |      |      |
|      | .... | .... | .... |      |
| .... | .... | .... | .... | .... |
+------+------+------+------+------+

26960840421
+------+------+------+------+------+------+------+------+------+
|      |      |      |      |      |      |      |      |      |
|      |      |      |      |      |      |      |      |      |
|      |      |      |      |      |      |      |      |      |
|  .   |  .   |  .   | .... | .... | .... |  .   |  .   |  .   |
+------+------+------+------+------+------+------+------+------+

126524984376952
+------+------+------+------+------+------+------+------+------+------+------+
|      |      |      |      |      |  ..  |      |      |      |      |      |
|  ..  |      |      |      |  ..  | .... |  ..  |      |      |      |  ..  |
| .... |  ..  |      |  ..  | .... | .... | .... |  ..  |      |  ..  | .... |
| .... | .... |  ..  | .... | .... | .... | .... | .... |  ..  | .... | .... |
+------+------+------+------+------+------+------+------+------+------+------+

PureBasic

#START_X=-4 : #START_Y=2
Dim pl$(5)
pl$(0)=" Θ  " : pl$(1)=" •  " : pl$(2)=" •• "
pl$(3)="••• " : pl$(4)="••••" : pl$(5)="‒‒‒‒"
If OpenConsole() : EnableGraphicalConsole(1) : Else : End 1 : EndIf

Procedure.s Dec2Mayan(wert.i)
  result$=""
  If wert=0 : result$="0;" : EndIf
  While wert : result$=Str(wert%20)+";"+result$ : wert/20 : Wend
  ProcedureReturn result$
EndProcedure

Procedure PutMayan(may$)
  Shared pl$()
  X=#START_X+6 : Y=#START_Y
  For i=1 To CountString(may$,";")
    m=Val(StringField(may$,i,";"))
    yp=Y+4
    If m=0 : ConsoleLocate(X,yp) : Print(pl$(0)) : X+5 : Continue : EndIf
    While m
      If m-5>=0
        ConsoleLocate(X,yp) : Print(pl$(5)) : yp-1 : m-5
      ElseIf m-4>=0
        ConsoleLocate(X,yp) : Print(pl$(4)) : yp-1 : m-4
      ElseIf m-3>=0
        ConsoleLocate(X,yp) : Print(pl$(3)) : yp-1 : m-3
      ElseIf m-2>=0
        ConsoleLocate(X,yp) : Print(pl$(2)) : yp-1 : m-2
      ElseIf m-1>=0
        ConsoleLocate(X,yp) : Print(pl$(1)) : yp-1 : m-1        
      EndIf
    Wend
    X+5
  Next  
EndProcedure

Procedure MayanNumerals(may$)
  X=#START_X : Y=#START_Y
  m.i=CountString(may$,";")
  For i=1 To m
    X+5
    ConsoleLocate(X,Y)    : Print("╔════╗")    
    ConsoleLocate(X,Y+1)  : Print("║    ║")
    ConsoleLocate(X,Y+2)  : Print("║    ║")
    ConsoleLocate(X,Y+3)  : Print("║    ║")
    ConsoleLocate(X,Y+4)  : Print("║    ║")
    ConsoleLocate(X,Y+5)  : Print("╚════╝")    
  Next
  X=#START_X
  For i=1 To m
    X+5
    If i<m 
      ConsoleLocate(X+5,Y)   : Print("╦") 
      ConsoleLocate(X+5,Y+5) : Print("╩")
    EndIf    
  Next 
  PutMayan(may$)
EndProcedure

Repeat
  ConsoleLocate(0,0)          : Print(LSet(" ",60))
  ConsoleLocate(0,0)          : Print("MAYAN: ? ") : i$=Input()
  ClearConsole()              : If i$="" : End : EndIf
  j$=Dec2Mayan(Val(i$))       : MayanNumerals(j$)  
  ConsoleLocate(0,#START_Y+7) : Print("Dezimal  = "+i$)
  ConsoleLocate(0,#START_Y+8) : Print("Vigesimal= "+j$)
ForEver
Output:
MAYAN: ?                                                    
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║‒‒‒‒║    ║    ║
║‒‒‒‒║ Θ  ║‒‒‒‒║
╚════╩════╩════╝

Dezimal  = 4005
Vigesimal= 10;0;5;

MAYAN: ?                                                    
╔════╦════╦════╦════╗
║    ║    ║    ║ •• ║
║    ║    ║    ║‒‒‒‒║
║    ║    ║    ║‒‒‒‒║
║ •  ║ Θ  ║ Θ  ║‒‒‒‒║
╚════╩════╩════╩════╝

Dezimal  = 8017
Vigesimal= 1;0;0;17;

MAYAN: ?                                                    
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║‒‒‒‒║    ║    ║
║    ║    ║‒‒‒‒║‒‒‒‒║    ║
║ •• ║ Θ  ║‒‒‒‒║‒‒‒‒║‒‒‒‒║
╚════╩════╩════╩════╩════╝

Dezimal  = 326205
Vigesimal= 2;0;15;10;5;

MAYAN: ?                                                    
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║‒‒‒‒║    ║    ║
║    ║‒‒‒‒║‒‒‒‒║‒‒‒‒║    ║
║‒‒‒‒║‒‒‒‒║‒‒‒‒║‒‒‒‒║‒‒‒‒║
╚════╩════╩════╩════╩════╝

Dezimal  = 886205
Vigesimal= 5;10;15;10;5;

Python

Works with: Python version 3.7
'''Mayan numerals'''

from functools import (reduce)


# -------------------- MAYAN NUMERALS --------------------

# mayanNumerals :: Int -> [[String]]
def mayanNumerals(n):
    '''Rows of Mayan digit cells,
       representing the integer n.
    '''
    return showIntAtBase(20)(
        mayanDigit
    )(n)([])


# mayanDigit :: Int -> [String]
def mayanDigit(n):
    '''List of strings representing a Mayan digit.'''
    if 0 < n:
        r = n % 5
        return [
            (['●' * r] if 0 < r else []) +
            (['━━'] * (n // 5))
        ]
    else:
        return ['Θ']


# mayanFramed :: Int -> String
def mayanFramed(n):
    '''Mayan integer in the form of a
       Wiki table source string.
    '''
    return 'Mayan ' + str(n) + ':\n\n' + (
        wikiTable({
            'class': 'wikitable',
            'style': cssFromDict({
                'text-align': 'center',
                'background-color': '#F0EDDE',
                'color': '#605B4B',
                'border': '2px solid silver'
            }),
            'colwidth': '3em',
            'cell': 'vertical-align: bottom;'
        })([[
            '<br>'.join(col) for col in mayanNumerals(n)
        ]])
    )


# ------------------------- TEST -------------------------

# main :: IO ()
def main():
    '''Mayan numeral representations of various integers'''
    print(
        main.__doc__ + ':\n\n' +
        '\n'.join(mayanFramed(n) for n in [
            4005, 8017, 326205, 886205, 1081439556,
            1000000, 1000000000
        ])
    )


# ------------------------ BOXES -------------------------

# wikiTable :: Dict -> [[a]] -> String
def wikiTable(opts):
    '''Source text for wiki-table display of rows of cells,
       using CSS key-value pairs in the opts dictionary.
    '''
    def colWidth():
        return 'width:' + opts['colwidth'] + '; ' if (
            'colwidth' in opts
        ) else ''

    def cellStyle():
        return opts['cell'] if 'cell' in opts else ''

    return lambda rows: '{| ' + reduce(
        lambda a, k: (
            a + k + '="' + opts[k] + '" ' if (
                k in opts
            ) else a
        ),
        ['class', 'style'],
        ''
    ) + '\n' + '\n|-\n'.join(
        '\n'.join(
            ('|' if (
                0 != i and ('cell' not in opts)
            ) else (
                '|style="' + colWidth() + cellStyle() + '"|'
            )) + (
                str(x) or ' '
            ) for x in row
        ) for i, row in enumerate(rows)
    ) + '\n|}\n\n'


# ----------------------- GENERIC ------------------------

# cssFromDict :: Dict -> String
def cssFromDict(dct):
    '''CSS string from a dictinary of key-value pairs'''
    return reduce(
        lambda a, k: a + k + ':' + dct[k] + '; ',
        dct.keys(),
        ''
    )


# showIntAtBase :: Int -> (Int -> String)
# -> Int -> String -> String
def showIntAtBase(base):
    '''String representation of an integer in a given base,
       using a supplied function for the string
       representation of digits.
    '''
    def wrap(toChr, n, rs):
        def go(nd, r):
            n, d = nd
            r_ = toChr(d) + r
            return go(divmod(n, base), r_) if 0 != n else r_
        return 'unsupported base' if 1 >= base else (
            'negative number' if 0 > n else (
                go(divmod(n, base), rs))
        )
    return lambda toChr: lambda n: lambda rs: (
        wrap(toChr, n, rs)
    )


# MAIN ---
if __name__ == '__main__':
    main()
Output:

Mayan numeral representations of various integers:

Mayan 4005:

━━
━━
Θ ━━


Mayan 8017:

Θ Θ ●●
━━
━━
━━


Mayan 326205:

●● Θ ━━
━━
━━
━━
━━
━━


Mayan 886205:

━━ ━━
━━
━━
━━
━━
━━
━━
━━


Mayan 1081439556:


━━
━━
━━
●●
━━
━━
━━
●●●
━━
━━
━━
●●●●
━━
━━
━━
●●●
━━
━━
━━
●●
━━
━━
━━

━━
━━
━━


Mayan 1000000:


━━
━━ Θ Θ Θ


Mayan 1000000000:

━━
━━
━━
●●
━━
━━
━━
━━
Θ Θ Θ Θ

Raku

(formerly Perl 6)

Just a matter of converting to base twenty, then divmod 5 each digit and map to the appropriate glyph. Most of this is display code to deal with the cartouche requirement.

I actually spent a little time looking into what exactly a Mayan cartouche was supposed to look like. The classic Mayan cartouche was kind of a rounded rectangle with three little semi-circles underneath. Kind of looks like a picture frame. In general, they were only used when expressing significant "holy" dates in the Mayan calender.

These don't particularly resemble the Mayan cartouche, more like mahjong tiles actually. It would have been so much easier and more compact if I could have put all the styling into a CSS file instead of inlining it, but oh well, it was entertaining to do.

### Formatting ###
my $t-style = '"border-collapse: separate; text-align: center; border-spacing: 3px 0px;"';
my $c-style = '"border: solid black 2px;background-color: #fffff0;border-bottom: double 6px;'~
  'border-radius: 1em;-moz-border-radius: 1em;-webkit-border-radius: 1em;'~
  'vertical-align: bottom;width: 3.25em;"';
my $joiner = '<br>';

sub display ($num, @digits) { join "\n", "\{| style=$t-style", "|+ $num", '|-', (|@digits.map: {"| style=$c-style | $_"}), '|}' }

### Logic ###

sub mayan ($int) { $int.polymod(20 xx *).reverse.map: *.polymod(5) }

my @output = <4005 8017 326205 886205 16160025 1081439556 503491211079>.map: {
  display $_, .&mayan.map: { [flat '' xx 3, '●' x .[0], '───' xx .[1], ('Θ' if !.[0,1].sum)].tail(4).join: $joiner }
}

say @output.join: "\n$joiner\n";
Output:
4005


───
───



Θ



───


8017






Θ



Θ
●●
───
───
───


326205



●●



Θ

───
───
───


───
───



───


886205



───


───
───

───
───
───


───
───



───


16160025



───






Θ



Θ






───


1081439556

───
───
───
●●
───
───
───
●●●
───
───
───
●●●●
───
───
───
●●●
───
───
───
●●
───
───
───

───
───
───


503491211079
●●●●
───
───
───

●●●
───
───


●●
───






Θ





●●
───

●●●
───
───
●●●●
───
───
───


Or, plain old text mode. Not as pretty, but still serviceable.

### Formatting ###
use Terminal::Boxer;
my $joiner = "\n";

sub display ($num, @digits) { "$num\n" ~ dd-box( :6cw, :4ch, @digits ) }

### Logic ###

sub mayan ($int) { $int.polymod(20 xx *).reverse.map: *.polymod(5) }

my @output = <4005 8017 326205 886205 16160025 1081439556 503491211079>.map: {
  display $_, .&mayan.map: { [flat '' xx 3, '●' x .[0], '────' xx .[1], ('Θ' if !.[0,1].sum)].tail(4).join: $joiner }
}

say @output.join: $joiner;
Output:
4005
╔══════╦══════╦══════╗
║      ║      ║      ║
║      ║      ║      ║
║ ──── ║      ║      ║
║ ──── ║   Θ  ║ ──── ║
╚══════╩══════╩══════╝

8017
╔══════╦══════╦══════╦══════╗
║      ║      ║      ║  ●●  ║
║      ║      ║      ║ ──── ║
║      ║      ║      ║ ──── ║
║   ●  ║   Θ  ║   Θ  ║ ──── ║
╚══════╩══════╩══════╩══════╝

326205
╔══════╦══════╦══════╦══════╦══════╗
║      ║      ║      ║      ║      ║
║      ║      ║ ──── ║      ║      ║
║      ║      ║ ──── ║ ──── ║      ║
║  ●●  ║   Θ  ║ ──── ║ ──── ║ ──── ║
╚══════╩══════╩══════╩══════╩══════╝

886205
╔══════╦══════╦══════╦══════╦══════╗
║      ║      ║      ║      ║      ║
║      ║      ║ ──── ║      ║      ║
║      ║ ──── ║ ──── ║ ──── ║      ║
║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║
╚══════╩══════╩══════╩══════╩══════╝

16160025
╔══════╦══════╦══════╦══════╦══════╦══════╗
║      ║      ║      ║      ║      ║      ║
║      ║      ║      ║      ║      ║      ║
║      ║      ║      ║      ║      ║      ║
║ ──── ║   ●  ║   Θ  ║   Θ  ║   ●  ║ ──── ║
╚══════╩══════╩══════╩══════╩══════╩══════╝

1081439556
╔══════╦══════╦══════╦══════╦══════╦══════╦══════╗
║   ●  ║  ●●  ║  ●●● ║ ●●●● ║  ●●● ║  ●●  ║   ●  ║
║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║
║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║
║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║ ──── ║
╚══════╩══════╩══════╩══════╩══════╩══════╩══════╝

503491211079
╔══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╦══════╗
║ ●●●● ║      ║      ║      ║      ║      ║      ║      ║ ●●●● ║
║ ──── ║  ●●● ║      ║      ║      ║      ║      ║  ●●● ║ ──── ║
║ ──── ║ ──── ║  ●●  ║      ║      ║      ║  ●●  ║ ──── ║ ──── ║
║ ──── ║ ──── ║ ──── ║   ●  ║   Θ  ║   ●  ║ ──── ║ ──── ║ ──── ║
╚══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╩══════╝

REXX

/*REXX program converts decimal numbers to the Mayan numbering system (with cartouches).*/
parse arg $                                      /*obtain optional arguments from the CL*/
if $=''  then $= 4005  8017  326205  886205,     /*Not specified?  Then use the default.*/
                 172037122592320200101           /*Morse code for MAYAN; egg is a blank.*/

  do j=1  for words($)                           /*convert each of the numbers specified*/
  #= word($, j)                                  /*extract a number from (possible) list*/
  say
  say  center('converting the decimal number '     #     " to a Mayan number:", 90,  '─')
  say
  call $MAYAN   #   '(overlap)'                  /*invoke the  $MAYAN (REXX) subroutine.*/
  say
  end   /*j*/                                    /*stick a fork in it,  we're all done. */

The   $MAYAN.REX   (REXX program) subroutine can be seen here   ───►   Mayan_numerals\$MAYAN.REX.

output   when using the default inputs:
─────────────────converting the decimal number  4005  to a Mayan number:──────────────────

╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝


─────────────────converting the decimal number  8017  to a Mayan number:──────────────────

╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝


────────────────converting the decimal number  326205  to a Mayan number:─────────────────

╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝


────────────────converting the decimal number  886205  to a Mayan number:─────────────────

╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝


─────────converting the decimal number  172037122592320200101  to a Mayan number:─────────

╔════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║
║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║
║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║    ║
║────║────║ Θ  ║ ∙  ║────║ Θ  ║────║ ∙  ║────║────║ Θ  ║ ∙  ║────║ Θ  ║────║ ∙  ║
╚════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩════╩════╝

Ruby

numbers = ARGV.map(&:to_i)
if numbers.length == 0
  puts
  puts("usage: #{File.basename(__FILE__)} number...")
  exit
end

def maya_print(number)
  digits5s1s = number.to_s(20).chars.map { |ch| ch.to_i(20) }.map { |dig| dig.divmod(5) }
  puts(('+----' * digits5s1s.length) + '+')
  3.downto(0) do |row|
    digits5s1s.each do |d5s1s|
      if row < d5s1s[0]
        print('|----')
      elsif row == d5s1s[0]
        print("|#{[(d5s1s[0] == 0 ? ' @  ' : '    '), ' .  ', ' .. ', '... ', '....'][d5s1s[1]]}")
      else
        print('|    ')
      end
    end
    puts('|')
  end
  puts(('+----' * digits5s1s.length) + '+')
end

numbers.each do |num|
  puts(num)
  maya_print(num)
end
Output:
$ ruby mayan.rb 4005 8017 326205 886205 4294967296
4005
+----+----+----+
|    |    |    |
|    |    |    |
|----|    |    |
|----| @  |----|
+----+----+----+
8017
+----+----+----+----+
|    |    |    | .. |
|    |    |    |----|
|    |    |    |----|
| .  | @  | @  |----|
+----+----+----+----+
326205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |    |----|----|    |
| .. | @  |----|----|----|
+----+----+----+----+----+
886205
+----+----+----+----+----+
|    |    |    |    |    |
|    |    |----|    |    |
|    |----|----|----|    |
|----|----|----|----|----|
+----+----+----+----+----+
4294967296
+----+----+----+----+----+----+----+----+
|    |    |    |    |    |... |    | .  |
|    |    |    |    |    |----|    |----|
|    | .. |    |    |----|----|    |----|
|... |----| .. |... |----|----|....|----|
+----+----+----+----+----+----+----+----+

Rust

const ONE: &str = "●";
const FIVE: &str = "——";
const ZERO: &str = "Θ";

fn main() {
    println!("{}", mayan(4005));
    println!("{}", mayan(8017));
    println!("{}", mayan(326_205));
    println!("{}", mayan(886_205));
    println!("{}", mayan(69));
    println!("{}", mayan(420));
    println!("{}", mayan(1_063_715_456));
}

fn mayan(dec: i64) -> String {
    let mut digits = vec![];
    let mut num = dec;
    while num > 0 {
        digits.push(num % 20);
        num /= 20;
    }
    digits = digits.into_iter().rev().collect();
    let mut boxes = vec!["".to_string(); 6];
    let n = digits.len();
    for (i, digit) in digits.iter().enumerate() {
        if i == 0 {
            boxes[0] = "┏━━━━".to_string();
            if i == n - 1 {
                boxes[0] += "┓";
            }
        } else if i == n - 1 {
            boxes[0] += "┳━━━━┓";
        } else {
            boxes[0] += "┳━━━━";
        }
        for j in 1..5 {
            boxes[j] += "┃";
            let elem = 0.max(digit - (4 - j as i64) * 5);
            if elem >= 5 {
                boxes[j] += &format!("{: ^4}", FIVE);
            } else if elem > 0 {
                boxes[j] += &format!("{: ^4}", ONE.repeat(elem as usize % 15));
            } else if j == 4 {
                boxes[j] += &format!("{: ^4}", ZERO);
            } else {
                boxes[j] += &"    ";
            }
            if i == n - 1 {
                boxes[j] += "┃";
            }
        }
        if i == 0 {
            boxes[5] = "┗━━━━".to_string();
            if i == n - 1 {
                boxes[5] += "┛";
            }
        } else if i == n - 1 {
            boxes[5] += "┻━━━━┛";
        } else {
            boxes[5] += "┻━━━━";
        }
    }

    let mut mayan = format!("Mayan {}:\n", dec);
    for b in boxes {
        mayan += &(b + "\n");
    }
    mayan
}
Output:
Mayan 4005:
┏━━━━┳━━━━┳━━━━┓
┃    ┃    ┃    ┃
┃    ┃    ┃    ┃
┃ —— ┃    ┃    ┃
┃ —— ┃ Θ  ┃ —— ┃
┗━━━━┻━━━━┻━━━━┛

Mayan 8017:
┏━━━━┳━━━━┳━━━━┳━━━━┓
┃    ┃    ┃    ┃ ●● ┃
┃    ┃    ┃    ┃ —— ┃
┃    ┃    ┃    ┃ —— ┃
┃ ●  ┃ Θ  ┃ Θ  ┃ —— ┃
┗━━━━┻━━━━┻━━━━┻━━━━┛

Mayan 326205:
┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓
┃    ┃    ┃    ┃    ┃    ┃
┃    ┃    ┃ —— ┃    ┃    ┃
┃    ┃    ┃ —— ┃ —— ┃    ┃
┃ ●● ┃ Θ  ┃ —— ┃ —— ┃ —— ┃
┗━━━━┻━━━━┻━━━━┻━━━━┻━━━━┛

Mayan 886205:
┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓
┃    ┃    ┃    ┃    ┃    ┃
┃    ┃    ┃ —— ┃    ┃    ┃
┃    ┃ —— ┃ —— ┃ —— ┃    ┃
┃ —— ┃ —— ┃ —— ┃ —— ┃ —— ┃
┗━━━━┻━━━━┻━━━━┻━━━━┻━━━━┛

Mayan 69:
┏━━━━┳━━━━┓
┃    ┃    ┃
┃    ┃    ┃
┃    ┃●●●●┃
┃●●● ┃ —— ┃
┗━━━━┻━━━━┛

Mayan 420:
┏━━━━┳━━━━┳━━━━┓
┃    ┃    ┃    ┃
┃    ┃    ┃    ┃
┃    ┃    ┃    ┃
┃ ●  ┃ ●  ┃ Θ  ┃
┗━━━━┻━━━━┻━━━━┛

Mayan 1063715456:
┏━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓
┃ ●  ┃    ┃    ┃    ┃    ┃    ┃ ●  ┃
┃ —— ┃ ●● ┃    ┃    ┃    ┃ ●● ┃ —— ┃
┃ —— ┃ —— ┃●●● ┃    ┃●●● ┃ —— ┃ —— ┃
┃ —— ┃ —— ┃ —— ┃●●●●┃ —— ┃ —— ┃ —— ┃
┗━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┛

Wren

Translation of: Go
Library: Wren-fmt
import "./fmt" for Conv

var ul = "╔"
var uc = "╦"
var ur = "╗"
var ll = "╚"
var lc = "╩"
var lr = "╝"
var hb = "═"
var vb = "║"

var mayan= [
    "    ",
    " ∙  ",
    " ∙∙ ",
    "∙∙∙ ",
    "∙∙∙∙"
]

var m0 = " Θ  "
var m5 = "────"

var dec2vig = Fn.new { |n| Conv.itoa(n, 20).map { |c| Conv.atoi(c, 20) }.toList }

var vig2quin = Fn.new { |n|
    if (n >= 20) Fiber.abort("Cant't convert a number >= 20.")
    var res = [mayan[0], mayan[0], mayan[0], mayan[0]]
    if (n == 0) {
        res[3] = m0
        return res
    }
    var fives = (n/5).floor
    var rem = n % 5
    res[3-fives] = mayan[rem]
    for (i in 3...3-fives) res[i] = m5
    return res
}

var draw = Fn.new { |mayans|
    var lm = mayans.count
    System.write(ul)
    for (i in 0...lm) {
        for (j in 0..3) System.write(hb)
        if (i < lm - 1) {
            System.write(uc)
        } else {
            System.print(ur)
        }
    }
    for (i in 1..4) {
        System.write(vb)
        for (j in 0...lm) {
            System.write(mayans[j][i-1])
            System.write(vb)
        }
        System.print()
    }
    System.write(ll)
    for (i in 0...lm) {
        for (j in 0..3) System.write(hb)
        if (i < lm - 1) {
            System.write(lc)
        } else {
            System.print(lr)
        }
    }
}

var numbers = [4005, 8017, 326205, 886205, 1081439556]
for (n in numbers) {
    System.print("Converting %(n) to Mayan:")
    var vigs = dec2vig.call(n)
    var mayans = vigs.map { |vig| vig2quin.call(vig) }.toList
    draw.call(mayans)
    System.print()
}
Output:
Converting 4005 to Mayan:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝

Converting 8017 to Mayan:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝

Converting 326205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 886205 to Mayan:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

Converting 1081439556 to Mayan:
╔════╦════╦════╦════╦════╦════╦════╗
║ ∙  ║ ∙∙ ║∙∙∙ ║∙∙∙∙║∙∙∙ ║ ∙∙ ║ ∙  ║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
║────║────║────║────║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╝

zkl

var zero=" \u0398  ",one="\u2219", five=String("\u2500"*4,"\n"), fill="    \n";
var ds=T("    "," \u2219  "," \u2219\u2219 ","\u2219\u2219\u2219 ","\u2219\u2219\u2219\u2219");
fcn mayan(m){  //--> lists of lists of strings (each line of tile)
   m.toString(20).pump(List,fcn(m){		// 4,005 --> "a05"
      bars,dots := m.toInt(20).divr(5);		// "a" --> 10 --> (2,0)
      if(0==bars==dots) return(String(fill*3, zero).split("\n"));  // 0
      String(fill*(3-bars), ds[dots],"\n", five*bars)[0,-1].split("\n") // tile
   })
}
var vbar="\u2551", hbar="\u2550"*4, ut=(hbar+"\u2566"), bt=(hbar+"\u2569");
fcn displayMayan(m){  // eg 11 is ( (    ),( *  ),(----),(----) )
   println("\u2554", ut*(m.len()-1), hbar,"\u2557");  // top
   foreach n in (4){ println(vbar, m.apply("get",n).concat(vbar), vbar) }
   println("\u255a", bt*(m.len()-1), hbar,"\u255d");  // bottom
}
foreach m in (T(4_005, 8_017, 326_205, 886_205, 503_491_211_079, 88_637_341)){
   println("\n%,d:".fmt(m)); mayan(m):displayMayan(_);
}
Output:
4,005:
╔════╦════╦════╗
║    ║    ║    ║
║    ║    ║    ║
║────║    ║    ║
║────║ Θ  ║────║
╚════╩════╩════╝

8,017:
╔════╦════╦════╦════╗
║    ║    ║    ║ ∙∙ ║
║    ║    ║    ║────║
║    ║    ║    ║────║
║ ∙  ║ Θ  ║ Θ  ║────║
╚════╩════╩════╩════╝

326,205:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║    ║────║────║    ║
║ ∙∙ ║ Θ  ║────║────║────║
╚════╩════╩════╩════╩════╝

886,205:
╔════╦════╦════╦════╦════╗
║    ║    ║    ║    ║    ║
║    ║    ║────║    ║    ║
║    ║────║────║────║    ║
║────║────║────║────║────║
╚════╩════╩════╩════╩════╝

503,491,211,079:
╔════╦════╦════╦════╦════╦════╦════╦════╦════╗
║∙∙∙∙║    ║    ║    ║    ║    ║    ║    ║∙∙∙∙║
║────║∙∙∙ ║    ║    ║    ║    ║    ║∙∙∙ ║────║
║────║────║ ∙∙ ║    ║    ║    ║ ∙∙ ║────║────║
║────║────║────║ ∙  ║ Θ  ║ ∙  ║────║────║────║
╚════╩════╩════╩════╩════╩════╩════╩════╩════╝

88,637,341:
╔════╦════╦════╦════╦════╦════╦════╗
║    ║    ║    ║∙∙∙∙║    ║    ║    ║
║    ║    ║∙∙∙ ║────║∙∙∙ ║    ║    ║
║    ║ ∙∙ ║────║────║────║ ∙∙ ║    ║
║ ∙  ║────║────║────║────║────║ ∙  ║
╚════╩════╩════╩════╩════╩════╩════╝

The Raku numerals look so good, let's copy them.

Translation of: Raku
var [const]
  t_style=0''"border-collapse: separate; text-align: center; border-spacing: 3px 0px;"',
  c_style=0''"border: solid black 2px;background-color: #fffff0;border-bottom: double 6px;'
    0''border-radius: 1em;-moz-border-radius: 1em;-webkit-border-radius: 1em;'
    0''vertical-align: bottom;width: 3.25em;"';
var [const] dot="\u25cf", bar="\u2500\u2500\u2500!", zero=" \u0398 ";

fcn mayan(m){ m.toString(20).pump(List,fcn(m){ m.toInt(20).divr(5) }) }
fcn display(num,digits){
   "{| style=%s\n|+ %s \n|-\n%s|}".fmt(t_style,num,
      digits.split().pump(String, "| style=%s | %s\n".fmt.fp(c_style)) );
}

T(88637341,26960840421).apply(
   fcn(m){ 
      mayan(m).pump(String,
	 fcn([(bars,dots)]){
	    (if(bars or dots) (dot*dots + "!" + bar*bars)[0,-1] else zero)
	    + " "
	 }).replace("!","<br>") : display(m,_)
   })
.concat("\n<br>\n").println();
Output:
88637341
●●
───
●●●
───
───
●●●●
───
───
───
●●●
───
───
●●
───


26960840421

───

───

───