Programmazione Funzionale e Parallela

Corso di Laurea in Ingegneria Informatica e Automatica - A.A. 2021-2022

Home | Avvisi | Diario lezioni | Esercitazioni | Materiale didattico | Esami | Valutazioni studenti

Esercitazione del 1 dicembre 2021

Istruzioni per l’esercitazione:

Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.

Esercizio 1 (creazione di matrici immutabili in Scala)

Scrivere nel file E1.scala un metodo currificato def buildMatrix(rows:Int, cols:Int)(f:(Int,Int) => Double):Vector[Vector[Double]] che restituisce una matrice di Double con rows righe e cols colonne dove f(i,j) descrive il contenuto della cella (i,j).

Più precisamente, il metodo restituisce un Vector[Vector[Double]] v tale che per ogni i in [0,rows-1] e per ogni j in [0,cols-1] si ha v(i)(j) == f(i,j).

Usare il main di prova nella directory di lavoro E1. Non modificare alcun file tranne E1.scala.

Esercizio 2 (numeri di Fibonacci - parallelismo in Scala)

Scrivere nel file E2.scala una versione parallela fibPar del seguente metodo ricorsivo fib definito nel file Fib.scala usando fork-join in Scala mediante il costrutto par. La soluzione deve assumere la presenza di 2 core nella CPU.

def fib(a:Int, b:Int)(n:Int):Long = 
    if (n < 2) a
    else if (n == 2) b
    else fib(a,b)(n-1) + fib(a,b)(n-2)

Usare il main di prova nella directory di lavoro E2, mettendo sulla riga di comando tutti i file Scala forniti. Non modificare alcun file tranne E2.scala.

Suggerimento: nel metodo fibPar, che non dovrebbe essere ricorsivo, eseguite in parallelo le due chiamate fib(a,b)(n-1) e fib(a,b)(n-2)

Esercizio 3 (sottolista non consecutiva)

Scrivere nel file E3.scala un metodo def subList(l:List[T]):Boolean applicabile su un oggetto List[T] s che restituisce true se e solo se tutti gli elementi di l appaiono anche in s nello stesso ordine, anche non consecutivamente.

Usare il main di prova nella directory di lavoro E3. Non modificare alcun file tranne E3.scala.

Esercizio 4 (data analytics con metodi sulle collezioni)

Scrivere nel file E4.scala un metodo piuGiovane che, dato un Vector s di oggetti Studente(id, nome) e un Vector e di oggetti Eta(id, eta), restituisce un Option[String] che vale None se s è vuoto e Some(x), dove x è il nome dello studente più giovane, altrimenti. Si assuma che ogni id contenuto in s sia anche contenuto in e. Gli id sono unici in ciascuna collezione e servono come chiave primaria in s e in e.

Usare il main di prova nella directory di lavoro E4. Non modificare alcun file tranne E4.scala.

Soluzioni
object E1 {
    def buildMatrix(rows:Int, cols:Int)(f:(Int,Int) => Double):Vector[Vector[Double]] = {
        def buildRow(row:Int, cols:Int):Vector[Double] = (0 until cols).toVector.map(col => f(row,col))
        (0 until rows).toVector.map(row => buildRow(row, cols))
    }
}
object E2 {
    def fibPar(a:Int, b:Int)(n:Int):Long = {
        if (n < 2) a
        else if (n == 2) b
        else {
            val (x,y) = Par.par {
                Fib.fib(a,b)(n-1)
            }
            {
                Fib.fib(a,b)(n-2)
            }
            x + y
        }
    }
}
import scala.language.implicitConversions

object E3 { 
    implicit def seq2MySeq[T](s:List[T]):MyList[T] = new MyList(s)
}

class MyList[T](s:List[T]) {
    import E3._
    def subList(l:List[T]):Boolean = {
        if (l.isEmpty) true
        else if (s.isEmpty) false
        else if (s.head == l.head) s.tail.subList(l.tail)
        else s.tail.subList(l)
    }
}
object E4 {
    def piuGiovane(s:Vector[Studente], e:Vector[Eta]):Option[String] = {
        if (s.isEmpty) None
        else {
            val m:Map[Int,Vector[Eta]]  = e.groupBy(_.id)
            Some(s.reduce((x,y) => if (m(x.id)(0).eta < m(y.id)(0).eta) x else y).nome)
        }
    }
}

Valid XHTML 1.0 Transitional     Valid CSS!