Track
/
Common Lisp
Common Lisp
/
Esercizi
/
Il magnifico mapper di Lucy
Il magnifico mapper di Lucy

Il magnifico mapper di Lucy

Esercizio di apprendimento

Introduzione

Mappatura

La mappatura consiste nell'applicare una funzione a ogni elemento di una sequenza per produrre una nuova sequenza.

Su una lista questo si può fare facilmente con la funzione mapcar. Supponiamo di avere una funzione double che moltiplica il suo argomento per 2:

(mapcar #'double '(1 2 3 4)) ; => (2 4 6 8)

Nota che il primo argomento è una funzione da chiamare. Il #' è una sintassi di quotatura speciale per specificare una funzione.

double è stata chiamata prima con il primo elemento, poi con il secondo, e così via. I risultati sono stati raccolti in una lista, che è il valore risultante dalla valutazione dell'espressione.

Filtraggio

Il filtraggio è il processo che crea una sequenza a partire da un'altra sequenza, copiando dalla sequenza originale tutti gli elementi tranne alcuni. La scelta di quali elementi includere nella nuova sequenza può avvenire tramite una funzione predicato (una funzione che restituisce un valore booleano) oppure tramite uguaglianza con un oggetto specifico.

Rimuovere tramite un predicato

remove-if è una funzione che prende come argomenti una funzione predicato e una sequenza, e restituisce una sequenza dei soli elementi per i quali il predicato è risultato falso. In altre parole, «rimuove» tutti gli elementi della sequenza per cui il predicato è vero. Nota però che questa funzione non modifica la sequenza originale! Restituisce invece una nuova sequenza senza gli elementi in questione. Se il predicato era vero per tutti i valori, viene restituita una sequenza vuota.

(remove-if #'evenp '(1 2 3 4 5)) ; => (1 3 5)
(remove-if #'oddp '(1 3 5))      ; => ()

Rimuovere un elemento specifico

Se si vuole rimuovere un elemento specifico da una sequenza, si può usare remove, che prende l'elemento da rimuovere e una sequenza. Vengono restituiti tutti i valori della sequenza che non sono uguali all'elemento da rimuovere. NOTA: per impostazione predefinita l'uguaglianza è verificata con eql, il predicato di uguaglianza generico.

(remove 1 '(1 2 1 3 1 4)) ; => (2 3 4)
(remove #\l "hello")      ; => "heo"

Istruzioni

Lucy, l'aliena Lisp, ama i numeri e alcuni li trova «magnifici».

Ti chiede di aiutarla a scrivere delle funzioni per rendere i numeri ancora più magnifici.

Quello che secondo Lucy rende magnifico un numero può cambiare, quindi le funzioni dovranno essere flessibili.

1. Rendi magnifico

Per trasformare un array di numeri in un array di numeri più magnifici dovrai scrivere una funzione make-magnificent-maybe che prende una funzione da applicare ai numeri e un array di numeri. Deve restituire un array di numeri ancora più magnifici (secondo la funzione fornita).

(make-magnificent-maybe #'square '(1 2 3)) ; => (1 4 9)
(make-magnificent-maybe #'1+ '(1 2 3))     ; => (2 3 4)

2. Solo i migliori

Dopo aver reso (si spera) i numeri più magnifici, Lucy vuole vedere solo i numeri che sono davvero magnifici.

Sa per certo che 1 non è mai magnifico, quindi dovrai semplicemente eliminarlo.

Ma a parte questo, Lucy a volte cambia idea, quindi anche stavolta ti darà una funzione che ti dirà se un numero è magnifico oppure no.

Dovrai scrivere una funzione only-the-best che prende una funzione e un array di numeri e restituisce solo i numeri migliori (escluso 1 e i numeri per cui la funzione restituisce vero).

(only-the-best #'evenp '(1 2 3 4 5)) ; => (3 5)
(only-the-best #'oddp '(1 3 5))    ; => ()
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Common Lisp Exercism

Vuoi iniziare Il magnifico mapper di Lucy?

Iscriviti a Exercism per imparare e padroneggiare Common Lisp con 27 concetti92 esercizi e il mentoring di persone reali, tutto gratis.