quinta-feira, 16 de fevereiro de 2012

Antes que seja tarde

Hoje encontrei uma conta deveras interessante envolvendo a velocidade atual dos computadores. O objetivo dela é descobrir qual a distância que a luz percorre durante um ciclo de máquina.
  1. A velocidade da luz é cerca de 300.000km/s ou 3*10^8m/s
  2. Uma máquina de 3GHz (bem comum hoje em dia) executa um ciclo a cada 1/3.000.000.000s ou 1/3*10^9s
  3. Logo, em um ciclo de máquina a luz consegue andar 0,1m ou 10cm.
Isso significa que se eu levantar uma placa com uma conta (por exemplo, 1034*564), uma máquina moderna consegue calcular o resultado antes que a luz rebatida pela placa chegue a uma pessoa do outro lado da sala.

segunda-feira, 13 de fevereiro de 2012

Transformando colunas em linhas II

No artigo anterior, usei expressões regulares para transformar strings com valores separados por vírgula em linhas de uma consulta. Outra utilidade dessa técnica é transformar colunas de uma consulta em linhas.

Por exemplo, considere uma tabela de pessoas que inclui também os nomes dos pais:

  CREATE TABLE PESSOAS (
    NOME VARCHAR2(200),
    NOME_PAI VARCHAR2(200),
    NOME_MAE VARCHAR2(200)
  )

Para transformar isto numa única consulta que retorne os nomes de todas as pessoas referenciadas, podemos juntar com vírgula os nomes linha a linha e depois separá-los com uma expressão regular:

select trim(trailing ',' from nome) from (
  select regexp_substr(
            nome||','||nome_pai||','||nome_mae||','
         ,'[^,]+,',1,n.n) nome
  from pessoas,
      (select rownum n from all_tables where rownum<4) n
)

Deixei a concatenação sozinha numa linha, para evitar a confusão de vírgulas dentro e fora de strings.

A expressão "[^,]+," busca cada pedaço do string que não contenha vírgulas, mas que termine com uma. Por isso, é preciso adicionar uma vírgula ao último item. Por fim, tiram-se as vírgulas e apresentam-se os nomes, linha a linha.

sexta-feira, 10 de fevereiro de 2012

Transformando textos em linhas

Uma função que não se acha no SQL é a split(). Por exemplo, para transformar o string '12,34,56,78,90' em linhas de uma consulta, podemos escrever um pequeno bloco de PL/SQL no Oracle. No entanto, quero usar apenas o SQL.

Minha solução é a seguinte:

select trim(trailing ',' from item) from (
  select regexp_substr('12,34,56,78,90','\d+,',1,n.n) item
  from dual,
    (select rownum n 
     from all_tables 
     where rownum<length(translate('12,34,56,78,90', ',1234567890', ','))+1) n
) 

A função regexp_substr() permite indicar qual ocorrência da busca queremos mostrar, então, junto a tabela dual (que só tem uma linha) com n linhas de all_tables a fim de mostrar todas as ocorrências. Cada uma vira uma linha. Além disso, uso o mesmo string na consulta a all_tables para encontrar o número de vírgulas e somar um, produzindo o número total de elementos na lista.

Para testar mais um pouco minha pequena solução, criei uma tabela dos campões do mundo de futebol:

CREATE TABLE CAMPEOES (
  PAIS VARCHAR2(100), 
  CAMPEONATOS VARCHAR2(200)
)

E dentro dessa tabela coloquei o seguinte:

PAIS CAMPEONATOS
Uruguai 1930,1950
Alemanha 1954,1974,1990
Itália 1934,1938,1982,2006
Argentina 1978,1986
Inglaterra 1966
Espanha 2010
França 1998
Brasil 1958,1962,1970,1994,2002

Para enumerar os campeões ano a ano, executei a seguinte consulta:


select pais, trim(trailing ',' from item) from (
  select pais, regexp_substr(campeonatos||',','\d+,',1,n.n) item
  from campeoes,
    (select rownum n from all_tables where rownum<10) n
) where item is not null
order by 2


