====== Lab 06. List applications ====== In this lab, we will use **lists** to implement a lot of string processing. The type ''String'' is not decomposable as a list, but strings can be converted to lists **of Char** as follows: "Some string".toList For this reason, we will use the following aliases: type Str = List[Char] type Email = Str Throughout this lab, use higher-order functions (map, foldRight, foldLeft, filter, zip, partition, etc) **whenever possible**. ==== 6.1. Gradebooks ==== In what follows, we shall encode a gradebook as a list of pairs ''(,)'', where '''' is a String and '''' is an Int. Example: type Gradebook = List[(String,Int)] //the type Gradebook now refers to a list of pairs of String and Int val gradebook = List(("G",3), ("F", 10), ("M",6), ("P",4)) Add this type alias to your code before solving the following exercises. **6.1.1.** Write a function which adds one point to all students which have a passing grade (>= 5), and leaves all other grades unchanged. def increment(g: Gradebook): Gradebook = g.map(???) **6.1.2.** Find the average grade from a gradebook. You must use ''foldRight''. def average(g: Gradebook): Double = ??? **6.1.3.** Write a function which takes a gradebook and returns the percentage of failed vs. passed students, as a pair (x,y). def percentage(g: Gradebook): (Double,Double) = ??? **6.1.4.** Write a function which takes a gradebook and returns the list of names which have passed. Use filter and map from Scala. def pass(g: Gradebook): List[String] = ??? **6.1.5** Write a function which takes a gradebook and reports all passing students in **descending** order of their grade. def honorsList(g: Gradebook): List[String] = ??? **6.1.6.** We extend the type ''Gradebook'' to: type Name = String type Lecture = String type ExtGradebook = List[(Name,Lecture,Int)] val egradebook = List(("John","FP",4)) // the first string is the student name, the second is the course, and the final integer is the grade Write a function which reports all students that have failed at least one grade (each student will be reported once): def atLeastOneFail(g: ExtGradebook): List[Name] = ??? **6.1.7.**(!) Write a function ''groupBy'', which is a generalisation of the previous exercise: def groupBy[A,B](l: List[A])(criterion: A => B): List[(B,List[A])] = ??? The function ''groupBy'' takes a list with elements of type ''A'', a criterion ''A => B'' and produces a list of pairs ''(c, lp) : (B,List[A])'' with the property that each member of the list ''lp'' satisfy the criterion with the value ''c''. Suppose ''f: A => B'' is a criterion. Two elements ''a : A'' and ''b : A'' satisfy the criterion ''f'' **iff** ''f(a) == f(b)''. Examples: groupBy(List("john", "mary", "mihai"))(_.size) = List((4,List("john","mary")), (5, List("mihai"))) groupBy(List((1,2), (2,1), (3,3))(p => p._1 + p._2) = List((3,List((1,2),(2,1))), (6, List((3,3))) ==== 6.2. Lists of emails ===== **6.2.1.** Write a function which takes a list of emails and extracts the prefix (e.g. ''example@domain.com'' becomes ''example''). def getNames (l: List[Email]): List[Email] = ??? **6.2.2.** Write a function which filters out emails belonging to a specific Top-Level-Domain (e.g. those than end in ''com''). def removeTLD(l: List[Email], tld: Str): List[Email] = ??? **6.2.3.** Write a function which checks is there exist identical names under different domains in a list of emails (e.g. ''ana@amazon.com'' and ''ana@gmail.com'') def containsDuplicates(l: List[Email]): Boolean = ??? **6.2.4.** Write a function which reports **the number of duplicates** of names under different domains in a list of emails. (e.g. ''["ana@aol.com", "ana@aol.ro", "ana@amazon.com", "jim@cx.com", "mary@mail.com" , "mary@mail.ro"]'' will produce: ''2'' since there are two duplication instances: for ''ana'' and for ''mary''. def countDuplicates(l: List[Email]): Int = ??? **6.2.5.** Write a function which reports **all duplicates** of names under different domains in a list of emails. (e.g. ''["ana@aol.com", "ana@aol.ro", "jim@cx.com", "mary@mail.com" , "mary@mail.ro"]'' will produce: ''[ ["ana@aol.com", "ana@aol.ro"], ["mary@mail.com" , "mary@mail.ro"]]'' def extractDuplicates(l: List[Email]): List[List[Email]] = ??? **6.2.6.** Write a function which removes **all duplicates** of names under different domains in a list of emails. (e.g. ''["ana@aol.com", "ana@aol.ro", "jim@cx.com", "mary@mail.com" , "mary@mail.ro"]'' will produce: ''[ ["ana@aol.com", "ana@aol.ro"], ["mary@mail.com" , "mary@mail.ro"]]'' def extractDuplicates(l: List[Email]): List[List[Email]] = ???