Percursos
/
Common Lisp
Common Lisp
/
Exercícios
/
As compridas listas da Leslie
As compridas listas da Leslie

As compridas listas da Leslie

Exercício de aprendizagem

Introdução

Listas

Dado que o nome da linguagem que estamos a usar, Lisp, significa LIST Processing, poderias pensar que a linguagem tem recursos para lidar com listas de itens, e tens razão!

Apesar de Common Lisp ter outras estruturas de dados além das listas, as listas continuam a ser muito usadas.

Uma lista em Common Lisp é uma sequência de itens. Também é chamada de cons (sobretudo por razões históricas). Os próprios itens não têm de ser do mesmo tipo. Por exemplo, podes ter uma lista de 1, two, "III".

Criar listas

Podes simplesmente escrever uma lista citada assim: '(1 two "III"), o que faz com que uma lista seja criada e avaliada (é avaliada como (1 two "III")).

Há também duas funções principais usadas para criar listas: list e cons.

list recebe zero ou mais argumentos e é avaliada como uma lista criada com esses valores:

(list 1 'two "III") ; => (1 two "III")

cons recebe dois itens e cria uma lista em que o primeiro item é o seu car (a cabeça da lista) e o segundo item é o seu cdr (o resto da lista):

(cons 1 2)            ; => (1 . 2) ;; (a list without `nil` as its `cdr` is printed in this way)
(cons 1 nil)          ; => (1)
(cons 1 (cons 2 nil)) ; => (1 2)

As funções car e cdr podem ser usadas para aceder ao car e ao cdr de uma lista.

(first e rest são sinónimos de car e cdr e funcionam exatamente da mesma forma.)

Comprimento e acesso aleatório

O comprimento de uma lista pode ser determinado com length. Uma lista vazia tem comprimento zero.

Podes aceder a um item arbitrário com nth (repara que as listas têm índices a começar em zero).

Pedir um índice maior do que o comprimento da lista não é um erro. Em vez disso, é avaliado como nil:

(nth 23 '(short list)) ; => nil

Há também vários métodos auxiliares para aceder aos primeiros itens de uma lista: first, second, third, e por aí fora até tenth. Porreiro, não?

Combinar listas

Duas ou mais listas podem ser combinadas com append:

(append '(a b c) '(1 2 3)) ; => (A B C 1 2 3)
(append '(a b c) '())     ; => (A B C)

Cada argumento dado a append tem de ser uma lista.

Instruções

A Leslie, a alienígena do Lisp, precisa de fazer umas compras. É muito importante ter uma lista de compras. É preciso acrescentar coisas à lista e tirar coisas dela.

Claro que caneta e papel não chegam para uma alienígena do Lisp. "List" é a maior parte da palavra "Lisp"! Têm de existir funções escritas para ajudar a acompanhar as compras.

Consegues ajudar a Leslie a manter a lista de compras em ordem?

1. Criar uma nova lista

A primeira coisa de que a Leslie precisa é de criar uma lista vazia. Uma função chamada new-list seria perfeita para isso.

(new-list) ; => ()

Oh, não... A Leslie já tem algumas coisas em mente, por isso precisa de uma função que receba três itens (felizmente, a Leslie só cria listas de três itens. Nem mais, nem menos!) e que crie uma nova lista de compras com essas coisas. Escreve uma função, list-of-things, que receba três itens e devolva uma lista com eles.

(list-of-things 'bread 'milk 'butter) ; => '(bread milk butter)

2. Acrescentar coisas à lista.

Antes de ir à loja, a Leslie espreita a despensa para ver o que precisa. Ajuda-a escrevendo a função add-to-list, que acrescenta um item ao início de uma lista.

(add-to-list 'butter '(bread)) ; => '(butter bread)

3. O que vem a seguir na lista?

Enquanto faz compras, a Leslie quer saber o que procurar a seguir. Também gosta de espreitar a lista para ver o segundo, o terceiro ou até o 23.º item (o seu número da sorte).

  • first-thing dá como resultado a primeira coisa da lista
  • second-thing dá como resultado a segunda coisa
  • third-thing dá como resultado a terceira coisa
  • twenty-third-thing dá como resultado a vigésima terceira coisa
(first-thing '(bread butter milk)) ; => 'bread
(second-thing '(bread butter milk)) ; => 'butter
(third-thing '(bread butter milk)) ; => 'milk

4. Remover uma coisa da lista

A Leslie quer encontrar o primeiro item da lista e removê-lo da prateleira. Ajuda-a escrevendo uma função remove-first-item, que dá como resultado uma lista com tudo menos o primeiro item da lista recebida.

(remove-first-item '(bread butter milk)) ; => '(butter milk)

5. Listas maiores a partir de listas mais pequenas

A Leslie percebeu que fez duas listas de compras sem querer, em vez de uma! Escreve uma função, list-append, que devolve uma lista com os elementos da primeira lista seguidos dos da segunda.

(list-append '(bread salt) '(butter milk)) ; => '(bread salt butter milk)

6. Quanto tempo falta?

A Leslie está a ficar preocupada por esta ida às compras demorar muito tempo. Afinal, quantas coisas há nesta lista? Escreve uma função just-how-long que lhe diga qual é o comprimento da lista.

(just-how-long '(bread milk butter salt)) ; => 4
Editar via GitHub A ligação abre numa nova janela ou separador
Common Lisp Exercism

Estás pronto para começar As compridas listas da Leslie?

Inscreve-te no Exercism para aprenderes e dominares Common Lisp com 27 conceitos92 exercícios, e mentoria humana real, tudo grátis.