Uruguai 1930
Itália 1934
Itália 1938
Uruguai 1950
Alemanha 1954
Brasil 1958
Brasil 1962
Inglaterra 1966
Brasil 1970
Alemanha 1974
Argentina 1978
Itália 1982
Argentina 1986
Alemanha 1990
Brasil 1994
França 1998
Brasil 2002
Itália 2006
Espanha 2010

Modelei ao banco ao problema, mas a solução serve também para quando a modelagem for o problema.

terça-feira, 7 de fevereiro de 2012

Sexo e SOPA

Quando estamos no colégio nos ensinam um monte de simplificações e mentiras com o objetivo de nos dar uma idéia de como o mundo funciona. Uma mentira que apenas recentemente revelou-se para mim é a de que o sexo tem o objetivo de conferir maior variabilidade genética a uma população.

A semelhança que o nosso genoma tem com os outros mamíferos é impressionante. Mesmo com o pequeno rato, temos 80% dos genes com comum. Com os chimpanzés temos algo como 1% de diferença. Entre dois seres humanos, a diferença é minúscula. Então, não é variabilidade que procuramos, mas correção de erros!

A radiação e poluição com as quais convivemos todos os dias vão, pouco a pouco, minando nossa estrutura. Não há como um organismo viver por muito tempo sem uma correção. Nada melhor que o sexo. Comparamos o projeto de um com o projeto do outro, separamos os defeitos e criamos uma cópia.

Claro, ninguém vai contar para as crianças que seus organismos estão se decompondo aos poucos e que o melhor que têm a fazer é procriar. Como adultos, essa idéia também não é muito agradável (a parte sobre decompor, isto é).

Então, estamos nós neste planeta, dependendo vitalmente da nossa capacidade de copiar a nós mesmos enquanto algumas pessoas querem implantar leis como SOPA, PIPA e ACTA para colocar na cadeia quem copia! Não é natural e tampouco é saudável ensinar às crianças que compartilhar é feio.

Sempre achei que essa conversa de propriedade intelectual fosse conversa para consumidor dormir. Agora tenho a prova biológica!

sexta-feira, 27 de janeiro de 2012

A nota do vestibular e o sistema de cotas

Eu lembro bem até hoje da minha nota no vestibular. Era uma ótima nota e eu poderia, naquele ano, ter entrado em qualquer curso. E a verdade, passados 20 anos, é que a nota que me foi tão cara não teve nenhuma relevância sobre o que se passou depois. Por isso, não vejo a importância que se está dando às notas dos aprovados pelo sistema de cotas.

Sempre achei curioso como os norte-americanos entram na universidade para depois decidirem qual formação desejam (alguns devem ter propósitos bem firmes, mas, mesmo assim, as univerdades lhes deixam todas as portas abertas). Aqui no Brasil, por outro lado, parecemos ter a realidade perfeitamente sob controle; como numa ditadura stalinista bem planejada, temos, desde já, definidos os futuros dos 140 gloriosos engenheiros que ingressam hoje na faculdade do povo! E, assim como numa ditadura stalinista bem planejada, os resultados são, digamos, não tão brilhantes quanto se esperava.

Infelizmente, ingressamos sem conhecer o curso e muito menos o mercado profissional que nos aguarda depois. E a nota do vestibular perde toda a importância no minuto que nos matriculamos. Há portadores de notas medíocres com carreiras internacionais fantásticas, assim como portadores de notas excelentes com carreiras menos que gloriosas.

Há quem tema a decadência das universidades públicas, como se sua luz fosse hoje apenas reflexo do brilhantismo de seus alunos. Os professores são todos doutores, mas no instante em que substituirmos seus alunos por outros menos dignos, tudo isso tornar-se-á irrelevante, parecem pensar alguns. Eles tambêm, tudo indica, serão incapazes de dar notas baixas a quem não estudar.

