terça-feira, 20 de novembro de 2012

SQL Gaussiano

É bem conhecida a história de quando o professor de matemática de Gauss pediu que a turma somasse todos os números até 100. O mestre esperava ter um pouco de paz enquanto as crianças trabalhassem na soma. O pequeno Gauss, no entanto, resolveu a questão rapidamente.

A solução era simples. Ele somou 1 com 100, depois 2  com 99, então 3 com 98 e assim por diante. Vindo pelas pontas, a soma é sempre 101 e depois de 50 somas, os números encontram-se em 50 e 51. O total, portanto, é 50 vezes 101.

Esse pequeno truque pode ser usado no SQL para encontrar sequências de números ou de datas. Considere os seguintes números: 1; 2; 3; 5; 6; 8; 9; e 10. Se cada um estiver numa linha de uma tabela, eu quero uma consulta que gere o seguinte resultado:

   1   3
   5   6
   8 10

É necessária uma sequência decrescente para fazer o jogo com a nossa sequência crescente. Isso podemos resolver facilmente com funções analíticas. Na consulta abaixo, já somo cada número ao seu equivalente.


select n, n+row_number() over (order by n desc)
from numeros
order by n


Isso vai produzir as seguintes linhas:

19
29
39
510
610
811
911
1011

E todos os números consecutivos compartilham o mesmo valor na segunda coluna. O que nos resta é agrupá-los e encontrar o máximo e mínimo de cada grupo. Assim, chegamos ao nosso objetivo:


select min(n), max(n) from (
  select n, n+row_number() over (order by n desc) grupo
  from numeros
)
group by grupo
order by 1


O resultado é, conforme esperado, este:

   1   3
   5   6
   8 10

O mesmo pode ser feito com datas, basta tratar cada uma como o número de dias a partir da primeira data.

terça-feira, 13 de novembro de 2012

Nau em chamas

Quase sem querer, encontrei um fractal curioso chamado Burning Ship. Ele é uma variação do conjunto de Mandelbrot; a única diferença é que, a cada iteração, são aplicados os valores absolutos dos componentes imaginário e real.

Aproveitei o código de aventuras anteriores. Com o Javascript abaixo é possível analisar este fractal; basta clicar sobre a imagem para inspecionar regiões cada vez menores.

<html>
  <head>
  </head>
  <body>
    <canvas id="canvas" width="256" height="256"></canvas>
    <script>

function mandel(x,y) {
  var c=1;
  var r=0;
  var i=0;
  var MAXITER=512;
  while(r*r+i*i<4 && c<MAXITER) {
    var t=2*Math.atan2(i,r);
    var d=Math.pow(Math.sqrt(r*r+i*i),2);
    var nr=d*Math.cos(t)+x;
    var ni=d*Math.sin(t)+y;
    r=Math.abs(nr);//Aqui ocorre
    i=Math.abs(ni);//a mágica
    c+=1;
  }
  return c;
}

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var imageData=ctx.getImageData(0,0,256,256);
   
var minx=-2;
var miny=-2;
var maxx=2
var maxy=2;
   
  
function plot() {
  var deltax=(maxx-minx)/256;
  var deltay=(maxy-miny)/256;
 
  for(var x=0; x<256; x++) {
    for(var y=0; y<256; y++) {
      var c=mandel(minx+x*deltax, miny+y*deltay);
      var red=(c*8)%255;
      var green=(c*9)%255;
      var blue=(255-c*4)%255;
      var index=(x+y*imageData.width)*4;
      imageData.data[index+0]=red;
      imageData.data[index+1]=green;
      imageData.data[index+2]=blue;
      imageData.data[index+3]=0xff;
    }
  }
  ctx.putImageData(imageData,0,0);
}
plot();
   
function zoom(e) {
  var x=minx+(maxx-minx)*((e.clientX-canvas.offsetLeft)/256);
  var y=miny+(maxy-miny)*((e.clientY-canvas.offsetTop)/256);
  var dx=(maxx-minx)/4;
  var dy=(maxy-miny)/4;
  
  minx=x-dx;
  maxx=x+dx;
  miny=y-dy;
  maxy=y+dy;
  plot();
}
canvas.onclick=zoom;
   
    </script>
  </body>
</html>

Como se espera de um fractal, o tema torna a surgir com formas e cores ligeiramente diferentes.

segunda-feira, 12 de novembro de 2012

O iPad mini e o novo consumidor de TI

Observando alguns comentários e algumas avaliações do novo iPad mini eu percebi um mudança radical em relação aos consumidores de micros de 8 bits na década de 1980. O novo comprador de TI quer a perfeição e não se importa em gastar muito dinheiro para ter o melhor para cada situação.

O novo iPad mini, dizem, é muito melhor para carregar pela rua e ler no ônibus. Os modelos anteriores são grandes e pesados. Mas há pouco tempo tudo era perfeito; surge agora um novo modelo mais perfeito ainda.

O comprador de micros de 8 bits era um sonhador. Ele tinha que enxergar muito longe para ver algum potencial naquelas máquinas lentas e com pouquíssima memória. Os jogos exigiam muita criatividade tanto dos programadores como dos jogadores.

Junto com essa mudança nas expectativas, sumiram aquelas revistas legais para amadores, a Byte sendo a mais interessante (embora um pouco mais técnica que as outras). Hoje em dia temos revistas para profissionais (sobre Java, SQL, e outros assuntos bem específicos) e algumas revistas de consumidor com avaliações superficiais (como a Info Exame).

Eu sinto falta daquelas revistas, porque sempre abriam portas para áreas novas: gerar fractais, simular colisões de galáxias, fazer música. Parece que agora que o micro é poderoso, as pessoas não se preocupam em explorá-lo.

Torço que com o lançamento dessas plataformas pequenas, como o Raspberry Pi, voltem a surgir publicações para amadores inquisitivos. Enquanto isso, vou vasculhando as revistas antigas por projetos interessantes.