Fotolog.net Feed

[update] O script foi reescrito aqui e está muito mais interessante agora! :-) [/update]

Não sei se isso já não existe; Não sei se ninguém nunca sentiu falta. Afim de valorizar feeds RSS e acompanhar fotos de amigos, resolvi criar um feed para fotologs do Fotolog.net.

Eu disponibilizei o código aqui: ff.phps (infelizmente esse código foi perdido com o tempo) mas o script para uso coloquei no “meu servidor super-poderoso” na UNICAMP: ff.php (infelizmente esse arquivo foi perdido com o tempo), por um motivo óbvio: economia de banda. Só que os caras da UNICAMP devem excluir o meu usuário algum dia, por isso sugiro que você pegue o código e coloque no seu servidor. Só precisa ter fopen_wrappers (quem que já programou em PHP e nunca viu aquela mensagem no manual: Tip: You can use a URL as a filename with this function if the fopen wrappers have been enabled? :D )

Hmmm… Talvez esse código tenha algum bug. Não sei o porquê de nenhum dos meus feeds funcionarem no Google Reader. Quem tiver afim de corrigir, me manda o novo arquivo que arrumarei com enorme satisfação (e aproveita pra me ensinar onde foi que eu errei!). Além disso, tenho dúvidas sobre se a foto pode ser aberta de fora do Fotolog.net. No Bloglines, só consegui visualizar as fotos que eu já tinha no cache do navegador. Pra mim isso não faz muita diferença, já que eu gosto de feeds na barra de favoritos do Firefox.

Coisas legais que vi hoje

Compras e Blog

Hoje, no Linuxmall, comprei um pequeno livro chamado Invasão de Redes: Ataques e Defesas e foi escrito por Tiago José Pereira Nogueira. Nunca vi nada desse cara, ninguém me recomendou esse livro e não conheço ninguém que já tenha lido ou comentado alguma coisa sobre ele. É um livro que parece ser novo e me deu vontade de comprar porque sempre quis saber trabalhar com redes no C. Ele aborda tópicos interessantes, como sockets e conexões, port scanners, DDoS, entre outras coisas. Só tô explicando pra vocês não pensarem que eu comprei porque decidi virar um cracker maligno invasor de redes… :lol: Aproveitei o frete pra comprar também um novo adesivo pro laptop, um Tux grande (de 11x13cm – eu medi antes pra ver se ficava legal no laptop) que custou R$ 2,00. A compra deve chegar quinta-feira. A propósito, alguém já ouviu falar de E-Sedex? Parece ser legal… Barato e rápido! Pedi essa compra com ele pra testar. Faz tanto tempo que não compro na internet que eu fico por fora dessas novidades!

Vou aproveitar o post pra postar os códigos que eu estou fazendo pra interpretação de BBCodes e estatísticas do blog que eu, o Hélio e o Gustavo começamos a desenvolver semana passada e queremos acabar até no máximo o final de novembro (pretendemos acabar perto do dia 15/11).

Expressões Regulares

<?php
/* A parte de regex de códigos precisa do GeSHi Highlighter. Includando-o... */
include("geshi.php");

/* Essa classe serve para ser usada com "extends", ela sozinha "não é nada". */
class Regex {

    /* Função que interpreta emoticons */
    function Emoticons() {
        $origem=Array(":)", ":(", ":D", ":P", ":O", ":S", ":lol:", ":blink:");
        $destino=Array("feliz.gif", "triste.gif", "sorriso.gif", "lingua.gif", "espantado.gif", "confuso.gif", "riso.gif", "confuso.gif");
        // EM DESENVOLVIMENTO!
    }

