By paddloPayday loans

Brincando com recursividade em c#

September 15th, 2011 No Comments   Posted in Desenvolvimento

Recursividade, o que é?

A idéia de recursividade é a de um procedimento que chama a si mesmo, seria como se uma ação pudesse desencadear a si mesma, O pãozinho vende muito porque está sempre quentinho ou está sempre quentiho porque vende muito? seria esta questão filosófica, recursiva? É difícil fazer uma analogia da recursividade com as coisas do mundo “real”, uma idéia interessante seria o ato de subir  escadas, em que é preciso repetir os mesmos procedimento diversas vezes até atingir o objetivo.

Recursividade no contexto de programação

Neste contexto, podemos dizer que a recursividade é um procedimento (método, função, procedure, etc) que chama a si mesmo até que um objetivo seja atingido, ou seja, é um loop, um loop com condição de parada (se não não seria algoritmo).

Algoritmo para contar letras em uma palavra

Digamos que tenhamos que desenvolver um método que receba dois parametros, uma palavra e uma letra, e que o algoritmo tenha que contar o número daquela letra naquela palavra. Vamos fazer este exercício e 2 formas:

De forma iterativa

Como sabemos que em c# toda string é um vetor, basta fazer um for para percorrer os elementos deste vetor e ir incrementando um contador todas as vezes que se encontrar a letra procurada (tomando o cuidado para converter tudo para maiúsculas no teste condicional).

1
2
3
4
5
6
7
8
9
10
11
<pre>

public static int ContaLetraIteracao(String _string, String _letra)
{
  int contador = 0;
  for (int i = 0; i < _string.Length; i++)
  {
      if (_string[i].ToString().ToUpper() == _letra.ToUpper()) contador++;
  }
  return contador;
}

De forma recursiva

Digamos que a linguagem não oferecesse nenhum comando que nos permitisse iteração (loop), então teriamos que construir o método sem a utilização do for, while ou qualquer outra estrutura de repetição, então uma possível solução para isto seria fazer com que o metodo chamasse a si mesmo tantas vezes até atingir o tamanho da palavra, e ir contando  as vezes que letra aparecece.

É preciso observar que neste caso, teremos que usar variáveis externas ao método, pois cada vez que ele é chamado (não importa que seja ele mesmo que esteja se chamando) as variáveis são criadas, isto estragaria nossos contadores:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<pre>
int numVezes, numLetras;
boolean inicio;
public Int32 ContaLetra(String _string, String _letra)
{
   if (inicio)
   {
       numVezes = 1;
       numLetras = 0;
       first = false;
   }

   if (numVezes <= _string.Length)
   {
       if (_string[numVezes-1].ToString().ToUpper() == _letra.ToUpper()) numLetras++;
       numVezes++;  // O que acontecria se esta linha fosse a última? e a primeira?
       ContaLetra(_string, _letra);
   }

   inicio = true;
   return numLetras;
}
Explicando as variáveis:

Parametros:
_string = Palavra a qual vamos procurar pela letra
_letra = A letra a ser procurada

Variáveis externas ao método
inicio => Variável booleana que funciona como uma “sentinela” indicando a primeira vez em que o método é chamdo de “fora” dele mesmo, foi definida fora do método, isto é, na classe que implementa o metodo, para que as chamadas subsequentes não a redefina. Antes do return do método, esta variável é colocada em true, para que a proxima chamada (de fora) reinicie o processo.

numLetras => É o contador de letras, é zerado na primeira chamada ao método (chamada externa) e depois vai acumulando o número de vezes que encontra a letra procurada.

numVezes => É o numero de vezes que o método é chamado, esta variável é incrementada de uma unidade até que seja igual ao tamanho da string enviada (_string.Length)

Utilidade da recursividade.

