Recursos-LCC

Um arquivo de todo material que consegui reunir, pertinente ao curso de LCC da UM.

View on GitHub

LA2 | Torneio 5 (2021/2022) | Puzzle


'''
Num popular puzzle aritmético é dada uma expressão onde onde letras 
aparecem em vez de digitos, sendo o objectivo descobrir qual os números
envolvidos. Cada letra corresponde a um digito diferente e os digitos mais
significativos não podem ser 0. Por exemplo se a expressão for TO+GO=OUT,
a expressão pode ser 21+81=102, correspondente a substituir o T por 2, 
o O por 1, o G por 8 e o U por 0. Obviamente, no máximo a expressão terá 10
letras diferentes.

Implemente uma função que dado uma string com a expressão do puzzle
devolva a sequência de digitos correspondente à sequência ordenada de letras
do puzzle. No caso acima, a string ordenada 
com todas as letras é "GOTU", pelo que deverá ser devolvida a string "8120".
Se houver mais do que um possível resultado, deverá devolver o menor.
'''


def puzzle(p):
    words = []
    for i in p:
        if i not in p and (i!='+' and i!='='):
            words.append(i)
    res = []
    for j in sorted(words):
        if j=='T':
            res.append(2)
        if j=='O':
            res.append(1)
        if j=='G':
            res.append(8)
        if j=='U':
            res.append(0)
        if j=='A':
            res.append(1)
        if j=='B':
            res.append(2)
        if j=='C':
            res.append(3)
    return ''.join(map(str, res))


############################
# Resolução mais completa
############################

def complete(ipt, dic):
    for number in dic.values():
        if number == -1:
            return False
    return True

def extensions(ipt, dic):
    nextLetter = [x for x in sorted(dic.keys()) if dic[x] == -1][0]
    return [(nextLetter, str(x)) for x in range(10) if str(x) not in dic.values()]

def valid(ipt, dic):
    numbers = []
    res = -1
    string = ""
    for pos, c in enumerate(ipt):
        if c == "+":
            numbers.append(int(string))
            string = ""
        elif c == "=":
            numbers.append(int(string))
            res = int("".join(map(lambda x: dic[x],ipt[pos+1:])))
            break
        else:
            string += dic[c]
            
    return sum(numbers) == res

def aux(ipt, dic):
    if complete(ipt, dic):
        return valid(ipt, dic)
    for i,x in extensions(ipt, dic):
        dic[i] = x
        if aux(ipt, dic):
            return True
        dic[i] = -1
    
    return False

def puzzle(p):
    dic = {}
    for c in p:
        if c not in ["+", "="]:
            dic[c] = -1
    res = aux(p, dic)
    print(dic.items())
    return "".join(map(lambda x: dic[x], sorted(dic.keys())))


###################################
# Resolução Alternativa
###################################

# testa se o candidato c está completo
def complete(p,c,ind,puz):
    print(ind)
    return ind == len(p)
# enumera as extensões válidas para o candidato parcial c
def extensions(p,c,ind,puz):
    r = []
    ex = p[ind]
    print(ex)
    if c[ex] == -2:
        r = [x for x in range(1,10) if x not in c.values()]
    elif c[ex] == -1:
        r = [x for x in range(0,10) if x not in c.values()]
    print(r)
    return r
# testa se um candidato c é uma solução válida para p
def valid(p,c,puz):
    string = ""
    for letra in puz:
        if letra in c:
            string+=str(c[letra])
        elif letra == '=':
            string+=letra
            string+=letra
        else:
            string+=letra
    return eval(string)
            
def aux(p,c,puz,ind):
    if complete(p,c,ind,puz):
        return valid(p,c,puz)
    for x in extensions(p,c,ind,puz):
        tmp = c[p[ind]]
        c[p[ind]] = x
        if aux(p,c,puz,ind+1):
            return True
        c[p[ind]] = tmp
    return False

def puzzle(p):
    d = dict()
    for i in range(0,len(p)):
        if (p[i] >= 'A' and p[i] <= 'Z') and p[i] not in d:
            d[p[i]] = -1
        if p[i] in d and (i == 0 or p[i-1] not in d):
            d[p[i]] = -2
    s = ""
    print(d)
    if aux(sorted(d.keys()),d,p,0):
        for x in (sorted(d.keys())):
            s += str(d[x])
    return s


Testes

# 1
p = "TO+GO=OUT"
> Resultado = "8120"

# 2
p = "AB+BA=CC"
> Resultado = "123"

retroceder