'''Mayan numerals'''

from functools import (reduce)





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



def mayanDigit(n):
    '''List of strings representing a Mayan digit.'''
    if 0 < n:
        r = n% 5
        return [
            (['' * r] if 0 < r else []) +
            ([''] * (n 
        ]
    else:
        return ['']



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': '
                'color': '
                'border': '2px solid silver'
            }),
            'colwidth': '3em',
            'cell': 'vertical-align: bottom;'
        })([[
            '<br>'.join(col) for col in mayanNumerals(n)
        ]])
    )





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





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 + '= ' if (
                k in opts
            ) else a
        ),
        ['class', 'style'],
        ''
    ) + '\n' + '\n|-\n'.join(
        '\n'.join(
            ('|' if (
                0 != i and ('cell' not in opts)
            ) else (
                '|style=|'
            )) + (
                str(x) or ' '
            ) for x in row
        ) for i, row in enumerate(rows)
    ) + '\n|}\n\n'





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




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



if __name__ == '__main__':
    main()