Isto parece inútil e sem sentido, realmente é bem difícil dar um exemplo realmente útil de recursividade, mesmo porque poderia não fazer sentido para quem ainda está iniciando no assunto, mas é fácil perceber o valor da técnica neste simples exemplo, no caso estamos pesquisando em um vetor (lembrando que uma string em c# é um vetor de caracteres). Mas digamos que a estrutura de dados não fosse um simples vetor, digamos que fosse uma estrutura que pudesse comportar dentro dela, qualquer coisa, até mesmo vetores, ou vetores de vetores. Neste caso o único jeito seria a recursividade.

Exercícios

Exercício 1:

Faça um programa (aqui será mostrado somente o metodo) para calcular a potencia de um número. O método recursivo deve receber como parâmetro a base e o expoente, e devolver o valor da potência.
EX: double CalculaPotencia (int base, int expoente) CalculaPotencia (2,3) = 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<pre>
bool inicio;
int resultPot;
public Int32 CalcPot(int _base, int _expoente)
{
    if (inicio)
    {
        resultPot = _base;
        inicio = false;
    }

     if (resultPot == 0) resultPot = _base;

     if (_expoente > 1)
    {
        resultPot = (resultPot  * _base);
        CalcPot(_base, --_expoente);
    }

    inicio = true;
    return resultPot;
}
Exercício 2:

Faça um programa para imprimir a tabuada, usando recursividade.

Implementação

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<pre>
bool inicio;
int dec, numTabuada;

// Vetor com o resultado da tabuada, ja convertida em string
string[] vetor_t new string[10];
  public String[] Tabuada(int _num)
  {
      if (inicio)
      {
          numTabuada = _num;
          dec = 10;
          inicio = false;
      }

      if (dec > 0)
      {
          vetor_t[dec - 1] = Convert.ToString((dec * numTabuada));
          Tabuada(--dec);
      }
      inicio = true;
      return vetor_t;
   }

 

Exercício 3:

Faça um método para limpar todos os maskedit e os Textbox de um form, mesmo que eles estejam dentro de panels, groupbox, etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<pre>
public void LimpaForm(Control _Parent)
{
   // Percorre todo o container
   foreach (Control c in _Parent.Controls)
   {
      // Se o objeto for outro Control, chama o proprio metodo
      if (c.Controls.Count > 0) LimpaForm(c);

      // Limpa se for um textbox
      if (c is TextBox) (c as TextBox).Clear();
      // Limpa se for um MaskedTextBox
      if (c is MaskedTextBox) (c as MaskedTextBox).Clear();
    }
}

Este é um exercicio realmente útil e que seria muuuito dificil (impossivel, talvez) resolve-lo sem a recursividade, explicando:

O método recebe o parametro _parent, do tipo Control, Control é uma coleção de controles ou um Container onde se pode armazenar outros controls, por exemplo, um Form é um control, um panel é um control.

O método faz um foreach percorrendo todos os objetos dentro de _parent, quando encontra um objeto do tipo Control (Um panel, por exemplo) o metodo chama a si mesmo enviando como parametro o objeto encontrado.

Se o objeto não for um control, o metodo verifica se é um TextBox, se sim, chama o metodo Clear() para limpa-lo, fazendo o mesmo como o MaskedTextBox.

 

Resolução no visual studio 2008.

recursividadeO programa apresenta um Form com todas as soluções apresentadas neste texto, na parte de cima é solicitado uma base e a potencia, clicando no botão calcular, a potencia é calculada e o resultado é apresentado.

Em seguida é apresentado um panel onde é solicitado uma string e uma letra que deverá ser procurada nesta string, há 2 radio buttons para se escolher se a busca será feita de forma recursiva ou iterativa.

Logo em seguida é solicitado um numero e ao se clicar no botão, a tabuado do numero á apresentada no panel abaixo.

E, por último, um groupbox com panels internos para testar a limpeza do form, que devera ocorrer a se pressionar o botão “Limpa Form”

Baixe, clicando aqui!


O Desenvolvimento de software nunca será engenharia?

August 10th, 2011 1 Comment   Posted in Desenvolvimento

 

Ponte1Interessante texto (Em ingles) em que o autor tece suas considerações sobre a tentativa de se "adaptar o desenvolvimento de software às rígidas práticas da engenharia".

Algumas observações bem pertinentes, por exemplo ele diz que os defensores desta idéia dizem que o desenvolvimento de sw ainda é um campo bem novo em relação à engenharia e por isto ainda não temos as práticas ideais e "blah"… Então ela cita que o desenvolvimento hoje é muito diferente do de a 10 anos atrás, observa também que já construimos muito mais softwares do que pontes.

Para mostrar a diferença da evolução da área de desenvolvolvimento de software demonstra a evolução do jogo de poquer depois do advento dos jogos online, onde garotos de 19 anos derrotam profissionais veteranos.

O cara é tão convicto que chega a afirmar que "esperar que o desenvolvimento de sw um dia se torne uma disciplina da engenharia é o mesmo que ficar esperando que a água se transforme em gelatina sem adicionarmos o pó para tal" :-)

Segundo ele a 10 anos atrás começamos a utilizar UML e ferramentas CASE, 10 anos atrás achavamos que nos 10 anos seguintes teriamos programas que nos permitiria construir softwares da mesma forma que ferramentas CAD permitem construir máquinas (ou parte delas), ainda segundo ele, isto não só não aconteceu, como acabamos tomando um caminho totalmente diferente, hoje falamos em desenvolvimento ágil. Hoje, desenvolvemos software sem tentar definir todo o sistema em diagramas UML.

Para ele, a questão é bem clara, “software é algo vivo, pontes não.”, quando desenvolvemos softwares,  a liberação V1 será muito diferente da versão final, em alguns casos a liberação V2  sera bem diferente da V1.

No final ele conclui que “Desenvolvedores tem muito mais em comum com cirugiões do que com Engenheiros”

Mais interessante ainda são as reações nos comentários, vale a pena ler.

http://elegantcode.com/2011/06/22/why-software-development-will-never-be-engineering/

Desenvolvedores: Médicos ou Jardineiros?

melanciasEm Outro interessante texto sobre o mesmo tema,  o autor afirma que desenvolvedores se parecem mais com jardineiros do que com Engenheiros, novamente fazendo alusão ao fato de que cuidamos de algo “vivo” ou muito mais dinamico do que os engenheiros cuidam.

Texto original:
http://chrisaitchison.com/2011/05/03/you-are-not-a-software-engineer

Voce pode ver a tradução/Interpretação em portugues por Eduardo Rolim aqui.

O direito de ser idiota

June 23rd, 2011 No Comments   Posted in Filosofia

Mais um feriadão, tempo para “ficar navegando a esmo”, eis que encontro a reprodução de uma parte de um dos programas do Jô, o video apresenta o posicionamento de um professor de Filosofia sobre a “interferencia do estado” em nossas vidas, acho que o professor poderia até ser mais feliz se escolhesse corretamente onde o estado erra quando tenta ser “o dono da verdade” (e olha que tem muitos assuntos em que ele –o estado- está totalmente equivocado) mas, infelizmente este “filosofo” acaba fazendo o papel de idiota.

O vídeo foi postado por um filsofo, este, na minha opinião, um verdadeiro filosofo, trata-se do professor Paulo Ghiraldelli Jr, que tem um canal de filosofia no youtube além da participação em alguns sites na internet, como por exemplo: http://www.livestream.com/filosofia e http://portal.filosofia.pro.br/, mas vamos ao vídeo:

 


De volta ao pi – agora com Leibniz

March 19th, 2011 No Comments   Posted in Educação

pi-31casas

Versão inicial baseado na fórmula de Leonhard Euler

Tudo começou com o post: calculando o pi em c ansi, um exercicio para cálculo do pi baseado na fórmula de Leonhard Euler, nossa primeira versão utilizava esta fórmula de forma bem simples, tudo explicado no mesmo link acima. Fizemos um teste com 10.000.000 de números primos, estamos aguardando o resultado…. :-)

