terça-feira, 26 de fevereiro de 2008

Primos em Smalltalk

VisualWorks Smalltalk é a linguagem orientada a objetos por excelência.

Desenvolvida na década de 1960, baseada na linguagem Simula, muitos paradigmas modernos foram criados por essa equipe do MIT.

Segue aqui um exemplo aplicado de Smalltalk: busca por números primos.

O algoritmo é baseado no crivo de Aristóstenes, que consiste em, a cada primo encontrado, eliminar seus múltiplos até o fim do conjunto.

Vamos começar declarando as variáveis locais count, com a contagem de primos encontrados, max, que conterá o tamanho do conjunto, e primeList, uma lista – na verdade dicionário – dos números marcados como não-primos:
| count max primeList |

count := 0.
max := 5000.
primeList := Dictionary new.


Começamos então com nenhum primo conhecido (0) e um conjunto de cinco mil (5000) números. Vamos agora informar ao dicionário que 1 não é primo e pedir para limpar o Transcript – área (stream) onde será exibido o resultado:
primeList at: 1 put: false.
Transcript clear.


É preciso agora criar um ciclo (loop) de 2 até o máximo de números do conjunto:
2 to: max do: [ :i |


Para cada i, é preciso verificar se é verdadeiro – se o número não existe na lista (ifAbsent:), ele não é múltiplo de nenhum dos números antecessores, portanto é primo (true):
    (primeList at: i ifAbsent: true) ifTrue: [


Se o número é primo, devemos:
  1. exibi-lo no Transcript;
  2. incrementar o contador;
  3. marcar todos seus múltiplos como não-primos


Fechando os colchetes já abertos, o código fica assim:
        Transcript show: i printString; tab.
count := count + 1.
i * 2 to: max by: i do: [ :j |
primeList at: j put: false
]
]
].


Resta agora somente exibir a contagem:
Transcript
cr;
show: 'Quantidade de primos: ', count printString;
cr.


Repara que, quando várias mensagens são enviada ao mesmo objeto, elas são separadas por ponto-e-vírgula (;).

Alguns comentários:
  • Quando um número recebe a mensagem #printString, ele retorna uma representação string para exibição.
  • Transcript trata a mensagem #tab exibindo uma tabulação e a mensagem #cr exibindo uma mudança de linha.
  • Quando um número recebe a mensagem #to:do:, reitera de forma parecida com for de C.
  • A mensagem #to:by:do: funciona como #to:do:, mas acrescenta o passo.
  • A mensagem #at:put: faz o dicionários associar um par chave-valor ou mudar o valor associado a uma chave.
  • A mensagem #at:ifAbsent: faz o dicionário retornar o valor associado a uma chave, ou um valor padrão.
  • A mensagem #ifTrue: é enviada a um objeto booleano, que executa o bloco de código somente se o objeto for verdadeiro. Outras mensagens similares são: #ifFalse:, #ifTrue:ifFalse: e #ifFalse:ifTrue:.


Bem, espero que esse pequeno tutorial seja de alguma ajuda, se não para o mercado, para expandir conhecimentos.

[]'s
Cacilhas, La Batalema
blog comments powered by Disqus