<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Aletéia</title>
	<atom:link href="http://aleteia.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://aleteia.wordpress.com</link>
	<description>Epopéias matemáticas, científicas e tecnológicas</description>
	<lastBuildDate>Sun, 08 Nov 2009 14:47:42 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='aleteia.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/2a87a6eaa3e10f062e695b5a75ce7ab9?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Aletéia</title>
		<link>http://aleteia.wordpress.com</link>
	</image>
			<item>
		<title>Gerador de Markov</title>
		<link>http://aleteia.wordpress.com/2009/11/08/gerador-de-markov/</link>
		<comments>http://aleteia.wordpress.com/2009/11/08/gerador-de-markov/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 14:38:11 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=431</guid>
		<description><![CDATA[Gerador de Markov
Um dos sites mais úteis que existem é o Gerador de Lero-lero. Não tenho certeza se o algoritmo usado é um Gerador de Markov mesmo, mas se não for, a idéia é bem parecida.
Gerador de Markov é um programa que analisa um texto procurando as combinações de palavras mais comuns e então gera [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=431&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Gerador de Markov</p>
<p>Um dos sites mais úteis que existem é o <a href="http://padrelevedo.hpg.ig.com.br/lerolero/lerolero.html">Gerador de Lero-lero</a>. Não tenho certeza se o algoritmo usado é um Gerador de Markov mesmo, mas se não for, a idéia é bem parecida.</p>
<p>Gerador de Markov é um programa que analisa um texto procurando as combinações de palavras mais comuns e então gera um texto usando as mesmas combinações em um texto que é estatisticamente similar ao anterior. Como essa análise será feita depende da implementação. Eu escolhi usar combinações de 3 palavras, ou seja, uma palavra do texto gerado depende das duas anteriores a ela. Variando a quantidade de palavras usadas em cada combinação, altera-se o texto resultante: se eu escolhesse combinações de uma palavra, o texto gerado seria completamente aleatório, se eu escolhesse combinações de dez palavras, o texto resultante ficaria mais parecido com o original.</p>
<p>A implementação de um Gerador é relativamente simples, clique em “Ler o resto do artigo” para ter acesso ao código em Common Lisp. O código está bem dividido e cada função tem uma função clara (evidentemente).</p>
<p>Primeiramente, criamos uma hash-table que conterá as combinações de palavras. Usamos uma hash-table por ela ser mais eficiente. Se usássemos listas ou árvores, teríamos de fazer buscas toda vez que o Gerador fosse adicionar uma nova palavra ao texto. Logo no começo também, inicializamos o gerador de números aleatórios.</p>
<p>Para que possamos analisar as combinações de palavras, precisamos primeiro dividir a string em uma lista de strings. A função &#8220;space-position&#8221; se ocupa de descobrir onde fica o próximo &#8220;divisor de palavras&#8221;, ou seja, um espaço, um tab ou uma quebra de linha. O que vier antes será o delimitador. Se houver vários espaços em sequência, nós teríamos uma lista com algumas strings vazias, mas o &#8220;cond&#8221; na função &#8220;split-string&#8221; detecta isso com &#8220;(= pos 0)&#8221; e evita que isso aconteça.</p>
<p>Logo em seguida vem algumas funções auxiliares. &#8220;Last-two&#8221; retorna os dois últimos elementos de uma lista qualquer. Precisaremos dela mais tarde. &#8220;Random-elt&#8221; e &#8220;random-key&#8221; retornam um elemento aleatório de uma lista e uma chave aleatória de uma hash-table respectivamente. &#8220;List-triples&#8221; retorna os trios que podem ser formados de uma lista. Note que ela não gera todos os arranjos possíveis, apenas as combinações sequenciais. Imagine que existe um bloco com espaço para três &#8220;coisas&#8221;. Esse bloco percorre a lista sequencialmente gerando os trios. Assim, a lista &#8216;(1 2 3 4 5) seria percorrida como: &#8216;((1 2 3) 4 5), &#8216;(1 (2 3 4) 5) e &#8216;(1 2 (3 4 5)). Portanto, (list-&gt;triples &#8216;(1 2 3 4 5)) retornaria &#8216;((1 2 3) (2 3 4) (3 4 5)). &#8220;String-&gt;symbol&#8221; retorna um símbolo com o mesmo nome que o conteúdo da string passada como argumento. Não me pergunte porque eu preferi usar símbolos ao invés de strings mesmo. Talvez o gerador ficaria melhor assim, já que ele saberia diferenciar quando uma palavra está iniciando uma frase pela letra maiúscula, ou talvez isso não mudasse lá grande coisa.</p>
<p>&#8220;Insert-triple-into-table&#8221; é a função que faz o trabalho sujo: ela é a responsável por inserir os trios gerados por &#8220;list-&gt;triples&#8221; na hash-table que críamos no começo do programa. Ela é feia, não é uma função que me orgulho de ter escrito, mas ela funciona. Perceba que cada entrada na hash-table inicial é, por sua vez, outra hash-table. Essa segunda hash-table guarda uma lista com as possíveis palavras que podem ser usadas.</p>
<p>&#8220;Insert-string-into-table&#8221; organiza o trabalho de separar uma string em uma lista de strings, transformá-las em símbolos, gerar os trios e inserí-los na hash-table.</p>
<p>&#8220;Insert-file-into-table&#8221; foi uma função que deu trabalho escrever. Inicialmente, ela seria a função responsável por abrir um arquivo, salvá-lo como uma string e então passar para &#8220;insert-string-into-table&#8221;. Porém, a forma com que fiz isso era péssima, o consumo de memória ia para as alturas e o tempo de execução também. Em uma das tentativas, reimplementei boa parte da &#8220;insert-string-into-table&#8221; em &#8220;insert-file-into-table&#8221;, mas acabei deixando as duas funções mesmo assim, já que as duas são úteis. Depois, consegui implementar esta função segundo a idéia original com um desempenho muito melhor.</p>
<p>Finalmente, a parte interessante: &#8220;generate&#8221; gera um texto com no máximo o número específicado de palavras. Não há garantias de que ele gerará o número máximo, já que algumas combinações podem fazer com que ele não consiga gerar mais nada.</p>
<p>Só para me exibir, resolvi colocar alguns trechos que o Gerador criou tendo como base o texto deste artigo (um artigo recursivo):</p>
<p>&#8220;logo no começo também, inicializamos o gerador de markov mesmo, mas se não for, a idéia é bem parecida.&#8221;</p>
<p>&#8220;gerador de markov é um gerador de markov&#8221;</p>
<p>&#8220;se houver vários espaços em sequência, nãs teríamos uma lista e uma chave aleatória de uma lista e uma chave aleatória de uma lista com algumas strings vazias, mas o &#8220;cond&#8221; na função &#8220;split-string&#8221; detecta isso&#8221;</p>
<p>Eu o tenho usado nas conversas de MSN com sucesso. Ele detecta que a outra pessoa falou &#8220;oi <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#8221; e gera o texto &#8220;olá =]&#8221; ou variação. Depois ele detecta a combinação &#8220;tudo bom?&#8221; e responde &#8220;sim, e contigo?&#8221;. Depois ele passa o comando para mim. OK, isso não é sério&#8230; ainda. Preciso aprender a fazer plugins para o Pidgin ainda (o bitlbee seria mais interessante nesse aspecto).</p>
<p><span id="more-431"></span></p>
<pre>
(defparameter *table* (make-hash-table))
(setq *random-state* (make-random-state t)) ; Random seed

(defun space-position (string)
  "Finds the position of a 'space' character in a string. By 'space' I mean a
newline, space or tab character."
  (let ((sp (position #\Space string))
        (nlp (position #\Newline string))
        (tp (position #\Tab string)))
    (let ((values-list (remove-if #'null (list sp nlp tp))))
      (if values-list
          (apply #'min values-list)
          nil))))

(defun split-string (string)
  "Splits a string into a list of strings use spaces as delimeters."
  (let ((pos (or (space-position string) -1)))
    (cond ((= pos -1) (list string))
          ((= pos 0)  (split-string (subseq string (1+ pos))))
          (t (append (list (subseq string 0 pos))
                     (split-string (subseq string (+ pos 1))))))))

(defun last-two (list)
  "Returns the last two elements from a list."
  (let ((l (length list)))
    (if (&gt; l 1)
        (list (nth (- l 2) list) (nth (- l 1) list))
        nil)))

(defun random-elt (list)
  "Returns a random element from a list"
  (let ((l (length list)))
    (if (= l 0)
        nil
        (nth (random (length list)) list))))

(defun random-key (table)
  "Returns a random key from table"
  (random-elt (loop for key being the hash-keys of table collect key)))

(defun list-&gt;triples (list)
  "Returns sequencial triples from a list."
  (if (&lt; (length list) 3)
      nil
      (append (list (list (nth 0 list) (nth 1 list) (nth 2 list)))
              (list-&gt;triples (cdr list)))))

(defun string-&gt;symbol (string)
  "Convert a string into a symbol"
  (intern (string-upcase string)))

(defun insert-triple-into-table (triple)
  "Insert a triple of symbols in the table"
  (if (hash-table-p (gethash (first triple) *table*))
      (progn
        (setf (gethash (second triple) (gethash (first triple) *table*))
              (push (third triple) (gethash (second triple) (gethash (first triple) *table*)))))
      (progn
        (setf (gethash (first triple) *table*) (make-hash-table))
        (setf (gethash (second triple) (gethash (first triple) *table*))
              (list (third triple))))))

(defun insert-string-into-table (string)
  "Inserts the string into a hash table."
  (mapcar #'insert-triple-into-table
          (list-&gt;triples (mapcar #'string-&gt;symbol (split-string string)))))

(defun insert-file-into-table (filename)
  (let ((str ""))
    (with-open-file (f filename :direction :input)
      (loop for line = (read-line f nil 'eof) until (eq line 'eof)
         do (setq str (concatenate 'string str '(#\newline) line))))
    (insert-string-into-table str)))

(defun generate (words)
  "Generate a text with 'words' words."
  (let* ((first-word (random-key *table*))
         (second-word (random-key (gethash first-word *table*)))
         (text (list second-word first-word))) ;;; This list will be reversed
    (dotimes (i words)
      (let ((first-table (gethash (second text) *table*)))
        (if (hash-table-p first-table)
            (push (random-elt (gethash (first text) first-table)) text))))
    (format t "~(~{~a ~}~)" (reverse text))))
</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/431/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/431/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/431/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/431/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/431/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/431/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/431/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/431/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/431/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/431/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=431&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/11/08/gerador-de-markov/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>Streams (listas infinitas) em C</title>
		<link>http://aleteia.wordpress.com/2009/10/10/streams-listas-infinitas-em-c/</link>
		<comments>http://aleteia.wordpress.com/2009/10/10/streams-listas-infinitas-em-c/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 15:58:46 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=423</guid>
		<description><![CDATA[Ultimamente tenho feito duas coisas: lido sobre Haskell e não postado no blog (além das outras coisas do dia-a-dia, claro).
Programas em Haskell são preguiçosos. Isso significa que quando uma variável é definida, ela só será computada quando seu valor for necessário. Assim, se fizermos um programa similar ao de baixo, fatorial de 1000 nunca será [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=423&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Ultimamente tenho feito duas coisas: lido sobre Haskell e não postado no blog (além das outras coisas do dia-a-dia, claro).</p>
<p>Programas em Haskell são preguiçosos. Isso significa que quando uma variável é definida, ela só será computada quando seu valor for necessário. Assim, se fizermos um programa similar ao de baixo, fatorial de 1000 nunca será calculado, já que o seu valor não é necessário para calcular 1+1.</p>
<p><code>x = factorial 1000<br />
putStrLn $ show (1+1)</code></p>
<p>Extrapolando essa mesma ideia* para outras definições, podemos definir uma lista de infinitos uns:</p>
<p><code>uns = repeat 1</code></p>
<p>Ou então com todos os números naturais:</p>
<p><code>naturais = [1..]</code></p>
<p>Com um pouco mais de perspicácia, é possível criar listas contendo todos os números de Fibonacci, ou então todos os fatoriais:</p>
<p><code>fibs = 1:1: (zipWith (+) fibs (tail fibs))<br />
facs = 1:(zipWith (*) facs [1..])</code></p>
<p>Se quisermos 10 elementos de cada, fazemos:</p>
<p><code>dezFibs = take 10 fibs<br />
dezFacs = take 10 facs</code></p>
<p>Essa implementação é bastante eficiente : se precisamos do fatorial de 10 e logo em seguida o de 11, não precisamos calcular 11×10×9×&#8230;×1, basta calcular 11×10!, que já havia sido computado. Melhor ainda : se uma hora precisarmos do fatorial de 7, ele já estará calculado, pronto para ser utilizado. </p>
<p>Agora sim a parte interessante, em que C entra nessa história. Embora minha implementação não seja nem de longe tão interessante como a utilizada pelo Haskell, ela serve de base para mostrar como uma implementação de <em>stream</em> ou listas infinitas pode ser feita em C.</p>
<p>A grande diferença entre listas e <em>streams</em> é que não trabalharemos com a idéia de um ponteiro para o próximo elemento, mas sim com uma expressão que ao ser executada nos dará o próximo elemento. Ou seja, ao invés de um ponteiro para outro elemento do mesmo tipo, nós temos um ponteiro para uma função.</p>
<pre class="brush: cpp;">
typedef struct {
    int i;
    int (*cont)(int);
} stream;
</pre>
<p>Isso altera a forma como acessamos o próximo elemento. Não podemos mais utilizar o famoso <tt>ptr = ptr-&gt;prox</tt> porque estaremos apontando para uma função. Por isso, abstraí o processo de chamar a função com o valor da <em>stream</em> em uma função chamada <tt>proximo</tt>, que retorna uma nova <tt>struct</tt> com seu valor <tt>i</tt> atualizado pela função <tt>cont</tt>, o que dá a impressão de que avançamos na lista.</p>
<pre class="brush: cpp;">
stream proximo(stream inicio)
{
    stream tmp;

    tmp.i = (*inicio.cont)(inicio.i);
    tmp.cont = inicio.cont;

    return(tmp);
}
</pre>
<p>Para exemplificar o uso de <em>streams</em>, criei a função <tt>pega</tt> que é similar à função <tt>take</tt> no Haskell, mas que no caso não retorna os valores, só os imprime.</p>
<pre class="brush: cpp;">
void pega(int elementos, stream inicio)
{
    int i;
    stream atual = inicio;

    for(i = 0; i &lt; elementos; i++)
    {
        printf(&quot;%d\n&quot;,atual.i);
        atual = proximo(atual);
    }
    printf(&quot;.\n.\n.\n\n&quot;);
}
</pre>
<p>Por fim, criei duas <em>streams</em> e duas funções auxiliares (que falta fazem expressões lambda). O código completo se encontra abaixo:</p>
<pre class="brush: cpp;">
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;

typedef struct {
    int i;
    int (*cont)(int);
} stream;

stream proximo(stream inicio)
{
    stream tmp;

    tmp.i = (*inicio.cont)(inicio.i);
    tmp.cont = inicio.cont;

    return(tmp);
}

int soma_um(int i)
{
    return(i+1);
}

int repete(int i)
{
    return(i);
}

void pega(int elementos, stream inicio)
{
    int i;
    stream atual = inicio;

    for(i = 0; i &lt; elementos; i++)
    {
        printf(&quot;%d\n&quot;,atual.i);
        atual = proximo(atual);
    }
    printf(&quot;.\n.\n.\n\n&quot;);
}       

int main(int argc, char *argv[])
{
    stream naturais, identidade;

    naturais.i = 1;
    naturais.cont = &amp;soma_um;

    identidade.i = 1;
    identidade.cont = &amp;repete;

    pega(10, naturais);
    pega(10, identidade);
    return 0;
}
</pre>
<p>*eu escrevi “idéia” mas aparentemente os verificadores ortográficos já aderiram todos às novas regras ortográficas&#8230; fica assim mesmo.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/423/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=423&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/10/10/streams-listas-infinitas-em-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>C: Hash tables, arrays associativos, dicionários&#8230;</title>
		<link>http://aleteia.wordpress.com/2009/08/09/c-hash-tables-arrays-associativos-dicionarios/</link>
		<comments>http://aleteia.wordpress.com/2009/08/09/c-hash-tables-arrays-associativos-dicionarios/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 16:29:33 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=411</guid>
		<description><![CDATA[Não sei quantos nomes existem para descrever esta forma de organizar séries de dados na memória, esses três do título foram as que eu consegui pensar em 5 segundos.  
Enfim, comecemos pela forma mais simples de armazenar séries de dados na memória, arrays, seguiremos para listas, árvores, e então chegaremos às hash tables. Se [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=411&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Não sei quantos nomes existem para descrever esta forma de organizar séries de dados na memória, esses três do título foram as que eu consegui pensar em 5 segundos. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Enfim, comecemos pela forma mais simples de armazenar séries de dados na memória, arrays, seguiremos para listas, árvores, e então chegaremos às <em>hash</em> tables. Se tudo que você quer é um exemplo de implementação, vá ao fim do artigo.<br />
<span id="more-411"></span></p>
<h1>Arrays</h1>
<p>Internamente, quando se declara um array, um bloco de memória contínuo é alocado. Isso significa que elementos de um array estão sempre próximos entre si e que percorrer todo um array é relativamente rápido. O ponto fraco dos arrays é não serem flexíveis: Um array de tamanho 5 tem tamanho 5 e pronto, acabou. É possível criar um array <em>b</em> com tamanho 6 e copiar os 5 primeiros elementos de <em>a</em> para <em>b</em>, mas o array <em>a</em> continua tendo tamanho 5. No entanto, se esse tipo de operação começa a se tornar frequente demais, a vantagem de performance do array começa a desaparecer.</p>
<p>Primeiro, é necessário alocar o novo array e copiar os elementos. Depois, é necessário limpar o array anterior, ou daremos início a um gasto desnecessário de memória.</p>
<p>Com o problema da flexibilidade em mente [1], foi criado um novo método para lidar com séries de dados, as listas ligadas/<em>linkadas</em>.</p>
<h1>Listas</h1>
<p>Listas ligadas recebem esse nome porque cada nó (<em>node</em>) se liga a outro. Existem algumas formas diferentes de se implementar isso, como:</p>
<ul>
<li>Cada elemento aponta para o próximo. O último aponta para <tt>NULL</tt>. É assim que funcionam as <em>cons cells</em> em Lisp, Haskell e aposto que em várias outras linguagens.</li>
<li>Cada elemento aponta para o próximo e o anterior. Isso facilita algumas operações, mas complica outras. Há um aumento no consumo de memória também, já que são necessários dois ponteiros.</li>
</ul>
<p>Existem outras formas, assim como variações dessas. Lembre-se que há sempre uma troca entre consumo de memória e eficiência no processamento. Existem formas de usar listas que apontam para o próximo elemento e para o anterior usando apenas um ponteiro, mas para isso é necessária uma operação a mais (XOR).</p>
<p>Um detalhe sobre listas: geralmente os novos elementos dela são &#8220;empurrados&#8221; (<em>push</em>) no começo da lista, ao invés de adicionados (<em>append</em>) ao fim da mesma. O código fica muito mais rápido assim, já que não é necessário percorrer toda a lista para adicionar um novo elemento.</p>
<p>Existem também as árvores binárias, que estruturalmente são parecidas com listas, mas que apresentam outras vantagens e desvantagens.</p>
<h1>Árvores binárias</h1>
<p>Árvores binárias facilitam muito nas buscas: Se a condição <em>c</em> for verdadeira, siga à esquerda, senão, siga à direita. Isso significa que mesmo em árvores muito grandes, o número de &#8220;passos&#8221; dados é relativamente pequeno. Para se ter uma idéia, em uma árvore com 100.000 elementos, no máximo 17 &#8220;passos&#8221; terão de ser dados (<img src='http://l.wordpress.com/latex.php?latex=%5Clog_2+100.000+%3D+16%2C6+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\log_2 100.000 = 16,6 ' title='\log_2 100.000 = 16,6 ' class='latex' />). No entanto, para que isso seja verdade, a árvore tem de estar bem equilibrada (tanto o lado esquerdo como o direito terem o mesmo número de níveis). Existem algoritmos para isso, mas não entrarei nesses detalhes.</p>
<p>Toda essa agilidade em buscas vem com um preço: a inclusão de novos elementos em uma árvore é mais próxima da função <em>append</em> em uma lista que um <em>push</em>. Apesar de não ser necessário atravessar a árvore toda, ainda é necessário fazer comparações e tomar decisões a partir daí. Além disso, árvores consomem um pouco mais de memória, já que são necessários dois ponteiros (esquerda e direita) ao invés de só um (próximo) como geralmente é o caso em listas.</p>
<p>Por fim, existem as <em>hash tables</em>, que mistura arrays com listas e tem bom desempenho em buscas.</p>
<h1><em>Hash tables</em></h1>
<p><em>Hash tables</em> são arrays de pequenas listas. No entanto, esse array não é acessado sequencialmente. Para ficar mais claro, vou começar com a função que dá nome a esse método: a função de <em>hash</em>.</p>
<p><strong>Função hash</strong><br />
Esta função tem por objetivo associar um número a uma &#8220;coisa&#8221;. No exemplo que darei mais a diante, a função hash associa um número a uma pessoa a partir de seu nome. É esse número que nos dirá em que posição do array a &#8220;coisa&#8221; será armazenada; por isso, é preciso levar duas coisas em consideração: seu tempo de execução, já que ela será executada na adição de novos elementos e na busca por elementos já existentes, e a probabilidade de ela gerar o mesmo número para representar objetos diferentes.</p>
<p><strong>Colisões</strong><br />
Se por um acaso a função hash gerar o mesmo número <em>n</em> para dois elementos, o programa não travará, nem o elemento anterior será apagado. O que ocorrerá é que a posição <em>n</em> deixará de conter unicamente um elemento, agora ela contém uma pequena lista de dois elementos.</p>
<p>Por que todo esse alarde sobre funções hash que gerem números diferentes? Pelo simples fato de que se você incluiu 10 elementos em um array com 10 posições, era de se esperar que em geral cada posição tivesse apenas um elemento. No entanto, com uma função hash ruim, pode acontecer de uma única posição ter, por exemplo, oito elementos. Analisando a performance deste caso, parece muito mais uma lista que uma <em>hash table</em>.</p>
<p>Lembre-se de que a função hash não pode ser aleatória ou depender do tempo, por exemplo, ou você não irá encontrar o elemento na hora de fazer uma busca!</p>
<p><strong>O Array</strong><br />
O número de colisões entre os números não depende exclusivamente da função hash. É evidente que se o programa for salvar 1000 elementos em um array de 10 posições, haverá várias colisões. Pelo outro lado, salvar 10 elementos em um array de 1000 posições é um desperdício enorme de memória.</p>
<p><strong>O código</strong></p>
<p>Creio que o código esteja bastante claro, mas qualquer coisa perguntem. Se vocês quiserem &#8220;ver&#8221; um caso de colisão, troque o 5 na linha <tt>#define REGISTROS 5</tt> por 4.</p>
<pre class="brush: cpp;">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

/* Define o numero de posicoes no array. Note que esse nao eh o limite maximo */
#define REGISTROS 5

/* Abstracao de uma pessoa. Apenas para exemplo. */
typedef struct Pessoa Pessoa;
struct Pessoa {
    char *nome;
    char *profissao;
    unsigned short idade;
    unsigned short senha;
    Pessoa *proxima;
};

/* Onde os registros serao salvos */
Pessoa *pessoas[REGISTROS];

unsigned int hash(const char *nome);
unsigned int registrar_pessoa(Pessoa *p);
Pessoa *achar_pessoa(const char *nome);

int main(int argc, char *argv[])
{
    /* Exemplos */
    Pessoa joao = { &quot;Joao Ninguem&quot;, &quot;Bohemio&quot;, 21, 6969, NULL };
    Pessoa jose = { &quot;Jose Pessoa&quot;,  &quot;Nerd&quot;, 12, 1234, NULL };

    registrar_pessoa(&amp;joao);
    registrar_pessoa(&amp;jose);

    achar_pessoa(&quot;Joao Ninguem&quot;);
    achar_pessoa(&quot;Jose Pessoa&quot;);
    achar_pessoa(&quot;Maria Pessoa&quot;);

    return 0;
}

/* Dado um nome, retorna um numero no intervalo [0,REGISTROS[ */
unsigned int hash(const char *nome)
{
    char *p = nome;
    unsigned int soma = 0;

    while(*p != 0) /* caractere nulo indica fim da string */
    {
        soma += *p;
        p++;
    }

    return(soma % REGISTROS);
}

/* Registra uma pessoa no array */
unsigned int registrar_pessoa(Pessoa *p)
{
    unsigned int posicao;
    if(p == NULL)
        exit(1);

    posicao = hash(p-&gt;nome);

    /* Posicao vazia, basta incluir a pessoa aqui */
    if(pessoas[posicao] == NULL)
    {
        pessoas[posicao] = p;
    }

    /* Houve uma colisao entre as posicoes, devemos usar o campo &quot;proxima&quot; */
    else
    {
        Pessoa *tmp = pessoas[posicao];
        while(tmp-&gt;proxima != NULL) tmp = tmp-&gt;proxima;
        tmp-&gt;proxima= p;
    }

    printf(&quot;registrado em %u.\n&quot;, posicao);
    return(posicao);
}    

Pessoa *achar_pessoa(const char *nome)
{
    unsigned int posicao = hash(nome);
    Pessoa *p = pessoas[posicao];

    for(; p!=NULL ; p = p-&gt;proxima)
    {
        /* Nome foi encontrado */
        if(strcmp(p-&gt;nome, nome) == 0)
        {
            printf(&quot;pessoa encontrada em %u.\n&quot;, posicao);
            return(p);
        }
    }

    /* Se a funcao chegar aqui, o loop terminou sem encontrar a pessoa, entao
     * ela nao existe */
    printf(&quot;pessoa nao encontrada.\n&quot;);
    return(NULL);
}
</pre>
<p>[1] Não tenho certeza se historicamente os arrays se desenvolveram antes das listas, eu creio que sim.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/411/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/411/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/411/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/411/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/411/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/411/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/411/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/411/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/411/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/411/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=411&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/08/09/c-hash-tables-arrays-associativos-dicionarios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8230; então eu resolvi criar um blog</title>
		<link>http://aleteia.wordpress.com/2009/08/07/entao-eu-resolvi-criar-um-blog/</link>
		<comments>http://aleteia.wordpress.com/2009/08/07/entao-eu-resolvi-criar-um-blog/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 20:14:39 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=409</guid>
		<description><![CDATA[Quem clicou no meu identi.ca viu que só estou escrevendo em inglês lá. Entretando, às vezes quero escrever um texto maior, e lá no identica não há espaço, então eu resolvi criar um blog em inglês.
Um blog não substitui o outro, a idéia é que eles se complementem, mas a verdade é que no momento [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=409&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Quem clicou no meu <a href="http://identi.ca/andrears">identi.ca</a> viu que só estou escrevendo em inglês lá. Entretando, às vezes quero escrever um texto maior, e lá no identica não há espaço, então eu resolvi criar um blog em inglês.</p>
<p>Um blog não substitui o outro, a idéia é que eles se complementem, mas a verdade é que no momento eu gosto mais do outro, por motivos que constam no primeiro post do outro blog: aqui eu sou muito mais um tradutor que um criador de conteúdo, e eu mesmo não faço parte do meu público alvo. Com isso eu consigo separar as coisas e ver cada blog em seu devido lugar, e evitar decepções.</p>
<p><a href="http://alpharhosigma.blogspot.com">αρσ (alpha rho sigma)</a></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/409/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=409&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/08/07/entao-eu-resolvi-criar-um-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>I can has twitter?</title>
		<link>http://aleteia.wordpress.com/2009/08/03/i-can-has-twitter/</link>
		<comments>http://aleteia.wordpress.com/2009/08/03/i-can-has-twitter/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 18:58:47 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=407</guid>
		<description><![CDATA[Acabei de criar um conta no Identi.ca e no Twitter. Eu vou postar principalmente em inglês, mas quem quiser fique à vontade para me seguir (preferencialmente no Identi.ca, mas isso é com vocês).
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=407&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Acabei de criar um conta no <a href="http://identi.ca/andrears">Identi.ca</a> e no <a href="http://twitter.com/andreramaciotti">Twitter</a>. Eu vou postar principalmente em inglês, mas quem quiser fique à vontade para me seguir (preferencialmente no Identi.ca, mas isso é com vocês).</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/407/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/407/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/407/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/407/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/407/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/407/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/407/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/407/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/407/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/407/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=407&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/08/03/i-can-has-twitter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>BigBusca</title>
		<link>http://aleteia.wordpress.com/2009/07/28/bigbusca/</link>
		<comments>http://aleteia.wordpress.com/2009/07/28/bigbusca/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 16:27:38 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=403</guid>
		<description><![CDATA[Estava dando uma olhada numa entrevista com o criador do BigLinux. Além de manter a distro, ele tem um site de buscas chamado &#8220;BigBusca&#8221;. Entrei para dar uma olhada, crente de que seria uma porcaria. Engano meu. Apesar do sistema de busca não ser exatamente dele (são buscas personalizadas do Google), existem opções que ficam [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=403&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Estava dando uma olhada numa entrevista com o criador do BigLinux. Além de manter a distro, ele tem um site de buscas chamado &#8220;BigBusca&#8221;. Entrei para dar uma olhada, crente de que seria uma porcaria. Engano meu. Apesar do sistema de busca não ser exatamente dele (são buscas personalizadas do Google), existem opções que ficam meio escondidas no Google mesmo.</p>
<p>Por exemplo, na pesquisa Web, é possível escolher a idade máxima dos artigos (24 horas, um mês, um ano, etc). A busca por documentos permite especificar se quero pdfs, docs, odts&#8230; A busca por imagens novamente apresenta facilidades do tipo.</p>
<p>Ah sim, o link: <a href="http://bigbusca.com/en/">BigBusca</a></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/403/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/403/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/403/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/403/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/403/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/403/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/403/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/403/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/403/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/403/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=403&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/07/28/bigbusca/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>Melhorando a aparência das fontes no Arch Linux</title>
		<link>http://aleteia.wordpress.com/2009/07/26/melhorando-a-aparencia-das-fontes-no-arch-linux/</link>
		<comments>http://aleteia.wordpress.com/2009/07/26/melhorando-a-aparencia-das-fontes-no-arch-linux/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 14:28:45 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=401</guid>
		<description><![CDATA[Eu instalei os pacotes cairo-lcd e libxft-lcd aqui e as fontes ficaram com uma aparência bem melhor. Claro que isso é subjetivo, então recomendo que experimentem os pacotes cairo-cleartype, freetype2-cleartype e libxft-cleartype.
A diferença entre eles é o algoritmo usado no subpixel shading. Pessoalmente, acho o algortimo padrão ruim, tanto que eu o deixava desligado. O [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=401&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Eu instalei os pacotes cairo-lcd e libxft-lcd aqui e as fontes ficaram com uma aparência bem melhor. Claro que isso é subjetivo, então recomendo que experimentem os pacotes cairo-cleartype, freetype2-cleartype e libxft-cleartype.</p>
<p>A diferença entre eles é o algoritmo usado no <em>subpixel shading</em>. Pessoalmente, acho o algortimo padrão ruim, tanto que eu o deixava desligado. O Cleartype é o mesmo usado pelo Windows, mas também não gosto, acho que as fontes ficam “embaçadas”. O LCD, se não me engano, é um conjunto de patches utilizado pelo Ubuntu.</p>
<p>Infelizmente, nenhum desses dois últimos poderá vir a ser o padrão por questões legais.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/401/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=401&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/07/26/melhorando-a-aparencia-das-fontes-no-arch-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>Criando fractais no Linux</title>
		<link>http://aleteia.wordpress.com/2009/07/23/criando-fractais-no-linux/</link>
		<comments>http://aleteia.wordpress.com/2009/07/23/criando-fractais-no-linux/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 15:57:06 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[Appz]]></category>
		<category><![CDATA[GNU/Linux]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=397</guid>
		<description><![CDATA[Eu adoro imagens de fractais, geralmente servem como ótimos papéis de parede e acho interessante essa conexão entre Matemática e Arte.
Durante algum tempo dei uma pesquisada nos programas disponiveis para Linux e elegi meus três favoritos:

xaos &#8211; é o mais antigo, mas é relativamente leve e roda bem até mesmo em máquinas mais modestas. Da [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=397&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Eu adoro imagens de fractais, geralmente servem como ótimos papéis de parede e acho interessante essa conexão entre Matemática e Arte.</p>
<p>Durante algum tempo dei uma pesquisada nos programas disponiveis para Linux e elegi meus três favoritos:</p>
<ul>
<li><a href="http://wmi.math.u-szeged.hu/xaos/doku.php">xaos</a> &#8211; é o mais antigo, mas é relativamente leve e roda bem até mesmo em máquinas mais modestas. Da minha galeria no DeviantArt, o único que foi feito com ele foi este: <a href="http://andreramaciotti.deviantart.com/art/Burtonian-Brain-90874358">Burtonian Brain</a>.
</li>
<li><a href="http://code.google.com/p/qosmic/">qosmic</a> &#8211; é uma interface gráfica para o flam3, mas ainda não aprendi a usá-lo muito bem.
</li>
<li><a href="http://gnofract4d.sourceforge.net/">gnofract4d</a> &#8211; é o mais amigável de todos e é possível chegar a resultados interessantes usando apenas a função &#8220;Explorer&#8221;. Um detalhe interessante é que um dos meus fractais está nos <a href="http://catenary.deviantart.com/favourites/">favoritos do criador do software</a> (o Malignific).
</li>
</ul>
<p>Para quem quiser ver, <a href="http://andreramaciotti.deviantart.com/gallery/">minha galeria no DeviantArt</a> tem alguns fractais que foram feitos usando esses programas.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/397/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=397&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/07/23/criando-fractais-no-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>Sinto-me iluminado (uma crítica aos gerenciadores de janelas do Linux) &#8211; Parte 2</title>
		<link>http://aleteia.wordpress.com/2009/07/18/sinto-me-iluminado-parte-2-2/</link>
		<comments>http://aleteia.wordpress.com/2009/07/18/sinto-me-iluminado-parte-2-2/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 23:14:59 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=394</guid>
		<description><![CDATA[Após uma semana mais ou menos com o Enlightenment, posso dizer que gosto dele, mas que ele ainda não está pronto para uso. Não duvido que quando ele estiver pronto ele será um ótimo gerenciador de janelas / desktop, mas no momento os pequenos defeitos me encomodam.
Pesquisei mais gerenciadores de janelas aqui e ali, mas [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=394&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Após uma semana mais ou menos com o Enlightenment, posso dizer que gosto dele, mas que ele ainda não está pronto para uso. Não duvido que quando ele estiver pronto ele será um ótimo gerenciador de janelas / desktop, mas no momento os pequenos defeitos me encomodam.</p>
<p>Pesquisei mais gerenciadores de janelas aqui e ali, mas os que pareciam promissores eram projetos mortos, todos os outros que pareciam interessantes eu já tinha testado e não gostava por um detalhe ou por outro.</p>
<p>Por fim, resolvi fazer o meu próprio gerenciador, baseado no que eu gostava ou não em cada gerenciador que já experimentei (e acreditem, eu já experimentei vários). Se você não quiser ler um pequeno review de cada gerenciador, pule direto para o cabeçalho “O meu”.</p>
<p><span id="more-394"></span></p>
<h3>Não <em>tilings</em>:</h3>
<ul>
<li><strong>Enlightenment:</strong> O Enlightenment é um projeto que tem futuro. Não conheço os desenvolvedores do projeto, mas aposto que são perfeccionistas; entretanto, o projeto ainda está em fase <em>alfa</em>, significando que ainda faltam muitas coisas até que ele esteja de fato utilizável.
</li>
<li><strong>XFCE4:</strong> Tem um gerenciador de janelas bom, que permite a utilização de composição, janelas transparentes, de maneira bastante fácil (e bastante leve). Infelizmente, não achei um modo de fazer com que certos programas abrissem em certos desktops virtuais.
</li>
<li><strong>KDE e GNOME:</strong> São os projetos com maior integração entre os programas que os compõe, algo que de certa forma eu sinto falta, mas ambos são monstruosos: mais de 300MB de downloads cada. Além disso, apesar de às vezes eu sentir falta de uma maior integração entre os programas, eu sei que sou minimalista na essência, e que logo me encheria dos dois.
</li>
<li><strong>Openbox:</strong> Eu gosto do Openbox, mas o uso de XML como arquivo de configuração realmente me desanima. Entre os *box, é o mais bonito.
</li>
<li><strong>Fluxbox:</strong> Fluxbox é leve e é relativamente fácil de configurar (se comparado ao Openbox), mas nem mesmo com os melhores temas ele parece ter <em>sex appeal</em>, sempre sinto que estou usando um software arcaico quando estou com ele.
</li>
<li><strong>PekWM:</strong> Um gerenciador de janelas muito bom, reune as qualidades do Openbox (é bonito) e do Fluxbox (é fácil de ser configurado). Entretanto, ele também sofre da síndrome de não parecer um software “terminado”, assim como o Enlightenment.
</ul>
<p>Além disso, não posso me enganar, os gerenciadores de janela que mais gostam foram os <em>tiling</em>, mas mesmo assim eles não são perfeitos&#8230;</p>
<h3><em>Tiling:</em></h3>
<ul>
<li><strong>DWM:</strong> Espartano demais. Ele sequer tem um arquivo de configuração propriamente dito, as configurações são feitas em um <em>header</em> (um arquivo .h) e o programa deve ser recompilado para que as alterações tenham efeito.
</li>
<li><strong>Awesome:</strong> Legal, mas seu arquivo de configuração muda mesmo a cada troca de versão menor (de 3.0 para 3.1 mudou, de 3.1 para 3.2 mudou&#8230;).
</li>
<li><strong>Xmonad:</strong> Legal, mas é escrito em Haskell, o que faz do GHC uma dependência. Eu não uso Haskell para mais nada, então ter um pacote que ocupa mais de 300MB quando descompactado é exagero.
</li>
</ul>
<h3>O meu:</h3>
<p>Baseado nisso tudo, resolvi fazer o meu. As idéias principais são:</p>
<ul>
<li>Configurável sem precisar recompilar.</li>
<li>O arquivo de configuração em hipótese alguma será em XML.</li>
<li>Pequeno número de dependências, e preferencialmente dependências pequenas.</li>
<li>Configurável por uma linguagem que permita que o gerenciador seja extensível.</li>
<li>A sintaxe do arquivo de configuração não ficará mudando de hora em hora.</li>
</ul>
<p>O resultado disso tudo é um fork do DWM que usa o ECL para lidar com seus arquivos de configuração. O que isso significa? Que o usuário tem um ambiente Lisp completo para suas configurações.</p>
<p>- Quantos desktops virtuais você quer?<br />
- 5!<br />
- Cinco fatorial? Sem problemas:</p>
<pre>(defun factorial (n)
  (if (= n 1)
      1
    (* n (factorial (1- n)))))

(workspaces (factorial 5))</pre>
<p>Assim que ele estiver minamente funcional, estarei disponibilizando o código para quem quiser testar.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/394/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/394/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/394/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=394&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/07/18/sinto-me-iluminado-parte-2-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
		<item>
		<title>Sinto-me iluminado (Enlightenment17)</title>
		<link>http://aleteia.wordpress.com/2009/07/14/sinto-me-iluminado-enlightenment17/</link>
		<comments>http://aleteia.wordpress.com/2009/07/14/sinto-me-iluminado-enlightenment17/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 15:05:47 +0000</pubDate>
		<dc:creator>André Ramaciotti</dc:creator>
				<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[enlightenment]]></category>

		<guid isPermaLink="false">http://aleteia.wordpress.com/?p=384</guid>
		<description><![CDATA[Não preciso nem dizer que sou um chato em relação a gerenciadores de janelas. Passei um tempo com o PekWM, mas ele não estava se entendendo muito bem com o Emacs. Além disso, algumas leituras recentes sobre inovações no Desktop me fizeram querer largar mão um pouco do minimalismo, estava até cogitando usar o KDE [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=384&subd=aleteia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Não preciso nem dizer que <a href="http://aleteia.wordpress.com/2009/06/20/awesome-desisto/">sou um chato em relação a gerenciadores de janelas</a>. Passei um tempo com o PekWM, mas ele não estava se entendendo muito bem com o Emacs. Além disso, algumas leituras recentes sobre inovações no Desktop me fizeram querer largar mão um pouco do minimalismo, estava até cogitando usar o KDE 4.3, e estou ansioso pelo GNOME 3.</p>
<p>Dei uma olhada na <a href="http://wiki.archlinux.org/">Wiki do Arch Linux</a> para ver que outras opções eu tinha e me lembrei do Enlightenment 17. Logo quando editei meu <tt>.xinitrc</tt> e iniciei o X com o Enlightenment, uma surpresa : Uma tela inicial permitindo a configuração de algumas coisas. O interessante é que existem “perfis” pré-configurados : um minimalista, que creio que não tenha tantos efeitos visuais, o tradicional, e dois que me chamaram a atenção para dispositivos de tela pequena (um é voltado para Netbooks e outro para dispositivos embarcados).</p>
<p>Comecei a mexer com ele e me impressionei com a atenção que foi dada aos mínimos detalhes. Por exemplo, no <em>pager</em>, dispositivos que mostra os Desktops Virtuais, existem miniaturas das janelas que estão abertas naquele Desktop. Se uma janela chama a atenção, sua miniatura no <em>pager</em> fica balançando. O ícone que aparece no canto superior esquerdo da decoração da janela também fica balançando, e aparece um ponto de exclamação.</p>
<p>Outro detalhe interessante é a existência de um botão “Modo de apresentação”. Ele desliga temporariamente a proteção de tela e as configurações de economia de energia, assim a tela não desliga enquanto você está fazendo aquela apresentação ou assistindo aquele filme.</p>
<p>Vale lembrar, entretanto, que ele ainda é uma versão em desenvolvimento. Apesar dessa atenção dispensada até aos mínimos detalhes, ele ainda não é perfeito. Por exemplo, nas configurações de que aplicativos serão iniciados automaticamente ao iniciar não é possível adicionar aplicações arbitrárias. Quando eu quis que o xbindkeys fosse iniciado junto ao Enlightenment, tive de criar um &#8220;ícone&#8221; para a aplicação e então adicioná-la à lista de aplicações iniciadas.</p>
<p>Outro problema é o gerenciador de arquivos. No momento, ele é minimamente funcional. <strong>Minimamente</strong>. Para se ter uma idéia, se estou em <tt>/home/usuario</tt>, não há como acessar <tt>/home</tt> diretamente. Ao invés de abrir Home e subir um nível, é necessário abrir o Root e clicar em home. Por enquanto fica só a promessa e a curiosidade de como seria um gerenciador de arquivos inovador.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aleteia.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aleteia.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aleteia.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aleteia.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aleteia.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aleteia.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aleteia.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aleteia.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aleteia.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aleteia.wordpress.com/384/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aleteia.wordpress.com&blog=1012158&post=384&subd=aleteia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://aleteia.wordpress.com/2009/07/14/sinto-me-iluminado-enlightenment17/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">_andre</media:title>
		</media:content>
	</item>
	</channel>
</rss>