Segunda versão com a fórmula de Euler

Depois de alguma pesquisa resolvemos implementar uma nova versão baseada na mesma fórmula, desta vez o que muda é a forma de “gerar” o número de números primos desejado pelo usuário, agora usamos um algoritmo um pouco mais sofisticado que, com certeza, nos trará mais velocidade, o algoritmo para gerar os primos é explicado aqui. Também trabalhamos com variaveis double para tentar maior precisão

Em um teste com 10.000.000 de números primos obtivemos o resultado apresentado na figura abaixo:

pi_euler_v2-10M

Abaixo o codigo da segunda versão:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

// Variaveis globais
char tics[12] = "Segundo(s)";
time_t start;

// Prototipos:
int eh_primo(unsigned int n);
float time_waste(time_t start, time_t end);
float time_waste(time_t start, time_t end);
double retorna_pi(double nprimos);

int main() {
    double n;
    time_t end;
    system("cls");
    printf("Entre com numero de primos : ");
    scanf("%lf",&n);
    printf("%1.60lf\n", retorna_pi(n));
    end = time(NULL);
    printf("\ntempo gasto: %f, %s\n ",time_waste(start,end),tics);
    fflush(stdin);
    getch() ;    
   
}

// Calcula e retorna o PI
double retorna_pi(double nprimos) {
    double soma1 = 1;
    unsigned int primos = 0, count = 2;
    start = time(NULL);
   
    while (primos < nprimos) {
         
        if (eh_primo(count) == 1)
        {
            soma1 *= (pow(count, 2) / (pow(count, 2) - 1));;
            primos++;
        }
        count++;
    }
    return sqrt(soma1 * 6);
}


int eh_primo(unsigned int n) {
    unsigned int i;
    static unsigned int primes55[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
        73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179,
        181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257};

    // Checa divisibilidade do numero pelos primos acima
    for (i = 0; i < 55; i++) {
        if (n % primes55[i] == 0) {
            if (n == primes55[i]) return 1;
            else return 0;
        }
    }

    // extrai raiz do numero n
    unsigned int raiz_n = sqrt(n);

    // Se o numero par é descartado antecipadamente
    if (n % 2 == 0) return 0;

    // Verifica se tem algum divisor entre 3 e a raiz do proprio numero
    for (unsigned int i = 3; i < raiz_n; i += 2) {
        if (n % i == 0) return 0;
    }
    return 1;
}


// Calculo do tempo gasto (gastando mais tempo :/ )
float time_waste(time_t start, time_t end) {
    float tempo_gasto;
    tempo_gasto = (difftime(start, end)*-1);

    // POG
    tempo_gasto = (tempo_gasto < 1) ? (0.1) : tempo_gasto;

    if (tempo_gasto > 59) {
        tempo_gasto = (tempo_gasto / 60);
        strcpy(tics, "Minuto(s)");
    }

    if (tempo_gasto > 59) {
        tempo_gasto = (tempo_gasto / 60);
        strcpy(tics, "Hora(s)");
    }
    return tempo_gasto;
}

 

Fórmula de Leibniz

pi-leibniz1 Não é a primeira vez que procurando algo relacionado à matemática ou a computação, nos deparamos com algo do genial Leibniz, é interessante como este verdadeiro genio da humanidade é tão pouco lembrado. A figura ao lado foi extraida em um texto da wikipedia e, por si só, ja explica a fórmula, para desenvolver o algoritmo passamos o 4 para o lado esquerdo da equação, criamos uma variável que funciona como uma “flag” para somar ou subtrair, é muito mais fácil apresentar diretamente o código que tentar explicar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


// Calculo do PI baseado nas séries de Leibniz
// 4/1 - 4/3 + 4/5 - 4/7 + 4/9 ...

// Prototipos
void tempo_gasto(time_t start, time_t final);
double pi(double divisores);

// Variaveis globais :/
float time_waste;char tics[10] = "Segundo(s)";

void main() {
    double divisores;
    system("cls");
    printf("Entre com o numero de iteracoes: ");
    scanf("%lf",&divisores);
    printf("%1.20lf\n", pi(divisores));
    printf("Tempo gasto: %.2f %s \n\n", time_waste, tics);
    fflush(stdin);
    getchar();
}

// Calculo do pi
double pi(double divisores) {
    double pi = 0.0, divisor = 1.0;
    int somar = 1;
    time_t start = time(NULL), end;
    do {
        if (somar == 1) {
            pi = pi + (4.0 / divisor);
            somar = 0;
        } else {
            pi =  pi - (4.0 / divisor);
            somar = 1;
        }
        divisor = (divisor + 2.0);
    } while (divisor < divisores);

    end = time(NULL);
    tempo_gasto(start, end);
   
    return pi;
}      

// Funcao para mostar o tempo gasto no calculo
void tempo_gasto(time_t start, time_t final) {

    time_waste = (difftime(start, final)*-1);

    // POG
    time_waste = (time_waste < 1) ? (0.1) : time_waste;

    if (time_waste > 59) {
        time_waste = (time_waste / 60);
        strcpy(tics, "Minuto(s)");
    }

    if (time_waste > 59) {
        time_waste = (time_waste / 60);
        strcpy(tics, "Hora(s)");
    }
}

 

Também fizemos o teste com 10.000.000, o resultado:

pi-leibniz-10M

Como o tempo foi muuito rápido, resolvemos fazer com 1.000.000.000, o resultado foi:

pi-leibniz-1BI

Como o tempo continua sendo extremamente satisfatório, resolvemos extrapolar e testar com 1.000.000.000.000 (Um trilhão) de iterações,  é impressionante como este algoritmo é rápido, neste caso a aproximação ficou um pouco melhor, talvez se fizermos mais testes com um número maior de iteracoes, consigamos precisao um pouco melhor.

