Soluzioni - Dipartimento di Scienze Ambientali, Informatica e Statistica
Transcript
Soluzioni - Dipartimento di Scienze Ambientali, Informatica e Statistica
Soluzione Università Ca’ Foscari Dipartimento di informatica Programmazione part-time Esame Ocaml Nome: Matricola: Samuel Rota Bulò , a.a. 2009/2010 Programmazione part-time a.a. 2009/2010 Esame Ocaml Nome: Samuel Rota Bulò Teoria. (10 punti) Rispondere ai seguenti quesiti utilizzando eventualmente gli appositi spazi bianchi. Tempo totale a disposizione: 20 min. (2pts ) 1. Dato il seguente codice: let a =( fun a -> a ** 2.) 4.;; quale delle sequenti affermazioni è corretta? (Barrare la risposta esatta) (a) a = 8 (b) a è di tipo int (c) errore di tipo (d) 4 a = 16 (3pts ) 2 pts (e) a è una funzione 2. Scrivere il corpo della sequente funzione let inv erti_p rimi_d ue lst = 3 pts (* corpo *) ;; in modo tale da ritornare la lista lst con i primi 2 elementi invertiti se la lista ha almeno due elementi. La lista lst in caso contrario. Per esempio: • inverti_primi_due [1;2;3] = [2;1;3] • inverti_primi_due [’a’] = [’a’] Solution: let inv erti_p rimi_d ue lst = match lst with e1 :: e2 :: t -> e2 :: e1 :: t |x -> x ;; (2pts ) 3. Qual è il tipo della funzione inverti_primi_due definita nell’esercizio precedente? val inverti_primi_due : (3pts ) ’a list -> ’a list 2 pts 4. Date le seguenti variabili: let f x = function _ -> x + x ;; let h = fun x y -> y ;; let g = if x >= 0 then 1 else -1 ;; dire quale di queste affermazioni è vera (V) o falsa (F). (0.5 punti per risposta corretta). (a) F f è una funzione che raddoppia un numero intero. (b) V il tipo di f è int -> ’a -> int. (c) F g è la funzione segno (vale 1 o −1 in base al segno dell’argomento). (d) V f 2 è una funzione costante (per ogni valore dell’argomento ritorna una stessa costante). (e) F h (1,’a’)= ’a’. (f) V il tipo di h è ’a -> ’b -> ’b. 3 pts Programmazione part-time/Esame Ocaml – Pag. 3 / 5 – Nome: Pratica. (23 punti) Nello svolgimento del seguente esame, il candidato crei una cartella con il proprio cognome e numero di matricola (e.g. Rossi887766) inserendo all’interno i file corrispondenti agli esercizi che si intendono consegnare (e.g. Esercizio1.ml). Le prime righe del file devono essere dei commenti che specifichino il vostro nome e cognome e l’esercizio a cui si riferiscono. Tempo a disposizione: 1h e 45 min. (8pts ) 1. Gestione di liste “miste”. (a) (2 pts) Definire un nuovo tipo per gestire liste che possano essere composte da stringhe, interi e booleani. Idealmente lo scopo è poter creare liste “miste” del tipo true,"abc",2,false,"cde". 8 pts Solution: type variant = Bool of bool | Int of int | String of string ;; (b) (4 pts) Scrivere una funzione che estragga da una lista “mista” una lista di elementi di tipo stringa. Nel caso della lista “mista” true,"abc",2,false,"cde" la funzione dovrà ritornare ["abc";"cde"] (ovvero una string list). Solution: let rec lista_stringhe = function ( String s ) :: coda -> s :: lista_stringhe coda | _ :: coda -> lista_stringhe coda | [] -> [] ;; (c) (2 pts) Scrivere la stessa funzione utilizzando le funzioni List.filter e List.map. • val filter : (’a -> bool)-> ’a list -> ’a list. List.filter p l ritorna tutti gli elementi della lista l che soddisfano il predicato p. L’ordine degli elementi nella lista in input è preservato. • val map : (’a -> ’b)-> ’a list -> ’b list. List.map f [a1; ...; an] applica la funzione f alla coda [a1; ...; an] ottenendo quindi la lista [f a1; ...; f an]. Solution: let lista_stringhe list = List . map ( function String s -> s | _ -> " " ) ( List . filter ( function String _ -> true | _ -> false ) list ) ;; (15pts ) 2. Si vogliono scrivere delle funzioni Ocaml per la gestione dei propri segnalibri di indirizzi WEB. Un segnalibro è composto da due stringhe, la prima è l’identificatore del segnalibro e la seconda è l’indirizzo. Ad esempio "Google" "http://www.google.it" è il segnalibro il cui identificatore è Google e la stringa seguente è l’indirizzo. Per gestire la struttura dati si consiglia l’utilizzo di una semplice lista di coppie di stringhe. (a) (3 pts) Si crei una funzione per inserire un segnalibro in una lista di segnalibri. Una possibile firma è: let inserisci segnalibri identificatore indirizzo = (* corpo *) ;; Solution: let inserisci segnalibri identificatore indirizzo = ( identificatore , indirizzo ) :: segnalibri ;; 15 pts Programmazione part-time/Esame Ocaml – Pag. 4 / 5 – Nome: (b) (3 pts) Si crei una funzione per l’eliminazione di tutti i segnalibri di una lista di segnalibri con un certo identificatore dato. Solution: let rec elimina segnalibri identificatore = match segnalibri with ( id , ind ) :: coda when id = identificatore -> elimina coda identificatore | s :: coda -> s ::( elimina coda identificatore ) | [] -> [] ;; (c) (3 pts)Si crei una funzione per la ricerca di un indirizzo a partire dall’identificatore in una lista di segnalibri. (Nota: Lo studente è libero di trovare l’indirizzo relativo solo alla prima occorrenza dell’identificatore o di tutte le occorrenze). Solution: let rec trova segnalibri identificatore = match segnalibri with ( id , ind ) :: coda when id = identificatore -> ind | s :: coda -> trova coda identificatore | [] -> failwith " non trovato " ;; (d) (6 pts) Si crei una funzione che elimini da una lista di segnalibri quelli duplicati. I segnalibri duplicati sono quelli che hanno la parte iniziale dell’indirizzo uguale, cioè il prefisso fino a quando si incontra un carattere / singolo o la fine della stringa. Ad esempio: "http://www.prova.it" è uguale ad "http://www.prova.it/cartella" che a sua volta è uguale a "http://www.prova .it/hello". È consentito utilizzare le seguenti funzioni: • val length : string -> int String.length s ritorna la lunghezza della data stringa. • val get : string -> int -> char String.get s n ritorna l’n-esimo carattere nella stringa s. • val sub : string -> int -> int -> string String.sub s start len ritorna la sottostringa di lunghezza len di s che inizia dal carattere alla posizione start. Solution: let taglia_stringa s = let ultimo =( String . length s ) -1 in let rec taglia_stringa posizione num_barre = if posizione <= ultimo then ( if String . get s posizione = ’/ ’ then taglia_stringa ( posizione +1) ( num_barre +1) else if num_barre =1 then else String . sub s 0 ( posizione -1) taglia_stringa ( posizione +1) 0 ) else if num_barre = 1 then String . sub s 0 ultimo else s in taglia_stringa 0 0 ;; Programmazione part-time/Esame Ocaml – Pag. 5 / 5 – Nome: let rec eli mina_d uplica ti segnalibri = let rec e l i m i n a _ d u p l i c a t i _ i n d i r i z z o indirizzo segnalibri = match segnalibri with ( id , ind ) :: coda when indirizzo = taglia_stringa ind -> e l i m i n a _ d u p l i c a t i _ i n d i r i z z o indirizzo coda | s :: coda -> s ::( e l i m i n a _ d u p l i c a t i _ i n d i r i z z o indirizzo coda ) | [] -> [] in match segnalibri with ( id , ind ) :: coda -> ( id , ind ) ::( elimi na_dup licati ( e l i m i n a _ d u p l i c a t i _ i n d i r i z z o ( taglia_stringa ind ) coda ) ) |[] - >[] ;;