Fibonacci: alguns algoritmos efetivos em AWK

Estava apreciando hoje de manhã um post do Felipe Tonello: Analisando Número de Fibonacci e Recursividade. É um bom artigo sobre aquelas coisas que alguns podem ter visto na faculdade e são sempre uteis: matemática, analise de algoritmos e um pouco de mente aberta.

Imediatamente tratei de testar a velocidade dos dois algoritmos propostos usando AWK (que, por ser interpretado, pode revelar melhor as nuances entre as abordagens). Algoritmos recursivos são interessantes, principalmente quando trabalhamos com linguagens funcionais, porém algumas formas tem um custo computacional muito alto e o calculo de Fibonacci é um exemplo perfeito: para cada termo eu preciso calcular os dois termos anteriores e, então, soma-los, e isso cresce geométricamente, consumindo memória e processamento, sem falar que tenho muita repetição de código desnecessária.

A tecnica de programação dinâmica apresentada cria um cache de resultados, dessa forma evito boa parte do trabalho extra, veja o resultado:

Fibonacci(36) pelo algoritmo recursao simples:14930352 usando 48315633 iteracoes

real    0m51.961s
user    0m23.881s
sys     0m0.012s
Fibonacci(36) pelo algoritmo programacao dinamica:14930352 usando 71 iteracoes

real    0m0.002s
user    0m0.000s
sys     0m0.000s

Usando programação dinâmica eu uso muito menos de 1% do processamento necessário pela forma recursiva tradicional. Parece ótimo, não? Depende, pois eu apenas afastei o problema: ao calcular termos de alta ordem eu terei o mesmo problema, afinal o algoritmo é O[n].

Lembrei de um post do Ronaldo Melo Ferraz, Conceitos de Programação: Tail Recursion enquando estava testando os algoritmos em Erlang e encontrei esta implementação. A adaptação para awk é tranquila e o teste mostrou este resultado:

Fibonacci(36) pelo algoritmo programacao dinamica:14930352 usando 71 iteracoes

real    0m0.002s
user    0m0.000s
sys     0m0.000s
Fibonacci(36) pelo algoritmo tail recursion:14930352 usando 38 iteracoes

real    0m0.001s
user    0m0.000s
sys     0m0.004s

Um resultado ainda mais interessante, pois eu consigo obter o valor do termo com um pouco mais da metade das iterações do que usando programação dinâmica (sem onerar a memória com o cache dos resultados).

Esta analise é muito superficial, a ideia é apenas despertar a curiosidade sobre estes tópicos.

O codigo fonte utilizado nesse benchmark:
function Fib_normal(N) {
return (N > 1)? Fib_normal(N-1) + Fib_normal(N-2) : N
}
function Fib_dinamic(N) {
if (!m[N]) m[N] = (N > 1)? Fib_dinamic(N-1) + Fib_dinamic(N-2) : N
return m[N]
}

function Fib(N) { return Fib_tr(N,0,1); }
function Fib_tr(I,R,N){
return (I==0)? R : Fib_tr(I-1,N,R+N)
}

Pesquisa: o que te desmotiva no trabalho?

Nem sempre estamos satisfeito no ambiente de trabalho, seja pelo transito, paredes que dão choques ou projetos malucos que fazem a gente varar a noite.

Pensando no que os meus colegas e eu ja passamos, quero fazer uma pesquisa: alguem ja passou por estas situações e quais são as piores, no sentido de arrebentar com a nossa incrivel motivação no trabalho?
- Falta de equipamentos adequados (quem nunca pensou em comprar um pente de memória com o dinheiro do bolso pra levar pro trabalho);
- Falta de café, chá ou ar condicionado (ou quando tem é ruim);
- Colegas doidos que te levam a loucura;
- Internet bloqueada (incluindo o google);
- Ter que trabalhar depois do horario (as vezes sem receber por isso);
- Codigos que parecem ter saido de um conto de H.P. Lovecraft;
- Projetos que parecem não ter sentido ou importância;
- Chefes que parecem ter saido de uma tirinha do Dilbert;
- Chefes truculentos, desses que da medo falar o nome;
- Resistência a mudanças (riem de Ruby on Rails e desenvolvem em Java como se fosse Cobol);
- Buzzwords são mais importantes do que atender aos clientes;

Os profissionais de informática, especialmente os desenvolvedores, possuem formas de encarar o trabalho que, de acordo com o ambiente, a vontade de fazer algo bom some restando cinismo, péssimo humor e curriculos atualizados prontos para zarpar para outras oportunidades. Algumas vezes é inevitavel, afinal somos humanos, mas o que nos leva a aguentar, enfrentar ou desistir desses problemas?

Uma caracteristica é bem clara: gostamos de fazer coisas especiais. É ironicamente engraçado ver as reações de alguns profissionais quando estão fazendo algo ordináriol, comum ou que julguem sem importância pois muitos odeiam isso, porém estão fazendo por algum motivo: geralmente existe alguma extratégia da empresa que deveria ser respeitada. Creio que este tipo de “soberba” afeta o nosso rendimento pois é muito facil ver reações emocionais e não tanto racionais.

No aguardo da flame-war

RPG em Ruby com apenas 15 linhas

Achei este link bem interessante: MUD in 15 Lines of Ruby. Para quem não sabe MUD é uma familia de jogos textuais inspirados em RPGs conhecidos: normalmente vc escolhe uma raça e uma classe e, dentro do jogo, evolui através da morte de criaturas controladas pelo jogo e através de missões varias como recuperar itens ou decifrar enigmas, são os avós dos MMORPGs modernos.

O codigo foi um tanto obsfuscado, na verdade são umas 77 linhas, mas não deixa de ser interessante o poder das linguagens scripts :)

GoogleTalk em Python

Com a biblioteca xmpp eu posso criar o client de Jabber, acessando a rede do GTalk.

import xmpp

login = 'login' # @gmail.com
pwd   = 'senha'

cnx = xmpp.Client('gmail.com')
cnx.connect( server=('talk.google.com',5223) )

cnx.auth(login,pwd, 'python-xmpp')

cnx.send( xmpp.Message( "teste123@gmail.com" ,"Hello World from Python" ) )

Basta incluir a biblioteca (apt-get install python-xmpp) e pronto. O codigo eu me baseei neste artigo. Facil não?