pi-leibniz-1T
 

Very very very crazy!

Pesquisando sobre o pi na rede, encontramos um codigo neste site que retorna o seguinte resultado:


 
O mais “doido” é o código, veja:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>

int a=10000,b,c=2800,d,e,f[2801],g;

main(){
  for( ;b-c; ) f[b++]=a/5;
  for( ; d=0,g=c*2; c-=14, printf("%.4d",e+d/a),e=d%a)
     for(b=c;d+=f[b]*a, f[b]=d%--g,d/=g--,--b;d*=b);
  printf("\n");  
  system("pause");
 
  }

 
Insano! :-)


De volta aos números primos

March 13th, 2011 1 Comment   Posted in Desenvolvimento

Continuação do post anterior

O tema do post anterior gerou algumas discussões em sala de aula, embora o tema seja o calculo do PI, parece que o que mais “pegou” foi o envolvimento com os números primos, depois de alguma pesquisa, fiquei particulamente interessado, por isto resolvi abstrair o pi (embora já tenha desenvolvido uma versão que utiliza o algoritmo de Leibniz, que dispensa a utilizacao do números primos –fica para um post no futuro- ) e me concentrar em um algoritmo de “primalidade”, existem “teracentos” na rede, a grande maioria exatamente como o da minha primeira versão, ou seja, pegando o número que se deseja saber se é primo e ir checando se há divisores. O problema deste algoritmo é a lentidão.

Como determinar se um número é primo

O primeiro raciocíneo que vem à cabeça dos simples mortais (como eu!) é ver se o número é um número par diferente de 2, se sim ele já é descartado, se for 2 é primo, depois é só ir dividindo pelos números subsequentes a ele até chegar a ele menos 1, se alguma das divisões resultar resto 0 (zero) então o número não é primo, o problema desta lógica quando convertemos em um algoritmo para ser executado em um computador, é custo computacional, tomanos o numero 1.000.000, teriamos que testar a divisão 500.00 vezes (excluindo os pares).

Otimizando o algoritmo

Todo número composto (não primo) é um produto de números primos, por exemplo: 120 é um número composto da seguinte maneira: 2^3x3x5, ou 2x2x2x3x5, ou seja, todo número composto tem um primo como divisor, por outro lado, nenhum número primo tem outro primo como divisor, a não ser ele mesmo, então bastaria saber se o número tem algum primo como divisor para saber que ele não é primo.

Otimizando ainda mais

Como a raiz quadrada é uma espécie de divisor da imagem de um número, qualquer número terá a mesma quantidade de divisores antes de sua raiz, exatamente igual aos divisores após a sua raiz, vamos considerar o numero 144, cuja raiz é 12:

Divisores antes da raiz: 2, 3, 4 , 6, 8 e 9

É facil perceber que o próximo divisor depois da própria raiz será o resultado da divisão do número considerado, pelo último divisor antes da raiz, neste caso 144/9 = 16, o próximo divisor é exatamente o resultado da divisão do número (144) pelo antepenúltimo divisor anterior à raiz, ou seja: 144/8 = 18 e assim sucessivamente até atingir ao primeiro divisor, no caso o 2 que ”olhando no espelho” se torna 72, resultado da contra 144/2. Tudo isto para mostrar que se um número não tiver divisores primos até a sua raiz, seguramente não terá após a mesma, então para sabermos se um número é primo ou não, basta procurarmos por divisores até a sua raiz, em vez de ficar procurando por toda a sua “extensão”. No caso de testarmos o número 1.000.000, poderiamos testar a divisibilidade pelos impares até a raiz que é 1.000, neste caso testarimos aproximadamente 500 vezes, e não 500.000.

Explicando o novo código

Depois de várias horas de pesquisa sobre a explanação acima um novo codigo foi desenvolvido, desta vez somente para “gerar” números primos, tantos quantos forem o número informado pelo usuário no primeiro input do programa, o algoritmo funciona da seguinte forma: há uma tabela com os primeiros 55 números primos pré-computados, o primeiro loop dentro de main, pega o número (que se quer determinar se é primo) e chama a função eh_primo() que vai dividindo pelos primos desta tabela, se houver divisão exata, que não seja por um dos números da tabela, então a função retorna falso. A função eh_primo permite testar até o numero 4177, com este numero de testes, podemos gerar 474 numeros primos, sendo o ultimo o próprio numero 4177.

Depois do primeiro loop “For” da função eh_primo()

Se o codigo passar a função eh_primo(), é calculada a raiz quadrada do número e então, em um loop, dividimos o número pelos impares entre 3 a propria raiz, se não houver nenhum divisor, á função retorna true, indicando a primalidade.

Codigo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<pre>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

long int entradas = 0, val_max, val_n = 1, val_max_259 = 0;
float time_waste(time_t start, time_t end);

// Variaveis globais
char tics[12] = "Segundo(s)";

// Prototipos:
int eh_primo(unsigned int n);
float time_waste(time_t start, time_t end);

int main() {
    unsigned int count = 1, primo = 1, n;
    time_t start, end;
    start = time(NULL);
    printf("\n");

    system("cls");
    printf("Entre com o numero de primos : ");
    scanf("%i",&n);

    while (primo <= n) {
        count++;
        if (eh_primo(count) == 1) {
            printf("%d\t", count);
            if (primo++ % 10 == 0) printf("\n");
        }
    }

    end = time(NULL);
    printf("\ntempo gasto: %f, %s\n", time_waste(start, end), tics);
    fflush(stdin);
    getch();
}