Os cotistas em geral, têm notas piores no vestibular, sim, mas o que importa saber é como serão seus desempenhos acadêmicos e como serão suas vidas depois de completado o curso e, também, como será a nota de seus filhos. Todos os dias, saio caminhando do meu prédio e vejo gente branca saindo em carros imponentes e gente de pele escura entrando à pé para fazer a limpeza. Nos 124 anos desde que foi abolida a escravatura, a sociedade brasileira não tentou de nenhuma forma diminuir as desigualdades e, no momento em que se produz um pequeno experimento, a reação é a de que a civilização ocidental está a perigo.

Penso eu que o vestibular tinha que ser abolido. Quem quiser que matricule-se na cadeira de cálculo e quem passar que prossiga. Podem colocar uma prova de exemplo na porta da reitoria que muitos já desistirão. Sem prova de admissão, então podemos voltar a falar em qualidade de ensino e deixar essa fixação juvenil no vestibular para trás.

P.S. Refletindo sobre o texto, lembrei depois que três empresários de sucesso que conheço não passaram no vestibular da UFRGS quando não havia cotas (talvez para sua própria sorte), o que confirma que a nota do vestibular não mede muita coisa.

quinta-feira, 12 de janeiro de 2012

Feliz 2*2*503!

Para iniciar positivamente o ano novo, resolvi comparar duas informações importantes. A primeira é a probabilidade de ganhar a Mega-Sena (1/50.063.860) e a outra é a de que a probabilidade de continuar vivo diminui pela metade a cada oito anos.

Qual seria a idade, pensei eu, cuja probabilidade de obtenção é igual a de acertar as seis dezenas? Com a ajuda do Wolphram Alpha, descobri que a idade é 111 (quase 112, para os otimistas).

Então, aproveite o pouco tempo que lhe resta e deixe de sonhar com bobagens!

quinta-feira, 22 de dezembro de 2011

Candidatos a primos

Quem sair a procurar primos não se dará ao trabalho de inspecionar os inteiros pares. Então, começando pelo primeiro inteiro não múltiplo de 2, basta ir somando 2 para encontrar aqueles que não são múltiplos de 2. Ou seja, há aí uma pequena série (2).

Resolvi investigar o que apareceria se eu quisesse eliminar também os múltiplos de 3. Começando com 5 (o primeiro inteiro que não é múltiplo nem de 2 nem de 3), descobri que basta somar 2, depois 4, depois 2, depois 4 e assim por diante. Então, a nova série é (2, 4).

Confiante com o sucesso, busquei, com a ajuda de um script em Perl, as séries para os primos seguintes. O que facilita a busca é que a soma dos elementos tem que ser igual ao produto dos primos que queremos excluir. Então, para 2 e 3 a nossa série é (2, 4), cuja soma é igual e 2*3.

A série para 2, 3 e 5 é (4, 2, 4, 2, 4, 6, 2, 6). A partir daí, as séries crescem seriamente. A tabela abaixo mostra a quantidade de elementos para cada uma:

PrimosElementos na série
21
2, 32
2, 3, 58
2, 3, 5, 748
2, 3, 5, 7, 11480
2, 3, 5, 7, 11, 135.760
2, 3, 5, 7, 11, 13, 1792.160
2, 3, 5, 7, 11, 13, 17, 191.658.880
2, 3, 5, 7, 11, 13, 17, 19, 2336.495.360

Quando tentei calcular a série para os primos até 29, a memória acabou. Cada série tem o número de elementos da série anterior vezes o novo primo menos um. A série dos 4 primeiros primos, por exemplo, tem 6 vezes mais elementos que a série para os 3 primeiros primos, porque adicionou o 7. A próxima série da minha tabela, portanto, deve ter 1.021.870.080 elementos (28 vezes mais que a anterior).

Usando a primeira série, reduz-se o domínio de busca pela metade (inspecionam-se apenas os ímpares). Com a segunda, resta apenas um terço (a série cobre 1/2+1/3-1/6 dos inteiros). Usando a série dos quatro primeiros primos, é preciso inspecionar apenas cerca de 22,8% dos inteiros. Logo, vê-se que a vantagem de usar séries que cobrem mais primos vai diminuindo rapidamente.