Esercizi svolti nella Lezione del 13/06/2012 Esercizio 1 (tempo

Transcript

Esercizi svolti nella Lezione del 13/06/2012 Esercizio 1 (tempo
Esercizi svolti nella Lezione del 13/06/2012
Esercizio 1 (tempo previsto: 20’): Scrivere in Scheme (o, se si preferisce, in Lisp) una funzione split
che prende in input una lista di interi l e restituisce in output la lista l con i numeri pari che precedono
i numeri dispari nello stesso ordinamento con cui i numeri compaiono in l. Si consiglia la definizione
di funzioni ausiliarie per l’implementazione di split.
NOTA: l’utilizzo dell’operatore Lisp/Scheme modulo non è ammesso per determinare se un intero è
pari o dispari. La lista può contenere sia interi positivi sia negativi (e anche doppioni). Si consideri lo 0
come un intero pari.
esempio: (split ‘(3 0 -73 6 -24 6 2)) restituisce: (0 6 -24 6 2 3 -73)
Esercizio 2 (tempo previsto: 10’): Mostrare cosa stampa in output ML nel valutare le seguenti
istruzioni. Se non si ricorda la sintassi dei messaggi di output di ML è sufficiente specificare il risultato
della valutazione dell’istruzione (e.g., identificatore con valore 5, puntatore al valore 7, il numero 3,
funzione, etc.), e il tipo del risultato (e.g., int, puntatore a real, bool*int->real, etc.). In caso di errore,
specificare il motivo per cui la valutazione dell’istruzione ha terminato in un errore. In caso di non
terminazione, specificarne la causa. Ogni istruzione va valutata tenendo conto dell’ambiente
modificato dalle precedenti istruzioni.
val x = 5;
________________________________________
val y = ref (ref (ref x));
_________________________________
let val y = 8 in let val y = 5 and z = 3 in y * z end end;
___________________________________________________________________
fun inc(y) = y + 1;
________________________________________
fun inc(f) = f(x);
________________________________________
inc(4);
________________________________________
inc(inc);
________________________________________
fun twice(y) = y * 2; ________________________________________
inc(twice);
________________________________________
Esercizio 3 (tempo previsto: 20’): Data le seguente definizione di tipo di dato astratto:
datatype intTree = ifoglia of int | inodo of int * intTree * intTree;
scrivere una funzione t2l_sort che prende in input un albero A di tipo intTree e ritorna in output un
lista B di interi dove gli elementi in B sono le etichette dei nodi contenuti in A e sono ordinati in modo
crescente. Si consiglia la definizione di funzioni ausiliare per l’implementazione di t2l_sort.
NOTA: i pattern match che si usano nella definizione delle varie funzioni devono essere tutti esaustivi
(ovvero non si accetta la definizione di funzioni parziali).
esempio: t2l_sort(
restituisce:
inodo(3,
inodo(0,ifoglia(73),ifoglia(6)),
inodo(24,i foglia(6),ifoglia(2))))
[0 2 3 6 6 24 73]
Esercizio 4 (tempo previsto: 20’): Data la seguente funzione ML:
fun g([x]) = x |
g(x::l) = if x < g(l) then x else g(l);
cosa calcola g e quale è il suo tipo. Inoltre dire, motivando
dire
la risposta, se g è una funzione parziale
o totale. Nel caso si riscontri che g è una funzione parziale, dire se in ML c’è un modo per considerare
anche i casi in cui la funzione g possa essere invocata su argomenti per cui essa non è semanticamente
definibile in modo corretto. Motivare la risposta fornendo del codice esemplificativo (si prenda in
considerazione la possibilità di poter aggiungere, se si ritiene opportuno, nuovi pattern matches al
codice di g sopra riportato).
Esercizio 5 (tempo previsto: 20’): Date le seguenti definizioni di classe in C++
class A {
public:
virtual void print() {
std::cout << "Ciao da A\n";
}
};
class B {
public:
virtual void print() {
std::cout << "Ciao da B\n";
}
};
class C: public A, B {
public:
virtual void print() {
std::cout << "Ciao da C\n";
}
};
dire se il compilatore C++ riesce a compilare il seguente main program oppure no. Motivare
opportunamente la risposta. Solo nel caso in cui si ritenga che il compilatore non ritorni errori, dire
cosa stampa la chiamata al metodo print. Motivare opportunamente la risposta.
int main (int argc, char * const argv[]) {
B *b = new B();
C *c = new C();
b = c;
b->print();
return 0;
}
Esercizi svolti nella Lezione del 14/06/2012
Esercizio 1 (tempo previsto: 30’). Scrivere in Scheme o in Lisp una funzione estrai_e_alterna che,
data una lista L di numeri naturali (ovvero numeri interi >= 0) e dato un intero N >= 0, restituisce la
lista M che contiene tutti i numeri di L che sono multipli di N elencati alternando i multipli pari con i
multipli
dispari
nel
seguente
modo:
(primo_multiplo_pari
primo_multiplo_dispari
secondo_multiplo_pari secondo_multiplo_dispari ….). Ad esempio se in input viene passata la lista
'(2 3 4 9 1 6) e l’intero 3, in output viene restituita la lista '(6 3 9).
NOTA: al fine di non rendere l’esercizio triviale, la funzione modulo fornita direttamente da
Scheme/Lisp non può essere utilizzata per controllare se un numero è pari o dispari, o se un numero è
multiplo di un altro. Pertanto, se lo studente ritiene di dover utilizzare una funzione equivalente a
modulo, essa deve essere definita dallo studente stesso.
Esercizio 2 (tempo previsto: 15’). Mostrare cosa stampa in output ML nel valutare le seguenti
istruzioni.
NOTA: se non si ricorda la sintassi dei messaggi di output di ML è sufficiente specificare il risultato
della valutazione dell’istruzione (e.g., identificatore con valore 5, puntatore al valore 7, il numero 3,
funzione, etc.), e il tipo del risultato (e.g., int, puntatore a real, bool*int->real, etc.). In caso di errore,
specificare il motivo per cui la valutazione dell’istruzione ha terminato in un errore. In caso di non
terminazione, specificarne la causa. Ogni istruzione va valutata tenendo conto dell’ambiente modificato
dalle precedenti istruzioni.
- val x = 3;
_____________________________________________
- val y = (ref x);
_____________________________________________
- val ref z = ref (ref y);
___________________________________________________________________
- val k =
let val k =
!(!z) and z=7 in fn g => g(fn z => z + k) + z end;
___________________________________
- fun f(k) = !k(x);
_____________________________________________
- k(fn x => x + 1);
_____________________________________________
- fun g(h, a) = fn k => (fn nil => nil | b::m => k(b)::h(a));
___________________________________________________________________
Esercizio 3 (tempo previsto: 25’). Sia dato uno stack definito dalla seguente definizione di tipo in
ML:
datatype 'a stack = Empty | elem of
'a | stack of 'a * 'a stack;
e la definizione dell’eccezione EmptyExc: exception EmptyExc;
a. Scrivere una funzione pop che prende in input uno stack di tipo ‘a stack e torna, se lo stack ha
almeno un elemento, una coppia costituita dall’elemento al top dello stack e lo stack con l’elemento al
top cancellato, oppure, se lo stack è vuoto, solleva l’eccezione EmptyExc.
b. Dare il tipo della funzione pop.
Esercizio 4 (tempo previsto: 15’). Dato il seguente codice C++:
class B {
public :
B() { Init(); }
virtual void Init() { cout << "B::B()" << endl; }
};
class D : private B {
public :
D() { Init(); }
virtual void Init() { cout << "D::D()" << endl; }
};
int main(int argc, char *argv[]) {
D *objD = new D();
}
dire se il programma viene compilato correttamente o se ci sono errori a tempo di compilazione. Se si
riscontra che non ci sono errori a tempo di compilazione, dire se il programma presenta errori durante
l’esecuzione oppure no. Se si riscontra che il programma esegue correttamente, dire cosa stampa in
output. Si motivino tutte le risposte in modo chiaro ed esaustivo.