int eh_primo(unsigned int n) {
    unsigned int i;
    static unsigned int primes55[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
        73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179,
        181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257};

    // Checa divisibilidade do numero pelos primos acima
    for (i = 0; i < 55; i++) {
        if (n % primes55[i] == 0) {
            if (n == primes55[i]) return 1;
            else return 0;
        }
    }

    // extrai raiz do numero n
    unsigned int raiz_n = sqrt(n);

    // Se o numero é para é é descartado antecipadamente
    if (n % 2 == 0) return 0;

    // Verifica se tem algum divisor entre 3 e a raiz do proprio numero
    for (unsigned int i = 3; i < raiz_n; i += 2) {
        if (n % i == 0) return 0;
    }
    return 1;
}


// Calculo do tempo gasto (gastando mais tempo :/ )
float time_waste(time_t start, time_t end) {
    float tempo_gasto;
    tempo_gasto = (difftime(start, end)*-1);

    // POG
    tempo_gasto = (tempo_gasto < 1) ? (0.1) : tempo_gasto;

    if (tempo_gasto > 59) {
        tempo_gasto = (tempo_gasto / 60);
        strcpy(tics, "Minuto(s)");
    }

    if (tempo_gasto > 59) {
        tempo_gasto = (tempo_gasto / 60);
        strcpy(tics, "Hora(s)");
    }
    return tempo_gasto;
}

Calculando o PI em C ANSI

March 5th, 2011 No Comments   Posted in Desenvolvimento

Formula_PI1 Mais um exercício de faculdade, a tarefa dada foi: desenvolver um program em C que retorne uma aproximação do PI, com base na fórmula de Leonhard Euler (veja figura e/ou o site da Universidade de Lisboa), O usuário deverá entrar com um número que determinará a precisão da aproximação, que para a fórmula servirá para gerar a quantidade de números primos (os números das bases das potencias dos numeradores da figura) depois da idéia esboçada em sala de aula, mas sem os recursos para o desenvolvimento, viemos para casa curiosos com o problema, resolvemos transformar a idéia em código e não é que funcionou?  na verdade não sabemos se está correto, mas parece “casar” com várias aproximações encontradas na rede.

O Algoritmo:

A função principal (retorna_pi) faz um loop em função do numero que o usuário informa, “cria” os números primos, tantos quantos forem o número informado, para isto a função apenas vai incrementando um contador e através da função checa_primo, verifica se este contador é primo ou não, se sim faz o calculo do lado direito da equação de Leonhard Euler e vai acumulando, até que o número de primos alcance o numero informado pelo usuario, ao final multiplica a soma por 6 e extrai a raiz quadrada:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;math.h&gt;

// Prototipos
int checaprimo(int num);
double calculo1(unsigned int n);
double retorna_pi(unsigned int nTimes);

void main(int argc, char *argv[])
{
    unsigned int n;
    system("cls");
    printf("Entre com a precisao : ");
    scanf("%i",&amp;n);
    printf("%.20f\n",retorna_pi(n));
    printf("%s\n\n"," ");
    system("PAUSE");   
}

// Calcula e retorna o PI
double retorna_pi(unsigned int nTimes)
{
     double soma1=1, pi;
     unsigned int primos=0, count=2;
     do
     {
        if (checaprimo(count)==1)
        {
          soma1 = (soma1*calculo1(count));
          primos++;
        }
       count++;  
     } while (primos&lt;=nTimes);
    return sqrt(soma1*6);
}

// Calcula o lado direito da equacao de Leonhard Euler        
double calculo1(unsigned int n) {
   int n2=n*n, n2m1=n2-1;
   return (double) n2 / n2m1;
}      
 
// Verifica se o numero é primo
int checaprimo(int num)
{
    for (int i=2; i&lt;num; i++) if (num%i==0) return 0;
    return 1;
}

Baixe o fonte e o executável aqui.


Conversão de base (d2b/b2d) em C ANSI

February 23rd, 2011 No Comments   Posted in Desenvolvimento

Considerações iniciais

É um simples exercicio dado por um professor de um curso de Desenvolvimento de sistemas de uma faculdade de tecnologia, o exercício foi feito a 4 mãos (em dupla) como sei que se eu olhar o codigo daqui alguns anos (quero dizer… meses) não lembrarei nem de 10%, resolvi documentar neste espaço todos os exercícios dados.

Ferramenta de desenvolvimento

Dev C++ ou Netbeans? quando nos foi dada a tarefa, foi indicado o Dev C++, achamos o bicho simpático mas meio pobre, interessante saber que ele foi feito em Delphi, sentimos-nos mais confortável no NB, mas… Encontramos vários problemas, estranhamente o executável gerado pelo NB se comporta de forma diferente do gerado pelo Dev, embora tenhamos configurado o NB para usar todo o ambiente do Dev, sei lá, provavelmente seja barberagem nossa, então optamos por usar o NB para o tempo de projeto e o Dev para a liberação do executável. Chega de blá blá blá e vamos ao código, como faria Jack, por partes.

Cabeçalho

Aqui temos os includes e, como optamos por colocar as funções abaixo da função principal (Main), então é necessário que se declare os protótipos das funções utilizadas no programa, achamos que fica mais documentado e evitamos a chatisse de ter que ficar empurrando a main para baixo. Comentários no próprio codigo;

#include &lt;stdio.h&gt;  // stdin
#include &lt;stdlib.h&gt;  // Exit
#include &lt;stdbool.h&gt;  // Bool

// Prototipo das funcoes que serao criadas mais abaixo
unsigned int b2d(char * bin);                // Binario para decimal
char d2b(long unsigned int Decimal);         // Decimal para binario
bool ChecaBin(char * bins);                  // Checa se o binário é válido
void Menu( int *opc );                       // Perfume barato. :-)

Função Principal

Variáveis criadas:

  • NumDecimal: Inteira, usada para armazenar a digitação do número decimal pelo usuário
  • NumBin: Matriz de caracteres para armazenar o binário digitado pelo usuário
  • opcao : Opcao do usuario que será alterada pela função Menu
  • isBin: Variável boolean auxiliar par sustentação do loop em Main

