Salta ai contenuti. | Salta alla navigazione

Strumenti personali

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 ;
%%