17 gennaio 2018
Linguaggi e Traduttori
Prof. Marco Gavanelli
17 gennaio 2018
Esercizio 1 (punti 17)
Da mesi, il terribile criminale Malvagik attanaglia la città in una spirale di violenza. I suoi delitti spaziano su tutta la città, senza che la polizia riesca ad acciuffarlo.
Ultimamente, però, qualcuno nella polizia ha ipotizzato che, fra i vari delitti di Malvagik, gli omicidi siano distribuiti nella mappa della città con un criterio: se si riesce ad indovinare il criterio, sarà forse possibile sapere in anticipo dove avverrà il prossimo omicidio.
Dagli archivi della polizia, è stato estratto un file crimini.txt in cui sono riportati i delitti di Malvagik. Per ciascun crimine, viene riportato
- tipo del delitto: stringa
- l'indirizzo a cui è avvenuto il crimine, costituito da
- nome della via: stringa
- numero civico: intero
Si ha poi un file indirizzi.txt che contiene, per ciascun indirizzo della città, le coordinate a cui si trova quell'indirizzo; per ciascun indirizzo il file contiene quindi:
- nome della via: stringa
- numero civico: intero
- x e y: due interi, compresi fra 0 e 9
A questo punto, voi dovete mostrare una mappa 10×10 che mostri con un asterisco la posizione dei soli crimini di tipo omicidio e con uno spazio le rimanenti posizioni. Riuscirete, osservando la mappa, a scoprire dove avverrà il prossimo omicidio di Malvagik?
Si usino opportunamente funzioni di ordine superiore. Per ottenere il massimo dei punti, si definisca almeno una funzione di ordine superiore (e la si usi).
Esercizio 2 (punti 3)
Si scriva un programma Lex che dice se una password è sicura. Una password può essere costituita da lettere maiuscole, lettere minuscole e numeri.
Qualora la password inserita dall'utente sia abbastanza sicura, il programma deve visualizzare "OK: " seguito dalla password inserita. Se, invece, la password non è sicura, il programma deve visualizzare la password stessa.
Una password è considerata sicura se contiene almeno una lettera maiuscola e almeno una minuscola (in qualsiasi ordine).
Si otterrà un punto in più se il programma considererà la password sicura se contiene almeno una maiuscola, almeno una minuscola e almeno un numero (in qualsiasi ordine).
Soluzione 1
data Crimine = Crimine {crimine::String, viaCrim::String, civicoCrim::Int} deriving (Show) data Indirizzo = Indirizzo {viaInd::String, civicoInd::Int, x::Int, y::Int} deriving (Show) main = do -- criminiStr <- readFile "crimini.txt" -- let crimini = map (leggiCrimini.words) (lines criminiStr) crimini <- leggiFile "crimini.txt" leggiCrimini -- indirizziStr <- readFile "indirizzi.txt" -- let indirizzi = map (leggiIndirizzi.words) (lines indirizziStr) indirizzi <- leggiFile "indirizzi.txt" leggiIndirizzi -- print crimini -- let mappa = itera crimini (riportaMappa indirizzi) buildMap let mappa = foldr (riportaMappa indirizzi) (initMap 10 10) (filter ((=="Omicidio").crimine) crimini) sequence (map print mappa) leggiFile nome parse = do stringa <- readFile nome return (map (parse.words) (lines stringa)) leggiCrimini [crimine,via,civico] = Crimine crimine via (read civico) leggiIndirizzi [via,civico,x,y] = Indirizzo via (read civico) (read x) (read y) riportaMappa indirizzi (Crimine crim via civico) mappa = let i = head [ind | ind <- indirizzi, (viaInd ind)== via, (civicoInd ind)==civico] yi = y i xi = x i in update yi mappa (update xi (mappa!!yi) '*') update _ [] _ = [] update pos (x:xs) val = if pos == 0 then val:xs else x:update (pos-1) xs val initMap r c = take r (lconst (take c (lconst ' '))) lconst c = iterate (\_ -> c) c -- In realta` lconst e` predefinita: si chiama repeat
Soluzione 2
NUM [0-9] MAI [A-Z] MIN [a-z] ALL {NUM}|{MAI}|{MIN} NUMMAI ({NUM}{ALL}*{MAI}{ALL}*)|({MAI}{ALL}*{NUM}{ALL}*) NUMMIN ({MIN}{ALL}*{NUM}{ALL}*)|({NUM}{ALL}*{MIN}{ALL}*) MAIMIN ({MIN}{ALL}*{MAI}{ALL}*)|({MAI}{ALL}*{MIN}{ALL}*) PWD {NUM}{ALL}*{MAIMIN}{ALL}*|{MAI}{ALL}*{NUMMIN}{ALL}*|{MIN}{ALL}*{NUMMAI}{ALL}* %% {PWD} printf("ok: %s",yytext); %%