def imprime(situação):
    palavra_esq, estado, palavra_dir = situação
    L = len(palavra_esq) + len(palavra_dir)

    posição_cabeça = (2*len(palavra_esq))+6
    
    linha_cima = '─┬'*(L+5) + '─'
    prefixo = '…│❑│❑'

    posfixo = '│❑│❑│…'
    linha_baixo  = '─┴'*(L+5) + '─'

    conteúdo = ''
    for s in (palavra_esq + palavra_dir):
        if s == 'B':
            s = '❑'
        conteúdo += f'│{s}'
            
    print(linha_cima)
    print(f'{prefixo}{conteúdo}{posfixo}')
    print(linha_baixo)
    print(f'{" "*posição_cabeça}⬑{estado}')
    
def passo(situação,transição):
    palavra_esq, estado, palavra_dir = situação
    # palavra_esq = palavra_esq.lstrip('B')
    # palavra_dir = palavra_dir.rstrip('B')
    if not palavra_dir:
        símbolo = 'B'
    else:
        símbolo = palavra_dir[0]
    novo_símbolo, novo_estado, direção = transição(símbolo,estado)
    if direção == '←' or direção == 'e':
        if palavra_esq:
            último_esq = palavra_esq[-1]
        else:
            último_esq = 'B'
        return palavra_esq[:-1], novo_estado, (último_esq + novo_símbolo + palavra_dir[1:])
    elif direção == '→' or direção == 'd':
        return palavra_esq + novo_símbolo, novo_estado, palavra_dir[1:]
    else:
        # cabeça fica parada
        return palavra_esq, novo_estado, novo_símbolo + palavra_dir[1:]

def executa(palavra_inicial,máquina,passo_a_passo=True):
    estado_inicial,estados_terminais = máquina[:2]
    if isinstance(máquina[2],dict):
        transição = transição_dic(máquina[2])
    else:
        transição = máquina[2]
    situação = ('',estado_inicial,palavra_inicial)
    passos = 0
    while True:
        passos += 1
        print(f'{passos}.')
        imprime(situação)
        if situação[1] in estados_terminais:
            print("SUCESSO")
            return
        if passo_a_passo:
            input("Pressione <enter> para continuar...")
        try:
            situação = passo(situação, transição)
        except Exception:
            print("TELA AZUL (não há transição válida)")
            return

def transição_dic(D):
    return lambda s,e: D[(s,e)]
    
#### EXEMPLOS
        
dic_ancn = {
    ('a','procura_fronteira')     : ('a','procura_fronteira','→'),
    ('c','procura_fronteira')     : ('c','procura_a_não_marcado','←'),

    ('X','procura_a_não_marcado') : ('X','procura_a_não_marcado','←'),
    ('a','procura_a_não_marcado') : ('X','procura_c_não_marcado','→'),
    ('B','procura_a_não_marcado') : ('B','tudo_X?','→'),

    ('X','procura_c_não_marcado') : ('X','procura_c_não_marcado','→'),
    ('c','procura_c_não_marcado') : ('X','procura_a_não_marcado','←'),

    ('X','tudo_X?')               : ('X','tudo_X?','→'),
    ('B','tudo_X?')               : ('B','sucesso','→'),
}

MT_ancn = ('procura_fronteira',{'sucesso'},dic_ancn)

def delta_ex1 (x,q):
    if x == 'B' and q == 'q_I':
        return ('B', 'q_I', '→')
MT_ex1 = ('q_I', set(), delta_ex1)


def delta_ex2 (simbolo, estado):
    if simbolo == 'x' and estado == 'q_I':
        return ('x', 'q_I', '→')
    if simbolo == 'y' and estado == 'q_I':
        return ('y', 'q_F', '⟳')
MT_ex2 = ('q_I', {'q_F'}, delta_ex2)
