def markov_chain_contour(contour_list, order=1, print_pd=False):
    def split_and_count_contour(cseg, order):
        without_repetition = contour.remove_adjacent_repetition(cseg)
        return contour.split_and_translate(without_repetition, order + 2)

    def check_dic(cseg_map_int, cseg_map_cseg, cseg, n):
        if cseg not in cseg_map_cseg.keys():
            cseg_map_cseg[cseg] = n
            cseg_map_int[n] = cseg
            ind = n
            n += 1
        else:
            ind = cseg_map_cseg[cseg]
        return ind, n


    output_csegs = []
    for cseg in contour_list:
        output_csegs.extend(split_and_count_contour(cseg, order))

    cseg_map_int = {}
    cseg_map_cseg = {}
    chain = {}
    n = 0

    for cseg in output_csegs:
        input_cseg = tuple(contour.translate(cseg[:-1]))
        output_cseg = tuple(cseg)
        input_n, n = check_dic(cseg_map_int, cseg_map_cseg, input_cseg, n)
        output_n, n = check_dic(cseg_map_int, cseg_map_cseg, output_cseg, n)

        if input_n not in chain.keys():
            chain[input_n] = []
        chain[input_n].append(output_n)

    if print_pd:
        cseg_map_int = print_pretty_pd(cseg_map_int)
        chain = print_pretty_pd(chain)

    return cseg_map_int, chain
 def make_csegs(size):
     base = list(range(size)) * size
     permutations = map(list, itertools.permutations(base, size))
     csegs_set = set([tuple(contour.translate(cseg)) for cseg in permutations])
     return sorted(list(csegs_set))