Esta função cria uma variável do tipo int chamada opcao e de dentro de um loop (do while)  chama a função Menu enviando para ela o endereço da (ponteiro) variavel opcao (passagem por referencia), a funcao Menu deverá alterar a variavel opcao de acordo com a escolha do usuario, o loop continuará enquanto a função menu não alterar o valor de opcao para 3. Se a escolha do usuário for 1 então Main solicitara a digitação do número decimal e chamará a função d2b (Decimal para Binario) enviando o valor da variável Numdecimal

main() {

    // <a href="http://tinyurl.com/vantagem-unsigned-int">http://tinyurl.com/vantagem-unsigned-int</a> */
    unsigned int NumDecimal;
   
    // Matriz de caracters para guardar o binário a ser convertido
    char NumBin[20];
   
    int opcao=0;
    bool isBin = 1;    

    do {
        Menu(&amp;opcao);
        switch (opcao) {
            case 1: printf("\nDigite o numero decimal: ");
                scanf("%d", &amp;NumDecimal);
                d2b(NumDecimal);
                break;

            case 2: printf("\nDigite o numero binario: ");
                 fflush(stdin);
                 scanf("%s", &amp;NumBin);
                // Chama a função que converte binário em decimal
                NumDecimal = b2d(NumBin);
                if (NumDecimal!=2) printf("Numero em decimal %ld",NumDecimal);
                  else printf("Numero binario invalido");
                //printf("Numero em decimal %ld",b2d(NumBin));
                break;
            default: printf("\nTermino!");
               fflush(stdin);
               getchar();
               exit(0);     
                      }
        fflush(stdin);
        getchar ();

    } while (opcao!=3);
}

Menu

Função para simular um menu, são apresentadas as 3 opções ao usuário, a função chama a si mesma (recursividade) enquanto o usuário não digitar uma opção válida (último if).

void Menu( int *opc ){
    system("cls");
    printf("\n\t\tM E N U");
    printf("\n\t1. Decimal para binario");
    printf("\n\t2. Binario para decimal");
    printf("\n\t3. Fim\n");
    fflush(stdin);
    scanf("%d",opc);

    if ((*opc &lt; 1) || (*opc &gt; 3)) {
        printf("Opcao invalida");
        fflush(stdin);
        getchar();
        Menu(opc);
    }
}

b2b

Converte de binario para decimal, a função é bem simples, recebe uma matriz de caracteres (passagem por referencia) e chama a função ChecaBin enviando esta matriz, então a função chamada checa se a sequencia dentro da matriz compõe um binário válido, se ChecaBin retornar false (0), b2d retornará o inteiro 2 para a função chamadora se retornar true (1) a função retorna esta matriz convertida em decimal, para isto utilizamos a função strtol da biblioteca padrão stdlib.h, referencia: http://pt.wikipedia.org/wiki/Strtol

unsigned int b2d(char * bin) {
  char *pEnd;

  if (ChecaBin(bin)) return strtol(bin, &amp;pEnd, 2);
  return 2;

}

d2b

Variáveis:

  • bins : Matriz de caracteres onde serão armazenados o digitos do numero binario (decimal convertido)
  • n : Variável auxiliar

Converte de decimal para binário, esta função recebe um número inteiro e, em um loop,  vai dividindo o numero por 2, armazenando os restos nos elementos da matriz (com a ajuda da variavel n), então converte o próprio numero recebido na divisão dele por 2 e retorna ao inicio do loop, até que o proprio numero se torne 1, finalmente (for final) apresenta a matriz na ordem inversa (Numero em binário)

char d2b(long unsigned int decimal) {
    unsigned bins[50];
    int n = 0;

    do {
        bins[n++] = decimal % 2;
        decimal = decimal / 2;
    } while (decimal != 1);

    bins[n] = decimal;

    printf("\nNumero em binario ");

    for (int i = n; i &gt;= 0; i--) {
        printf("%i", bins[i]);
    }
}

ChecaBin

Recebe uma matriz de caracteres que deveria conter somente 1s e 0s para compor um número binário, em um for a função percorre todos os elementos desta matriz e se qualquer elemento for diferente de 1 E diferente de 0, imediatamente retorna 0 (False)

bool ChecaBin(char * bins) {
    for (int i = 0; i &lt;= 0; i++) {
        if ( (bins[i]!='0') &amp;&amp; (bins[i]!='1') ) return 0;
    }
    return 1;
}

Baixe o fonte

Pacote com o executável e codigo fonte hospedado aqui.


Learning English…. on the Internet! (Parte 2)

February 13th, 2011 No Comments   Posted in English Language

Continuação do texto: http://www.cosmoverbal.net/english-language/learning-english-on-the-internet-parte-1

O Valor do Youtube

Muita gente pensa que o yt é um “site de tranqueiras”, a coisa que mais me surpreende é entrar em uma instituição de ensino e descobrir que o site do yt é bloqueado, isto é um erro, tenho certeza que o yt tem muito mais coisas boas do que ruins, inclusive cursos de Ingles, claro, a maioria em Ingles, mas tem também de outras linguas, principalmente o Espanhol.

Vídeos mais assistidos no YT

A maioria das pessoas assistem a vídeos no yt indicados por outras pessoas, ou que foram veiculados na mídia tradicional, isto é, vídeos que estão “em alta” e, logicamente, como seria de se esperar, vídeos que estão “bombando”, na maioria das vezes não são os mais interessantes ou os mais educativos, mas existem sim, centenas, talvez milhares, de vídeos altamente educativos no Yt, mas onde eles estão? Estão nos canais.

Canais no Yt

