
# This file was *autogenerated* from the file dimension_count.sage
from sage.all_cmdline import *   # import sage library

_sage_const_3 = Integer(3); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_30 = Integer(30)
from itertools import takewhile
import pprint

def pascal_matrix(size):
    if size == _sage_const_0 :
        return matrix([_sage_const_1 ])
    M = zero_matrix(size, size)
    M[_sage_const_0 , _sage_const_0 ] = _sage_const_1 
    for i in range(_sage_const_1 , size):
        M[i,_sage_const_0 ] = _sage_const_1 
        for j in range(_sage_const_1 , i+_sage_const_1 ):
            M[i, j] = M[i-_sage_const_1 , j-_sage_const_1 ] + M[i-_sage_const_1 , j]
    return M


def block_pascal_column(c, l):
    matrices = []
    M = pascal_matrix(size=c)
    for i in range(_sage_const_1 , l):
        R = matrix(c-i, i, _sage_const_0 ).augment(pascal_matrix(size=c-i))
        M = M.stack(R)
    return M

def zeros(m,n):
    return matrix(m,n,_sage_const_0 )

def block_pascal(d, l):
    M = block_pascal_column(d,l)
    r = d
    c = d-_sage_const_1 
    R = zeros(r, c)
    for i in range(_sage_const_1 ,l):
        A = block_pascal_column(d-i, l-i)
        M = M.augment(R.stack(A))
        r = r + c
        c = c - _sage_const_1 
        R = zeros(r, c)
    return M

def generate_matrices(i, n):
    l = n/_sage_const_3 
    h=_sage_const_0 
    ary = []
    for c in range(((n+i)+_sage_const_1 )):
        num_rows = [_sage_const_0  for _ in xrange(l+_sage_const_1 )]
        rows_to_keep = [[] for _ in xrange(l+_sage_const_1 )]
        columns_to_keep = [[] for _ in xrange(l+_sage_const_1 )]
        r = c+_sage_const_1 
        t = _sage_const_0 
        a = _sage_const_0 
        for k in range(l+_sage_const_1 ):
            m = n - _sage_const_3 *k
            j = i + k
            d = c - k
            if j >= m + _sage_const_2 *k:
                continue
            if d < k-c:
                continue

            if m == _sage_const_0 :
                if d <= (j + m):
                    a = _sage_const_1 
                    r -= d
                else:
                    a = _sage_const_0 
            elif d in range(j+_sage_const_1 ) and d <= m:
                a = d+_sage_const_1 
            elif d in range(j, m):
                a = j+_sage_const_1 
            elif d in range(m, d+m):
                a = min(max(m-(d-j)+_sage_const_1 ,_sage_const_0 ), m+_sage_const_1 )
                r = r-(d-m)
            num_rows[k] = a
            rows_to_keep[k] = range(r-a, r)
            if d in range(m, d+m) and m != _sage_const_0 :
                r += d-m
            if d >= _sage_const_0 :
                columns_to_keep[k] = range(t, t+min(d+_sage_const_1 , max((m-j)/_sage_const_2 ,_sage_const_0 )))
            else:
                columns_to_keep[k] = _sage_const_0 
            r += d
            t += d + _sage_const_1 

        cols = tuple([item for sublist in columns_to_keep for item in sublist])
        rows = tuple([item for sublist in rows_to_keep for item in sublist])
        pcols = list(columns_to_keep)
        prows = list(rows_to_keep)
        for idx in range(_sage_const_1 ,len(pcols)):
            for jdx in range(len(pcols[idx])):
                pcols[idx][jdx] -= ((c+_sage_const_1 )*(c+_sage_const_2 ))/_sage_const_2  - ((c+_sage_const_1 -idx)*(c+_sage_const_2 -idx))/_sage_const_2 
        for idx in range(_sage_const_1 ,len(prows)):
            for jdx in range(len(prows[idx])):
                prows[idx][jdx] -= ((c+_sage_const_1 )*(c+_sage_const_2 ))/_sage_const_2  - ((c+_sage_const_1 -idx)*(c+_sage_const_2 -idx))/_sage_const_2 
#         print rows_to_keep, columns_to_keep
        truncated_matrix = block_pascal(c+_sage_const_1 ,min(c+_sage_const_1 ,l+_sage_const_1 ))[rows,cols]
        h += truncated_matrix.rank()
        ary += [truncated_matrix.rank()]
 #       print '----------------------------------'
 #       print prows, pcols
 #       print 'c = ', c
#        print 'rows = ', rows_to_keep
#        r_to_keep = []
#        for j in rows_to_keep:
#            if j != []:
#                r_to_keep += [len(j)]
#        print r_to_keep
#        print 'num_cols = ', [len(i) for i in takewhile(lambda x: x!= [], columns_to_keep)]
#        print 'matrix\n', truncated_matrix.str()
#        print truncated_matrix.rank()

#        print '(i,c) = (%d,%d), rank = %d' % (i,c,truncated_matrix.rank())
#        print '----------------------------------'      
    return h, ary

def count_jets(n):
    sum = _sage_const_0 
    for i in range(-n/_sage_const_3 ,n, _sage_const_2 ):
#        print 'i = ', i
        h, ary = generate_matrices(i, n)
        sum += h
    return sum
for i in range(_sage_const_2 ,_sage_const_30 ):
    print _sage_const_3 *i, count_jets(_sage_const_3 *(i))



