    /* Função que interpreta BBCodes...
     * Totalmente desenvolvida por mim. (nem parece de tão linda, né?) */
    function InterpretaBBCodes() {
        /* Vamos começar pelos [codes], porque só o que tá fora deles deve ser
           interpretado depois. */

        preg_match_all("/[code language=([a-z]+)](.*)[/code]/sU", $this->texto, $matches_com_linguagens);
        preg_match_all("/[code](.*)[/code]/sU", $this->texto, $matches_sem_linguagens);

        /* - A parte dos códigos é $matches_com_linguagens[$i][2] e $matches_sem_linguages[$i][1].
               - A parte que diz em que linguagem os códigos $matches_com_linguagens[$i][2] foi escrita
              é $matches_com_linguagens[$i][1].
           - Para facilitar os códigos abaixo, vou trocar matches_com_linguagens para mcl e
           matches_sem_linguagens para msl. Só não fiz em cima pra quem tá de fora entender o que
           eu tô fazendo nessa parte do código. ;)
        */

        $mcl=$matches_com_linguagens;
        $msl=$matches_sem_linguagens;

        $con=0;
        for ($i=0; $i<sizeof ($mcl[0]); $i++) {
            $g=new GeSHi($mcl[2][$i], $mcl[1][$i], "./geshi/");
            $geshi_mcl[$i]=$g->parse_code();
            $mcl_md5[$i]=md5(time()*$con++);
            $this->texto=str_replace($mcl[0][$i], $mcl_md5[$i], $this->texto);
        }
        for ($i=0; $i</sizeof><sizeof ($msl[0]); $i++) {
            /* Aqui, vocês vão perguntar: "Por que passar no GeSHi, se não sei highlightear essa linguagem?
               A resposta é que o GeSHi não só highlighta, mas formata o código de forma que ele fique
               legível (por exemplo, troca < por &lt. */
            $g=new GeSHi($msl[1][$i], "", "./geshi/");
            $geshi_msl[$i]=$g->parse_code();
            $msl_md5[$i]=md5(time()*$con++);
            $this->texto=str_replace($msl[0][$i], $msl_md5[$i], $this->texto);
        }

        /* Beleza, agora precisamos sempre lembrar de não highlightear o que estiver entre
           E também não podemos deixar nada fora dos padrões XHTML Strict. */

        $this->texto=str_replace("&", "&", $this->texto);
        $this->texto=str_replace("< ", "<", $this->texto);
        $this->texto=str_replace(">", ">", $this->texto);
        $this->texto=str_replace(""", """, $this->texto);

        // Aqui tá o meu "nl2br" semântico! =)
        $this->texto="<p>".$this->texto."</p>";
        $this->texto=preg_replace("/\n\n\n*/", "<p>", $this->texto);
              /* </p><p></p> vazios não são semânticos. Mas estive pensando depois de fazer isso e acho que
                  algumas pessoas podem querer dar um grande espaço entre os <p>, por isso estou
                  pensando em fazer uma ER que a cada n a mais de dois n's adicione 10px ao
                  margin-bottom do último </p><p>. O que vocês acham? */
        $this->texto=preg_replace("/\n/", "<br />\n", $this->texto);
        $this->texto=preg_replace("/</p></p><p>/", " </p>\n<p>", $this->texto);

        // Formatação básica (negrito, itálico, sublinhado, cores, cabeçalhos)
        $this->texto=preg_replace("/[b](.*)[/b]/sU", "<strong>\1</strong>", $this->texto);
        $this->texto=preg_replace("/[i](.*)[/i]/sU", "<em>\1</em>", $this->texto);
        $this->texto=preg_replace("/[u](.*)[/u]/sU", "<span style="text-decoration:underline;">\1</span>", $this->texto);
        $this->texto=preg_replace("/[color=([^]]+)](.*)[/color]/sU", "<span style="color:\1;">\2</span>", $this->texto);
        $this->texto=preg_replace("/[h([1-6])](.*)[/h\1]/sU", "<h \1>\2< /h\1>n", $this->texto);

        // Citações
        $this->texto=preg_replace("/[quote](.*)[/quote]/sU", "<q>\1</q>n", $this->texto);
        $this->texto=preg_replace("/[quote=([^]]+)](.*)[/quote]/sU", "<q>\2</q>n<cite>\1</cite>", $this->texto);

        // URLs
        $this->texto=preg_replace("/([^\"/=]])(www.[^[:blank:]\"< ]+)/", "\1<a href=\"http://\2\">\2", $this->texto);
        $this->texto=preg_replace("/([^\"=]])(http://[^[:blank:]\"< ]+)/", "\1<a href=\"\2\">\2", $this->texto);

        $this->texto=preg_replace("/[url]([^\"]*)[/url]/sU", "<a href=\"\1\">\1</a>", $this->texto);
        $this->texto=preg_replace("/[url=([^[:blank:]\"]+)[[:blank:]]+title=([^]\"]+)](.*)[/url]/sU", "<a href=\"\1\" title=\"\2\">\3</a>", $this->texto);
        $this->texto=preg_replace("/[url=([^\]\"]+)](.*)[/url]/sU", "<a href=\"\1\">\2</a>", $this->texto);

        preg_match_all("/<a href=\"([^\"]+)\">/U", $this->texto, $matches);

        for ($i=0; $i<count ($matches[0]); $i++) {
            $parse=parse_url($matches[1][$i]);
            $dominio=$parse["host"];
            $this->texto=str_replace($matches[0][$i], "<a href="".$matches[1][$i]."" title="Link Externo: $dominio">", $this->texto);
        }

        // Imagens
        $this->texto=preg_replace("/[img=([^]]+)]([^\"]*)[/img]/U", "<img src=\"\2\" alt=\"\1\" />", $this->texto);
        $this->texto=preg_replace("/[img]([^\"]*)[/img]/U", "<img src=\"\1\" alt=\"Imagem: \2\" />", $this->texto);

        // Listas
        $this->texto=preg_replace("/[list](.*)[/list]/sU", "<ul>\1</ul>", $this->texto);
        $this->texto=preg_replace("/[li](.*)[/li]/sU", "<li><p>\1</p></li>", $this->texto);

        // Limpando besteiras... Alguém tem alguma idéia melhor do que esse FOR feio?
        for ($count=0; $count<10; $count++) {
            $this->texto=preg_replace("/<br /></li>/", "", $this->texto);
            $this->texto=preg_replace("/<ul><br />/", "</ul><ul>", $this->texto);
              $this->texto=preg_replace("/< (/?)li><br />/", "< \1li>",  $this->texto);
              $this->texto=preg_replace("/<q><br />/", "</q><q>", $this->texto);
              $this->texto=preg_replace("/< /q><br />/", "</q>", $this->texto);
          }

          // Emoticons
          // $this->Emoticons();

          /* Lembram que o código tinha sido transformado em md5s com o tempo, pros
             bbcodes não entrarem em ação dentro deles? Então vamos transformar de
             volta em códigos agora... */

          for ($i=0; $i<sizeof ($mcl[0]); $i++) {
              $this->texto=str_replace($mcl_md5[$i], $geshi_mcl[$i], $this->texto);
          }

          for ($i=0; $i</sizeof><sizeof ($msl[0]); $i++) {
              $this->texto=str_replace($msl_md5[$i], $geshi_msl[$i], $this->texto);
          }

          // Limpando as besteiras que não precisam ser repetidas (e coloquei depois dos codes porque
          // aqui corrijo o negócio com os <pre>s.
          $this->texto=preg_replace("/<p>[[:blank:]]*<pre>(.*)< /pre>[[:blank:]]*< /p>/sU", "<\/pre><pre>\1<\/pre>", $this->texto);
          $this->texto=preg_replace("/</p><p>[[:blank:]]*<ul>(.*)< /ul>[[:blank:]]*< /p>/sU", "</ul><ul>\1</ul>", $this->texto);
          $this->texto=preg_replace("/</p><p>[[:blank:]]*<h (.)>(.*)< /h\1>[[:blank:]]*< /p>/sU", "</h><h \1>\2</h>", $this->texto);
          $this->texto=preg_replace("/< ([^>]+)>[[:blank:]]?< /\1>/", "", $this->texto);

          // E pra finalizar, o mais mala de todos... =)
          $this->texto.="\n";
      }
  }
  ?>

