""" prob_0061.py """

# usage: python3 prob_0061.py

from itertools import permutations


def p3(x):
    """ triangle number """
    return x * (x + 1) // 2


def p4(x):
    """ square number """
    return x * x


def p5(x):
    """ pentagonal number """
    return x * (3 * x - 1) // 2


def p6(x):
    """ hexagonal number """
    return x * (2 * x - 1)


def p7(x):
    """ heptagonal number """
    return x * (5 * x - 3) // 2


def p8(x):
    """ octagonal number """
    return x * (3 * x - 2)


def bounded(function):
    """ 999 < function(n) < 10000, function(n) % 100 >= 10 """
    output = []
    n = 0
    while (fn := function(n)) < 10000:
        if fn > 999 and fn % 100 >= 10:
            output.append(fn)
        n += 1

    return output


def verify_left(item, item_list):
    """ abcd efgh - cd = ef """
    for i in item_list:
        if item // 100 == i % 100:
            return True

    return False


def verify_right(item, item_list):
    """ abcd efgh - ef = cd """
    for i in item_list:
        if item % 100 == i // 100:
            return True

    return False


def solve():
    """ let's go! """
    bins = {'3': bounded(p3), '4': bounded(p4), '5': bounded(p5),
            '6': bounded(p6), '7': bounded(p7), '8': bounded(p8)}
    keys = ''.join(bins.keys())

    size = len(bins)
    stop = [[] for _ in range(size)]
    output = None
    for trial in permutations(keys):
        x = [bins[t] for t in trial]
        i = 0
        while x != stop:
            j = (i - 1) % size
            x[i] = [k for k in x[i] if verify_left(k, x[j])]
            j = (i + 1) % size
            x[i] = [k for k in x[i] if verify_right(k, x[j])]

            if all(len(k) == 1 for k in x):
                break

            i = j

        if x != stop:
            check = {k[0] for k in x}
            if len(check) == size:
                output = sum(check)
                break

    return output


if __name__ == '__main__':
    print(solve())
