29 giugno 2016 - laboratorio
Linguaggi e Traduttori - Compito A
Prof. Marco Gavanelli
29 giugno 2016
Esercizio 1 (punti 16)
Un file di testo orario.txt contiene l'orario delle lezioni di un corso di laurea. Ogni riga del file rappresenta una lezione; per ciascuna lezione, il file contiene le seguenti informazioni:
- nome del corso, stringa
- giorno della settimana (intero da 1 a 5, che rappresenta i giorni da lunedì a venerdì)
- ora di inizio della lezione (intero)
- ora di fine (intero)
Si scriva un programma Haskell che legge il file orario.txt e visualizza a video il giorno in cui gli studenti devono trascorrere più tempo all'università, inteso come la differenza fra l'ora di inizio della prima lezione e quella di fine dell'ultima.
Ad esempio, se il file orario.txt contiene le seguenti informazioni:
Informatica | 1 | 16 | 18 |
Informatica | 2 | 16 | 18 |
Analisi | 1 | 8 | 11 |
Analisi | 2 | 14 | 16 |
Geometria | 2 | 10 | 13 |
il giorno in cui gli studenti passano più tempo all'Università è il giorno 1 (lunedì), in quanto iniziano la prima lezione alle 8 e terminano l'ultima alle 18 (10 ore di permanenza all'Università). Il giorno 2 (martedì), invece, iniziano alle 10 e terminano alle 18 (8 ore di permanenza).
All'interno del programma, si scriva e poi si usi (in più volte possibile, inteso come in più situazioni diverse possibile) una funzione di ordine superiore
maxf :: Ord a => (t -> a) -> [t] -> t
che prende come parametri una funzione f e una lista xs e fornisce l'elemento x della lista xs che massimizza la funzione f (ossia il valore x per cui f(x) è massimo).
Si scriva il programma in modo che possa essere creato l'eseguibile.
Esercizio 2 (Punti 2)
Si scriva un programma Lex produce in output le sole liste di numeri naturali date nel testo di input.
Una lista di naturali è una sequenza, iniziata da una parentesi quadra aperta e terminata da una parentesi quadra chiusa, di naturali separati da virgole.
Ad esempio, dato il testo
abc [1,2,3] def[3,2] [7,g,6] [2,3,4,] [88] [-2,5] [07,00,11]
produce
[1,2,3][3,2][88][07,00,11]
Soluzione 1
data Lezione = Lezione {nome :: String, giorno :: Int, inizio::Int, fine::Int} deriving Show
main = do
string <- readFile "orario.txt"
let orario = lettura string
orarioPerGiorno = [ lezGiorno orario g | g <- [1..5] ]
durate = map durataGiorno orarioPerGiorno
(putStrLn.show.fst) (maxf snd (zip [1..] durate))
-- calcolo della durata di un giorno
durataGiorno ls = (fine(maxf fine ls)) - (inizio(maxf (negate.inizio) ls))
lezGiorno ls g = filter ((g==).giorno) ls
lettura s = map (leggiLezione.words) (lines s)
leggiLezione riga = Lezione (riga!!0) (read(riga!!1)) (read(riga!!2)) (read(riga!!3))
maxf f (z:zs) = foldl (\x y -> if (f x) > (f y) then x else y) z zs
Soluzione 2
Nel caso il testo sia riconoscibile come lista, lo stampa. Qualsiasi altro carattere (.
o \n
) non viene stampato (viene eseguita l'istruzione vuota).
INTERO [0-9]+
LISTA \[({INTERO},)*{INTERO}\]
%%
{LISTA} printf("%s",yytext);
. ;
\n ;
%%