Task: Mayan numerals

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)) 


size_t base20(unsigned int n, uint8_t *out) {
    
    uint8_t *start = out;
    do {*out++ = n % 20;} while (n /= 20);
    size_t length = out - start;
    
    
    while (out > start) {
        uint8_t x = *--out;
        *out = *start;
        *start++ = x;
    }
    return length;
}


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

    
    for (i=4; i>0; i--, n -= 5)
        memcpy(place + i*line_length, parts[MAX(0, MIN(5, n))], 4);
        
    
    if (n == -20) place[4 * line_length + 1] = '@';
}


char *mayan(unsigned int n) {
    if (n == 0) return NULL; 
    
    uint8_t digits[15]; 
    size_t n_digits = base20(n, digits);
    
    
    size_t line_length = n_digits*5 + 2;
    
    
    char *str = malloc(line_length * 6 + 1);
    if (str == NULL) return NULL;
    str[line_length * 6] = 0;
    
    
    char *ptr;
    unsigned int i;
    
    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);
    
    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);

    
    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;
}




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()
    }
}