Fazendo um pouco melhor (ainda a provinha do GDD)
Ainda não desisti de resolver a prova do GDD em Erlang. Não. Não preciso resolver em Erlang, mas, com tanta gente usando Java, PHP e até PL/SQL pra resolvê-la (e com um amigo que usou Haskell), eu fiquei com vontade.
Também posso repetir uma do ano passado e fazê-la em Lisp.
Então. Erlang é avessa a loops. Loops fazem coisas mudarem de estado e linguagens funcionais não gostam que coisas mudem de estado. O dialeto de Lisp que eu usei ano passado também, mas faz uma concessão e me deixa fazê-los.
O comparador
Assim, a nossa primeira função com loop da prova, cmp_goog, que é assim:
def cmp_googlon(p1, p2): v = 'jgptzmqskbclrhdfnvwx' for l1, l2 in zip(p1, p2): if v.index(l1) != v.index(l2): return v.index(l1) - v.index(l2) return len(p1) - len(p2)
Ficaria assim:
def cmp_googlon(p1, p2): v = 'jgptzmqskbclrhdfnvwx' if p1 == p2: return 0 elif len(p1) == 0 or len(p2) == 0: return len(p1) - len(p2) elif p1[0] == p2[0]: return cmp_googlon(p1[1:], p2[1:]) else: return v.index(p1[0]) - v.index(p2[0])
Note que, em vez de comparar as strings em um loop, eu comparo só seus primeiros elementos e, se os dois forem iguais, eu chamo o comparador de novo, agora com as strings sem a primeira posição.
Bases numéricas
A outra função serve para nos dar o valor em base 10 de um número em googlon. O original é um clássico, em que você percorre os dígitos do número e vai totalizando os valores de cada casa:
def valor_numerico(p): v = 'jgptzmqskbclrhdfnvwx' vn = 0 i = 0 for c in p: vn += v.index(c) * (20 ** i) i += 1 return vn
A idéia é que o valor de um número é o valor do seu dígito menos significativo somado ao produto da base multiplicada pelo valor do resto. No caso de números em base 10, 123 é dado pela soma de 3 com o produto de 10 e 12, sendo que 12 é dado por 2 somado a 10 vezes 1. Transcrito em Python, a nova versão é bem mais concisa:
def valor_numerico_f(p): v = 'jgptzmqskbclrhdfnvwx' if len(p) == 1: return v.index(p) else: return v.index(p[0]) + 20 * valor_numerico_f(p[1:])
Agora eu preciso de algumas horas para escrever a versão em Erlang. Desejem-me sorte.