Tá bem comentado e queria pedir pra quem puder, dar uma testada com ele (coloquem uns BBCodes errados e coisas que vocês acham que eu não iria prever). Aí embaixo então a parte das estatísticas, para as quais estou usando um pouco do código do Shortstat. Ela tá assim por enquanto:

Estatísticas

<?php
class Estatisticas {
    var $ip, $pais, $codigopais, $referer, $url, $dominio, $res, $useragent, $navegador, $versaonavegador, $plataforma, $unixtime;

    /* Função que descobre o IP real do visitante
     * Copiada de: www.foo.com.br
     */
    function IpReal() {
        if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "desconhecido")) {
            $ip=getenv("HTTP_CLIENT_IP");
        } else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "desconhecido")) {
            $ip=getenv("HTTP_X_FORWARDED_FOR");
        } else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "desconhecido")) {
            $ip=getenv("REMOTE_ADDR");
        } else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "desconhecido")) {
            $ip=$_SERVER['REMOTE_ADDR'];
        } else {
            $ip="desconhecido";
        }

        return $ip;
    }

    /* Função para descobrir navegador, sistema operacional, etc. com base no User Agent.
     * "SI_parseUserAgent()" do Shortstat, levemente modificada.
     */
    function ParseUserAgent($ua) {
        $plataforma="Desconhecida";
        $navegador="Desconhecido";
        $versao="";

        if (eregi("Win", $ua)) {
            $plataforma="Windows";
        } else if (eregi("Mac", $ua)) {
            $plataforma="Macintosh";
        } else if (eregi("Linux", $ua)) {
            $plataforma="Linux";
        } else if (eregi("W3C", $ua)) {
            $plataforma="W3C Validator";
            $navegador="W3C Validator";
            $versao="-";
        } else if (eregi("Googlebot", $ua)) {
            $plataforma="Googlebot";
        } else if (eregi("msnbot", $ua)) {
            $plataforma="MSNBot";
        } else if (eregi("Cynthia", $ua)) {
            $plataforma="Cynthia";
            $navegador="Cynthia";
            $versao="0";
        }

        if (eregi("Mozilla/4", $ua)&&!eregi("compatible", $ua)) {
            $navegador="Netscape";
            eregi('Mozilla/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Mozilla/5", $ua)||eregi("Gecko", $ua)) {
            $navegador="Mozilla";
            eregi('rv(:| )([[:digit:].]+)', $ua, $b);
            $versao=$b[2];
        }
        if (eregi("Safari", $ua)) {
            $navegador="Safari";
            $plataforma="Macintosh";
            eregi('Safari/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("iCab", $ua)) {
            $navegador="iCab";
            eregi('iCab/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Firefox", $ua)) {
            $navegador="Firefox";
            eregi('Firefox/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Firebird", $ua)) {
            $navegador="Firebird";
            eregi('Firebird/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Phoenix", $ua)) {
            $navegador="Phoenix";
            eregi('Phoenix/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Camino", $ua)) {
            $navegador="Camino";
            eregi('Camino/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Chimera", $ua)) {
            $navegador="Chimera";
            eregi('Chimera/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Netscape", $ua)) {
            $navegador="Netscape";
            eregi('Netscape[0-9]?/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("MSIE", $ua)) {
            $navegador="Internet Explorer";
            eregi('MSIE ([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Opera", $ua)) {
            $navegador="Opera";
            eregi('Opera( |/)([[:digit:].]+)', $ua, $b);
            $versao=$b[2];
        }
        if (eregi("OmniWeb", $ua)) {
            $navegador="OmniWeb";
            eregi('OmniWeb/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }
        if (eregi("Konqueror", $ua)) {
            $navegador="Konqueror";
            $plataforma="Linux";
            eregi('Konqueror/([[:digit:].]+', $ua, $b);
            $versao=$b[1];
        }
        if (eregi('Crawl', $ua) || eregi('bot', $ua) || eregi('slurp', $ua) || eregi('spider', $ua)) {
            $navegador="Crawler/Search Engine";
            $versao="-";
        }
        if (eregi('Lynx', $ua)) {
            $navegador="Lynx";
            eregi('Lynx/([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
            $plataforma="Linux";
        }
        if (eregi('Links', $ua)) {
            $navegador="Links";
            eregi('(([[:digit:].]+)', $ua, $b);
            $versao=$b[1];
        }

        $array=Array($navegador, $versao, $plataforma);
        return $array;
    }

    /* Função para determinar o país do visitante
     * "SI_determineCountry()", do Shortstat, bem modificada por mim.
     */
    function DeterminarPais($ip) {
        global $BASE;
        $ip=sprintf("%u", ip2long($ip));

        $db=new $BASE['TYPE'];
        $db->Conecta();
        $db->Query("SELECT nome, codigo FROM ".$BASE['TABELA_PAISES']." WHERE ip_from < = $ip AND ip_to >= $ip");
        $array=$db->FetchRow();

        $db->Desconecta();

        /* Agora um monte de linhas por causa da incompetência do PHP 5.0.5... Hehehe... */
        $tmp1=preg_replace("/([A-ZxC0-xDF])/e", "chr(ord('\1')+32)", $array[0]);
        $tmp2=ucwords($tmp1);
        $array[0]=trim($tmp2);

        return $array;
    }

    /* Função para "increase stats"
     * O arquivo "inc.stats.php" do Shortstat, bem modificado por mim.
     */
    function IncStats() {
        global $BASE;
        $this->ip=$this->IpReal();
        list($this->pais, $this->codigopais)=$this->DeterminarPais($this->ip);
        $this->referer=$_SERVER["HTTP_REFERER"];
        $this->url=parse_url($this->referer);
        $this->dominio=eregi_replace("^www", "", $this->url["host"]);
        $this->resource=$_SERVER["REQUEST_URI"];
        $this->useragent=$_SERVER["HTTP_USER_AGENT"];
        list($this->navegador, $this->versaonavegador, $this->plataforma)=ParseUserAgent($this->useragent);
        $this->unixtime=time();

        $db=new $BASE['TYPE'];
        $db->Conecta();
        $db->Query("INSERT INTO ".$BASE['TABELA_ESTATISTICAS']." (ip, pais, codigopais, dominio,
        referer, resource, useragent, plataforma, navegador, versao, unixtime) VALUES ('{$this->ip}',
        '{$this->pais}', '{$this->codigopais}', '{$this->dominio}', '{$this->referer}', '{$this->resource}',
        '{$this->useragent}', '{$this->plataforma}', '{$this->navegador}', '{$this->versaonavegador}',
        '{$this->unixtime}')");
        $db->Desconecta();
    }
}
?>

Bom… Esses dois códigos estão em desenvolvimento ainda, mas acho que com o tempo vão melhorando. Tem umas coisas na parte de Regex que eu queria tornar mais simples mas ainda não descobri como! :blink: Quem quiser sugerir, sinta-se a vontade.

Início no Java

Nesse final de semana, comecei a estudar Programação Orientada a Objetos. Eu nunca tinha experimentado essa maneira de programar e venho gostando bastante. :)

No início, fiz alguma coisa em C++; Depois mudei todo o sistema do meu blog para usar classes (ou “bibliotecas”, como o hlegius prefere, não sei porquê…) e agora então, por sugestão do , comecei a aprender Java.

Acho que é uma excelente maneira de me aprofundar na orientação a objetos. Desde o início da minha apostila, estou me deparando com a POO; o Java é uma linguagem completamente orientada a objetos (tanto que é sempre o exemplo quando alguém fala dela).

Pelo pouco que programei até agora (comecei hoje), percebi quatro vantagens legais que o C não tinha:

  1. Declaração de variáveis em qualquer lugar do documento. O C++, o PHP e várias outras linguagens permitem isso também…
  2. Multi-plataforma. Linux, Windows, Mac, Solaris… O mesmo código roda em tudo! :) C também roda em tudo, mas não exatamente da mesma maneira como o Java
  3. Desenvolvimento para web via applets.
  4. Parece muito fácil criar interfaces gráficas. Não sei se é mesmo, mas parece.

Bom… Não entendi direito o negócio de plataforma Java, pra ser sincero… Mas ainda tô iniciando aí nesse mundo do Java e da POO. :)

E então, para finalizar fica um código de um exercício que eu fiz; o primeiro da primeira apostila (que inclusive eu já concluí a leitura):

Calcular a soma e a média de vários números, e ver o maior e o menor

import javax.swing.JOptionPane;

/* Eu não precisava de array para esse programa, só usei porque
 * estou aprendendo Java então preciso me acostumar com arrays... */

class Exercicio {
import javax.swing.JOptionPane;

/* Eu não precisava de array para esse programa, só usei porque
 * estou aprendendo Java então preciso me acostumar com arrays... */

class Exercicio {
        public static void main(String args[]) {
                int n;
                String string;

                JOptionPane.showMessageDialog(null, "Olá. Esse programa serve pra calcular a soma e a média entre vários números, além de definir o maior e o menor deles.");
                JOptionPane.showMessageDialog(null, "Restrições:nn1. Só funciona com números entre -1.000.000 e 1.000.000.n2. Só funciona (a entrada e a saída) com números inteiros.");
                string=JOptionPane.showInputDialog("Você quer calcular a média entre quantos termos?");
                n=Integer.parseInt(string);

                int array[] = new int[n];
                int i, m, soma=0, maior=-1000000, menor=1000000;

                for (i=0; i<n; i++) {
                        m=i+1;
                        string=JOptionPane.showInputDialog("Digite o "+m+"o. número:");
                        array[i]=Integer.parseInt(string);
                        soma+=array[i];
                        if (array[i]>maior) {
                                maior=array[i];
                        }
                        if (array[i]<menor) {
                                menor=array[i];
                        }
                }

                int media=soma/n;

                JOptionPane.showMessageDialog(null, "A soma de todos os números é "+soma+".");
                JOptionPane.showMessageDialog(null, "A média de todos os números é "+media+".");
                JOptionPane.showMessageDialog(null, "O maior dos números é "+maior+".");
                JOptionPane.showMessageDialog(null, "O menor dos números é "+menor+".");
        }
}

No mais, nada de novo. Só pra registrar a data de meu início no Java. :D

Programação Orientada a Objetos

Estou finalmente começando a aprender orientação a objetos. É claro que o conceito eu já conhecia e até como usar “cin” e “cout” no C++, mas agora resolvi estudar a fundo a Programação Orientada a Objetos, porque vejo que ela está cada vez mais comum entre os programadores. Estou aproveitando pra aprender C++, o que pode ser bastante útil em olimpíadas, para ter strings com o tipo string, poder declarar variáveis no meio, além de programar orientado a objetos.

Hmmm… Eu estava lendo uns tutoriais de introdução a POO e agora vou tentar fazer algumas coisas em C++ e em PHP também (porque é uma linguagem que eu domino mais, fica mais fácil entender POO). Se alguém quiser estudar comigo, entre em contato (e a mesma coisa se alguém tiver uma apostila legal e está afim de ajudar).

XUL

Durante as aulas, estou estudando XUL. É uma linguagem de interface gráfica, tipo um HTML, mas que tem umas coisas bem interessantes. O único problema é que só roda em Mozilla… E também estou aumentando bastante meu conhecimento de JavaScript utilizando XUL e iniciando uma fase nova de tableless com DOM. :)

Meetweb, tableless

Semana passada eu peguei dois serviços da Meetweb. São serviços de converter um site para tableless e programá-lo em PHP usando banco de dados MySql (ou seja, minha especialidade). Por isso também, estou entrando nessa nova fase de tableless que citei no parágrafo acima.

Desvendando os segredos do C

É incrível que quando eu estudei C no início eu passei por alguns conceitos que na época eu achava complicados. Além dos operadores binários que o Paulo Matias me ensinou semana passada, ontem é que eu finalmente aprendi as funções de alocação dinâmica do C… E é tão simples! :D

Olimpíada Regional de Matemática

Ontem fiz a prova da segunda fase (final) da Olimpíada Regional (catarinense) de Matemática. Dos cinco problemas, resolvi quatro e acho que acertei três e meio. Um deles eu pensei certo, mas dei a resposta errada… Mas já que a prova era discursiva, acredito que eles dêem no mínimo metade dos 20 pontos do problema. Não sei se dá pra ganhar medalha, porque a prova tava bem fácil então mais gente deve ter ido bem.

Problemas Lógicos

Estou meio parado quanto a solução de problemas lógicos, mas estou estudando bastante para resolvê-los de forma melhor. Por enquanto, nenhum código novo. Tenho uma lista de problemas da UVa para resolver e ainda falta o último problema do capítulo 1 do USACO Training Gateway (Checkers Challenge).

Mensageiros Instantâneos, OBM, Novos Programas, Música

Em primeiro lugar, venho por meio deste post comunicar que não uso mais MSN Messenger. O mensageiro instantâneo da Microsoft saiu da minha lista de contas do CenterICQ para a entrada de dois novos e melhores: IRC e GoogleTalk/Jabber. Cheguei a conclusão de que quem quer falar comigo deve usar o que eu uso e não ao contrário, por um motivo óbvio: o meu é melhor que o deles.

Esta decisão fez com que eu perdesse centenas de contatos, mas acho que foi a decisão certa a ser tomada. Quem quiser me contatar agora, pode me adicionar no ICQ como 147330555, GoogleTalk como tmadeira em gmail.com e no IRC/Freenode, como tiagomadeira.

O segundo ponto importante deste post é o anúncio da OBM, Segunda Fase. A prova acontecerá no sábado que vem, dia 03 de setembro. Acho difícil eu conseguir medalha nesse ano (Terceira Fase é difícil!), mas vou tentar me esforçar o máximo possível… Esta semana tivemos o treino para olimpíadas com o Vavá, aprendi algumas coisas úteis. E ontem conversei com o César Kawakami no ICQ que me deu umas dicas interessantes também sobre Teoria dos Números. Vou tentar aprender alguma coisa sobre isso nos próximos dias…

As aulas de matemática dessa semana foram pouco produtivas porque eu andei faltando algumas para a divulgação do fórum do colégio. Então, só deu pra fazer dois problemas: a implementação da Máxima Subcadeia Comum (LCS/Programação Dinâmica):

//LCS - Longest Common Subsequence
//Programação Dinâmica - MSC - Maior Subcadeia Comum

#include <stdio.h>
#define SMAX 1001
#define DIAGONAL 1
#define LADO 2
#define CIMA 3


//n = tamanho de x
//m = tamanho de y

int c[SMAX][SMAX], b[SMAX][SMAX], n, m;
char x[SMAX], y[SMAX];

int lcs_recupera(int i, int j) {
	if (i==0||j==0) {
		return 0;
	}
	if (b[i][j]==DIAGONAL) {
		lcs_recupera(i-1, j-1);
		printf("%c", x[i]);
	} else if (b[i][j]==CIMA) {
		lcs_recupera(i-1, j);
	} else {
		lcs_recupera(i, j-1);
	}
}

int main() {
	int i, j;


	printf("LCS - Longest Common Subsequence\nPor Tiago Madeira\n\n");
	printf("Digite o tamanho da string X: ");
	scanf("%d", &m);
	printf("Digite o tamanho da string Y: ");
	scanf("%d", &n);

	scanf("%*c");
	printf("Digite a string X: ");
	for (i=1; i<=m; i++) {
		scanf("%c", &x[i]);
		c[i][0]=0;
	}
	scanf("%*c");
	printf("Digite a string Y: ");
	for (i=1; i<=n; i++) {
		scanf("%c", &y[i]);
		c[0][i]=0;
	}

	printf("\nPrograma raciocinando...\n");
	for (i=1; i<=m; i++) {
		for (j=1; j<=n; j++) {
			if (x[i]==y[j]) {
				c[i][j]=c[i-1][j-1]+1;
				b[i][j]=DIAGONAL;
			} else {
				if (c[i][j-1]>c[i-1][j]) {
					c[i][j]=c[i][j-1];
					b[i][j]=LADO;
				} else {
					c[i][j]=c[i-1][j];
					b[i][j]=CIMA;
				}
			}
		}
	}

/*	printf("\nMATRIX C\n");
	for (i=1; i<=m; i++) {
		for (j=1; j<=n; j++) {
			printf("%d ", c[i][j]);
		}
		printf("\n");
	}

	printf("\nMATRIX B\n");
	for (i=1; i<=m; i++) {
		for (j=1; j<=n; j++) {
			printf("%d ", b[i][j]);
		}
		printf("\n");
	}
*/

	lcs_recupera(m, n);
	printf("\n");
}

e um programa bem ridículo para calcular os termos e a soma de uma PA (é o que o prof. tá ensinando, aí achei bom pra fazer os exercícios mais rápido…):

//Aplicar as fórmulas das PAs

//Progressão Aritmética
//Programa desenvolvido por Tiago Madeira (c) 2005.

#include <stdio.h>
#define MAX 1000001

long double a[MAX], s[MAX];

int main() {
	long double r;
	int n;

	printf("Primeiro termo da PA: ");
	scanf("%Lf", &a[1]);
	printf("Razão da PA: ");
	scanf("%Lf", &r);

	//Eu podia fazer só pros que vão ser usados, mas não sei porquê, deu vontade de fazer assim... =)
	printf("\nAguarde o problema raciocinar tudo que ele tem para raciocinar...\n");
	for (n=2; n<MAX; n++) {
		a[n]=a[1]+r*(n-1);
		s[n]=(a[1]+a[n])*n/2;
	}

	printf("\nE agora, digite números para o programa dizer A e S dele.\n");
	do {
		printf("Número: ");
		scanf("%d", &n);
		if (!n) {
			break;
		}
		printf("Número na posição N = %.Lf\nSoma de 1 a N = %.Lf\n\n", a[n], s[n]);
	} while (n);

}

No começo do mês que vem é o Festival de Música de Itajaí. Acho que vou fazer oficina de Piano Popular avançado com o Prof. Michel Freidenson, que foi quem me deu aulas numa oficina semelhante há dois anos. A semana da música vai contar também com uns shows bem legais e o site oficial é este aqui.

© 2005–2020 Tiago Madeira