Todo usuário que cria uma conta no Yt, ganha automaticamente seu próprio canal, o canal é o espaço onde voce pode postar seus vídeos, marcar os vídeos que voce assiste como favoritos, assinar canais de outros usuários e permitir que os outros assinem o seu canal, voce pode ler mais sobre isto neste link: http://informatica.hsw.uol.com.br/youtube4.htm, abaixo passo a apresentar alguns dos canais que venho ‘colecionando’ nos ultimos 2 ou 3 anos, para o aprendizado da língua inglesa, é importante dizer que é apenas uma parte dos que eu assino e que toda semana surgem novos canais, para acompanhar  voce pode visitar o link: http://www.youtube.com/channels

Mr Duncan in China

Mr. Duncan não tem site, somente o canal, estou apresentando em primeiro lugar, até para fazer justiça, foi o primeiro canal que eu assinei no yt, para alguns, Mr. Duncan pode parecer dificil a primeira vista, mas o método dele é muito bom para treinar a audição,  confesso que no início (assisti ao seu primeiro post) eu achava que seus vídeos seriam chatos, pois em seu primeiro post ele parecia se apresentar de forma um tanto formal, mas depois ele mostrou ao que veio. O cara é Inglês e, obviamente, ele fala um Inglês puramente britanico, fala rápido mas de forma clara e apresenta as legendas em todos os seus vídeos, o link do canal é: http://www.youtube.com/user/duncaninchina

Abaixo apresento a primeira aula dele:

Learn American English Online

Este cara é gente fina :-), um método bem produtivo (pelo menos no meu caso), voce pode seguir aulas metodicamente (não gosto disto) pelo site ou ir direto no canal de vez em quando e assistir a um dos vídeos (269 quando eu escrevia este texto), no site ele apresenta a teoria e logo em seguida um dos vídeos do canal sobre a teoria apresentada, veja o exemplo abaixo, onde apresento um dos vídeos mais elementares e em seguida o link para a lição que utiliza este vídeo:

Link para a lição: http://www.learnamericanenglishonline.com/Blue%20Level/B1%20Be.html

Steve Ford

Este cara esteve ou morou no Brasil (não sei ao certo), parece que ele levou uma loira de Belo Horizonte com ele (Nada bobo), fala de forma clarissima o Ingles, fiquei um tempo sem frequentar o canal dele, agora parece que ele fez algumas modificações, colocou legendas em Portugues, para quem gosta é “um prato cheio”, para mim, sinceramente, mais atrapalha do que ajuda, de qualquer forma está ai: http://www.youtube.com/user/Inglesonline

Corrigindo o paragrafo acima, parece que o cara tem mais de um canal, enaquanto escrevia fui verificar e encontrei este http://www.youtube.com/user/PrivateEnglishPortal, onde os videos são legendados em Ingles, veja um exemplo (Video 2 da serie acima):

Ta-ta for now!

Tem mais, tem muito mais, para esta semana é o suficiente, parece que a parte do Youtube vai ficar mais extensa do que eu imaginava, para encerar vou apresentar mais um Britanico, com seu remédio diario (Daily Dose of English), muito boa a idéia, também tem um site com um extenso e ótimo contéudo gratuito, com lições, games, palavras cruzadas, etc, etc. (é preciso tempo), os vídeos são ótimos, abaixo apresento 2 deles, o primeiro é uma fábula de Esopo (repare nos textos apresentados para a explicações das expressões mais dificeis, se necessário é só pausar para acompanhar melhor), e o segundo é para “Stop it”.

Ah! E antes que eu me esqueça, vamos aos links:

Portal: http://www.youtube.com/user/Linguaspectrum
Site: http://linguaspectrum.com/

Finish:

Para terminar mais um vídeo do canal:

That’s it, See you soon! :-)


Learning English…. on the Internet! (Parte 1)

February 6th, 2011 2 Comments   Posted in English Language

Motivação

Conversando com algumas pessoas sobre a necessidade e a dificuldade de se aprender Inglês, percebi que grande parte simplesmente desconhece as possibilidades existentes na internet para este objetivo, alias, a rede oferece um universo inteiro de conhecimentos, a maior parte inteirmente ‘Free’ e… In English! Venho coletando links (Delicious, meu grande amigo!) ha alguns anos, por isto seria inviável tentar resumir tudo em um mesmo post, assim, vou escrever este texto em partes, esta é a primeira parte.

Porque aprender Inglês

Blá blá blá, qualquer coisa que eu escrever aqui vai soar como blá blá blá, todo mundo já sabe que o ingles é essencial em nossos dias, não adianta resistir, “Everything is dominated”.

Minha experiencia

Em minha área de atuação sempre precisei de ler algumas coisas em Inglês, e sempre consegui me virar de uma forma ou de outra, até pouco tempo atrás até me sentia confortável , mas de uns 2 ou 3 anos pra cá as coisas mudaram drasticamente, aquele “algumas coisas” que eu precisa ler “vez ou outra”, tornaram-se “a maioria das coisas, quase sempre”, ao utilizar qualquer ferramenta de computação, basta teclar F1 para aparecer um enorme texto em Inglês, e como se não bastasse, muita vez os textos nos levam a um vídeo com alguem explicando algo na língua de Shakespeare, e é ai que o “bicho pega”.

Aprendendo Ingles ‘In English’

Em primeiro lugar é preciso deixar claro minha opinião, baseado na minha experiencia: Não se aprende Inglês ouvindo em Português, a boa noticia é que, ‘nowadays’, não é preciso pagar uma fortuna para se ter um curso em inglês, com falantes em inglês, com legendas em inglês e até com legendas e explicações (escritas) em Português, na verdade pode se ter isto absolutamente ‘Free’, isto é, totalmente gratis.

Para quem acha que não sabe absolutamente nada

