Bom dia pessoal, tudo bem? Ontem, aqui na Lambda3, tivemos um primeiro segundo Coding Dojo usando Elixir, e a idéia deste post é comentar um pouco do que aconteceu 😉

Errata: O 1º dojo com Elixir na Lambda3 ocorreu há cerca de 3 anos, e o código pode ser encontrado aqui.

O que é um dojo?

Algumas pessoas presentes nunca haviam participado de um dojo, então a primeira coisa a fazer é ambientá-las. Usei uns slides super antigos que eu tinha:

Escolhendo o problema

Depois de estarmos ambientadas, apresentei três problemas que eu havia achado interessantes para explorar um pouco mais os recursos do Elixir, e então as pessoas presentes escolheram este aqui: http://dojopuzzles.com/problemas/exibe/palavras-primas.

Um número primo é definido se ele possuir exatamente dois divisores: o número um e ele próprio. São exemplos de números primos: 2, 3, 5, 101, 367 e 523.
Neste problema, você deve ler uma palavra composta somente por letras [a-zA-Z]. Cada letra possui um valor específico, a vale 1, b vale 2 e assim por diante, até a letra z que vale 26. Do mesmo modo A vale 27, B vale 28, até a letra Z que vale 52.
Você precisa definir se cada palavra em um conjunto de palavras é prima ou não. Para ela ser prima, a soma dos valores de suas letras deve ser um número primo.

Programando com Elixir

Aqui é onde começaram os desafios. Uma das primeira perguntas que um piloto fez:

Ok, como eu faço um laço for?

Não faz, usa recursividade 😛

Aqui tivemos a primeira grande quebra no pensamento. Ao invés de ter um laço de repetição, usaríamos recursividade para executar um código mais uma vez. Após algum tempo passamos a conseguir identificar se um número era ou não primo. O mais interessante é que estávamos usando TDD, então cada nova experimentação que fazíamos tínhamos alguns testes para garantir que estávamos indo para o caminho correto.

Além disso paramos de usar if no código, e tudo deveria ser resolvido com pattern matching, o que é algo bem interessante no Elixir (e em outras linguagens funcionais).

Resultado

O resultado que chegamos durante o dojo pode ser visto abaixo:


defmodule Dojo1 do
    def is_prime(1), do: false
    def is_prime(n), do: is_prime(n, n-1)
    defp is_prime(_n, 1), do: true

    defp is_prime(n, start) do
        case rem(n, start) do 
        0 -> false
        _ -> is_prime(n, start-1)
        end
    end

    def numero_palavra(palavra), do: numero_palavra(to_charlist(palavra), 0)

    def numero_palavra([], acc), do: acc
    def numero_palavra([32 | tail], acc), do: numero_palavra(tail, acc)
    def numero_palavra([head | tail], acc) do
        case head > 90 do
            :true -> numero_palavra(tail, acc + head - 96)
            :false -> numero_palavra(tail, acc + head - 38)
        end
    end

    def palavra_prima(palavra), do: is_prime numero_palavra(palavra)
end

De fato este não é o melhor código, e até melhoramos ele um pouco depois. Confira o código final e os testes no repositório do github.

Nossa idéia é realizar mais dojos, e mais dojos usando Elixir também. Quaisquer dúvidas ou comentários, fiquem à vontade 🙂

Vinicius Quaiato