Em Clojure, as listas são coleções, assim como listas em outras linguagens. Assim como outras linguagens da família Lisp, Clojure usa parênteses para expressar listas.
Listas em Clojure podem ser criadas de duas maneiras. A função list pode criar uma lista, ou você pode usar quote em uma lista literal.
Listas são especiais porque Clojure as trata como chamadas. A chamada deve começar com um operador, que geralmente é uma função. Os itens restantes da lista são considerados operandos, ou seja, se tornam os argumentos da função.
Por causa do tratamento especial que Clojure dá às listas, não podemos criar uma lista literal diretamente. Citar uma lista usando quote ou seu atalho ' indica que a lista não deve ser avaliada.
Ao contrário de algumas linguagens modernas, as listas em Clojure são heterogêneas, ou seja, podem conter vários tipos de itens internamente, por exemplo, '(2 "a" "b" 3). Ao contrário de outros Lisps, uma lista vazia em Clojure é considerada verdadeira e não é equivalente a nil ou false.
A Elyse está muito animada para jogar um pouco de pôquer (e outros jogos de cartas) na viagem que vai fazer para Vegas. Como é uma grande fã de "self-tracking", ela quer montar algumas funções pequenas que vão ajudá-la com tarefas de acompanhamento e pediu sua ajuda para pensar sobre elas.
A Elyse gosta especialmente de pôquer e quer acompanhar quantas rodadas ela joga, e quais rodadas são essas. Cada rodada tem seu próprio número, e cada mesa mostra o número da rodada que está sendo jogada no momento. A Elyse escolhe uma mesa e se senta para jogar sua primeira rodada. Ela pretende jogar três rodadas.
Implemente uma função rounds que recebe o número da rodada atual e retorna uma list única com essa rodada e as duas próximas que estão por vir:
(rounds 27)
;;=> (27 28 29)
A Elyse jogou algumas rodadas na primeira mesa, depois fez uma pausa e jogou mais algumas rodadas em uma segunda mesa... mas acabou com uma lista diferente para cada mesa! Ela quer juntar as duas listas, para poder acompanhar todas as rodadas de pôquer no mesmo lugar.
Implemente uma função concat-rounds que recebe duas listas e retorna uma list única composta por todas as rodadas da primeira list, seguidas de todas as rodadas da segunda list:
(concat-rounds '(27 28 29) '(35 36))
;;=> (27 28 29 35 36)
Conversando sobre algumas das rodadas anteriores de pôquer, outro jogador comenta como duas delas foram parecidas. A Elyse não tem certeza se jogou essas rodadas ou não.
Implemente uma função contains-round? que recebe dois argumentos: uma lista de rodadas jogadas e um número de rodada.
A função retorna true se a rodada estiver na lista de rodadas jogadas, e false se não estiver:
(contains-round? '(27 28 29 35 36) 29)
;;=> true
(contains-round? '(27 28 29 35 36) 30)
;;=> false
A Elyse quer experimentar um jogo novo chamado Black Joe. Ele é parecido com o Black Jack, em que o objetivo é que as cartas na sua mão somem um valor alvo, mas no Black Joe o objetivo é que a média dos valores das cartas seja 7. A média pode ser encontrada somando todos os valores das cartas e depois dividindo essa soma pelo número de cartas na mão.
Implemente uma função card-average que retorna o valor médio de uma mão de Black Joe.
(card-average '(5 6 7))
;;=> 6.0
No Black Joe, a velocidade é importante. A Elyse vai tentar encontrar uma forma mais rápida de calcular a média.
Ela pensou em duas formas de obter um número parecido com uma média:
Implemente a função approx-average?, que recebe hand, uma lista contendo os valores das cartas na sua mão.
Retorne true se uma or ambas das estratégias citadas acima resultarem em um número igual à média real.
Observação: o comprimento de todas as mãos é ímpar, para facilitar encontrar a mediana.
(approx-average? '(1 2 3))
;;=> true
(approx-average? '(2 3 4 8 8))
;;=> true
(approx-average? '(1 2 3 5 9))
;;=> false
Intrigada com os resultados do seu experimento de médias, a Elyse se pergunta se tirar a média das cartas nas posições pares em comparação com a média das cartas nas posições ímpares daria os mesmos resultados. Hora de mais uma função de teste!
Implemente uma função average-even-odd? que retorna um Boolean indicando se a média das cartas nos índices pares é igual à média das cartas nos índices ímpares.
(average-even-odd? '(1 2 3))
;;=> true
(average-even-odd? '(1 2 3 4))
;;=> false
Toda 11ª mão no Black Joe é uma mão de bônus com uma regra de bônus: se a última carta que você compra for um Valete, você dobra o valor dela.
Implemente uma função maybe-double-last que recebe uma mão e verifica se a última carta é um Valete (11).
Se a última carta for um Valete (11), dobre o valor dela antes de retornar a mão.
(maybe-double-last '(5 9 11))
;;=> '(5 9 22)
(maybe-double-last '(5 9 10))
;;=> '(5 9 10)
Crie sua conta no Exercism para aprender e dominar Clojure com 12 conceitos105 exercícios e mentoria humana de verdade, tudo de graça.