Algumas pessoas se sentem constrangidas de iniciar o aprendizado de Ingles com um curso direcionado para crianças, isto é tolice, se voce acha que não sabe nada, que ainda está muito “crú”, a melhor estrategia é iniciar em um curso “for kids”, ouvi isto (quero dizer… li), de um grande professor de inglês: chamado A. J. Hoge, criador do Effort English ( http://effortlessenglishclub.com/), concordo  quando ele diz que se iniciarmos com algo muito difícil, a tendencia é desistirmos e/ou nos consideramos incapazes em um curto espaço de tempo.

Arregaçando as mangas

Vamos deixar de blá blá blá e iniciar no que realmente interessa, vou começar com alguns links para pessoas que, como eu, já tem o “Básico do básico, do básico”, para quem acha que se encontra na situação de “não sei nadica de nada”, reservei um espaço no fim  destes textos, e para quem já está em um nível além do básico, sorry, talvez voce não seja contemplado aqui.

English Made in Brasil

O English made in Brasil (http://www.sk.com.br/sk.html) não é o tipo de site que tem como foco o ensino, mas sim a lingua Inglesa em si, tem tudo sobre o idioma, aliás, sobre o aprendizado do idioma, se voce seguiu esta chatisse de texto até aqui (ou mesmo que tenha iniciado neste trecho) então acho que voce deveria entrar neste site e “debulha-lo”, nele voce vai encontrar tópicos escritos em Português, tais como:

Que é língua?
Que é aprender inglês e como aprender?
Línguas: conhecimento ou habilidade?

O site é bem extenso, procura derrubar alguns mitos, como o que a maioria dos professores afirmam que o Inglês é uma língua fácil, mais fácil que o português, lembro-me de uma discussão no forum do site em que um dos seus administradores apresentava varios argumentos para afirmar que o Inglês é mais dificil que o nosso idioma, um dos que recordo claramente é o fato do Português possuir tantas regras gramaticais, os acentos, etc, ele fazia um pararelo com o fato de voce dirigir em uma estrada sinalizada (nosso idioma) e dirigir em uma estrada não sinalizada (Inglês), O fato do idioma ser mais rico não implica, necessariamente, ser mais difícil, infelizmente não consegui encontrar o link quando escrevia este texto. De qualquer forma, o debate se deu antes da reforma ortográfica, seria esta reforma benéfica ao nosso idioma? sei lá! visite este site: http://www.acordarmelhor.com.br/ e tire suas próprias conclusões. Bah! o assunto é Inglês, vamos ao próximo:

Inglês Já

É um site de uma Brasileira que vive no Reino Unido, a proposta dela não é ensinar Inglês mas sim ensinar como estudar o idoma, como ela fala em Português, não vou me alongar explicando o trabalho dela, para compreende-lo, basta ir no site: http://inglesja.com/30dc/, o interessante é que quando eu escrevia este texto, bastou clicar no “Já sou cadastrado” para sair usando, nem precisou me cadastrar, pra se ter uma idéia do proposta da garota, deixo aqui o segundo vídeo da série de 30, escolhi este vídeo porque sempre quis postar algo no meu blog sobre o delicious, a Fabiana ja o fez:

Estudo baseado na repetição

Uma ótima opção para incrementar o vocabulário, Estas ferramentas são baseadas em estudos científicos, funciona mais ou menos como uma espécie de game ou quiz, em que é feito uma pergunta e dependendo do nível de acerto do usuário, a mesma pergunta será programada para um determinado tempo (algumas horas, 2 dias, 3 dias, etc), Estas ferramentas funcionam não só para o aprendizado de idiomas (na verdade para a memorização de vocábulos e expressões) mas também para qualquer assunto em que se possa fragmentar o conhecimento.

Supermemo

http://www.supermemo.net/
Basta voce criar uma conta e se inscrever nos vários cursos gratuitos disponiveis, tem também muitos cursos pagos, voce pode também crias seus proprios cursos.

Quizlet

http://quizlet.com/
Aqui também voce pode criar seu proprio set (http://quizlet.com/create_set/) ou estudar em um das centenas que existem, por exemplo:

http://quizlet.com/4226289/sat-vocab-flash-cards/
http://quizlet.com/4314264/list-e-antonyms-flash-cards/

Exercícios

Este site tem ‘teracentos’ exercícios, em varios níveis (vai aparecer no tópico “For kids”), o site pode te conduzir a conteúdos onde as instruções estão em espanhol ou outro idioma qualquer mas o objetivo sempre é o aprendizado de ingles: http://www.agendaweb.org/ alguns exercicios podem parecer “babacas” ou infantis, mas tem muita coisa boa

Help for Students Learning English

Como eles mesmos dizem “aprenda Inglês com nossos recursos gratuitos para estudantes ESL, incluindo referencias no aprendizado do idioma, atividades, tais como testes, votações e artigos em ingles, aqui é o lugar perfeito para o aprendizado de inglês, onde as pessoas estão online 24 horas por dia para responder suas perguntas” : http://www.usingenglish.com/students.html

Por enquanto é isto, na próxima semana continuarei o texto, o melhor está por vir! :-)

Segunda parte: http://www.cosmoverbal.net/english-language/learning-english-on-the-internet-parte-2


I’m proud 2b brazilian.

December 28th, 2010 No Comments   Posted in Diversão

Ahahahahahah! Pelo menos quando ouço um samba de qualidade eu tenho orgulho de ser brasileiro, vejam: o cara posta um video (video?) sem nenhum movimento, apenas com o som, e vejam só os comentários:

– I wish i was brazilian.

– Dude, it’s genius, period. Cause first, it’s Jorge’s song orginally, and second, his voice and tone is almost mesmerizing.

– i haven’t heard this original version for many years. thank you. this song and this genre of music is so easy on the ears and psyche. dripping with sophistication.

– thats amazing
from hong kong

– This is as pure a Brazilian” feel one can have of Brasilin music and culture………it’s dated but it is eternal…..what a culture and diversity of land. His voice is unbelievable….estava no Brasil quatros vezes na minha vida… vou denovo o prosimo ano……floating the Araguaia and Xingu rivers…..Ilha do Bananal…o mato fechado…..killing time on Copacaba…O Brasil……um pais fantastico…!!

E por ai vai…