diff --git a/TP3/project/build.properties b/TP3/project/build.properties old mode 100644 new mode 100755 diff --git a/TP3/src/main/scala/8.monoids.scala b/TP3/src/main/scala/8.monoids.scala index e2a474487e1f5b4a94af0458f69adc99cadb42d8..9a813f05b067809120b1b60dcd8b908f3690c200 100755 --- a/TP3/src/main/scala/8.monoids.scala +++ b/TP3/src/main/scala/8.monoids.scala @@ -111,18 +111,34 @@ object Examples { def minMax( as: List[Double] ): (Double,Double) = mapReduce[Double, (Double, Double)](as)((a:Double) => (a, a), tuple2M(doubleMin, doubleMax)) //Série 3: Even - def even[A]( as: List[A] ): Boolean = mapReduce[A, Int](as)(_ => 1, intSum)%2 == 0 + def even[A]( as: List[A] ): Boolean = mapReduce(as)(a=>false, Monoid(true)(_ == _)) //Compte le nombre d'occurence de chaque objet de la liste - def count[A]( as: List[A] ): Map[A,Int] = mapReduce[A, Map[A, Int]](as)((x: A) => Map[A, Int](x -> 1), mapM[A, Int](Monoid[Int](0)(_ + _))) + def count[A]( as: List[A] ): Map[A,Int] = mapReduce[A, Map[A, Int]](as)((x: A) => Map[A, Int](x -> 1), mapM[A, Int](intSum)) //Compte le nombre d'occurence de chaque pair d'objet - def count2[A,B]( as: List[(A,B)] ): Map[A,Map[B,Int]] = mapReduce[(A,B), Map[A,Map[B, Int]]](as)( (x:(A,B)) => Map(x._1 -> Map(x._2 -> 1)),mapM[A,Map[B, Int]](mapM[B, Int](Monoid[Int](0)(_ + _)))) + def count2[A,B]( as: List[(A,B)] ): Map[A,Map[B,Int]] = mapReduce[(A,B), Map[A,Map[B, Int]]](as)( (x:(A,B)) => Map(x._1 -> Map(x._2 -> 1)),mapM[A,Map[B, Int]](mapM[B, Int](intSum))) //Série 4: forall - def forall[A]( ps: List[(A)=>Boolean] ): (A)=>Boolean = (a:A) => { mapReduce(ps)((p:A=>Boolean) => p(a), Monoid[Boolean](true)(_ && _)) } + def funcM[A,B](MB: Monoid[B]) = { + Monoid[A=>B](a => MB.zero){ (f:A=>B, g:A=>B) => (a:A) => MB.op(f(a), g(a))} + } + + def forall[A]( ps: List[(A)=>Boolean] ): (A)=>Boolean = reduce(ps)(funcM(Monoid[Boolean](true)(_ && _))) + + def sortedList[A](as1:List[A], as2:List[A], smallerThan: (A,A)=>Boolean) = { + def mergeR(l1: List[A], l2: List[A], res:List[A]): List[A] = (l1,l2) match { + case (Nil, _) => res.reverse ++ l2 + case (_, Nil) => res.reverse ++ l1 + case (h1::t1, h2::t2) => + if(smallerThan(h1,h2)) mergeR(t1, l2, h1::res) + else mergeR(l1,t2, h2::res) + } + mergeR(as1, as2, Nil) + } + //def sort( as: List[Double]): List[Double] = } diff --git a/TP3/src/main/scala/9.Entities.scala b/TP3/src/main/scala/9.Entities.scala new file mode 100644 index 0000000000000000000000000000000000000000..2c3d0a59aae409a021d676754fdb5ec88ea1b1c0 --- /dev/null +++ b/TP3/src/main/scala/9.Entities.scala @@ -0,0 +1,79 @@ +import Monoid.Laws + +trait Monoid[A] { + def op( a1: A, a2: A ): A + def zero: A +} + +object Monoid { + def apply[A]( z: A )( f: (A,A)=>A ) = new Monoid[A] { + def op( a1: A, a2: A ): A = f(a1,a2) + def zero: A = z + } + + object Laws { + def checkAssociativity[A](mon: Monoid[A], a1: A, a2: A, a3: A) = { + import mon.op + op(a1,op(a2,a3)) == op(op(a1,a2),a3) + } + def checkNeutral[A](mon: Monoid[A], a: A) = { + import mon._ + op(zero,a) == a && op(a,zero) == a + } + } +} + +case class Module[+A](name: String, args: Map[String, A]){ + override def toString: String = { + s"Name : $name. Args : ${args.toString()}" + } +} + +case class Task(modules: List[Module[Any]]){ + override def toString: String = { + s"Modules : ${modules.toString()}\n" + } +} + +object TaskMonoid{ + def + = Monoid[Task](Task(Nil))( (t1, t2) => + Task(t1.modules:::t2.modules)) + + def mapReduce[A,B]( as: List[A] )(f: A=>B, M: Monoid[B]): B = { + def rec( rem: List[A], acc: B ): B = rem match { + case Nil => acc + case h :: t => rec( t, M.op(acc, f(h) ) ) + } + rec( as, M.zero ) + } + def reduce[A]( as: List[A] )( M: Monoid[A] ): A = + mapReduce( as )( identity, M ) +} + +object tp { + def main(args: Array[String]): Unit = { + import TaskMonoid._ + + val m1 = Module("Swiss-Impex", Map("year" -> 2019, "month" -> 1, "category" -> "2709.0090")) + val m2 = Module("Fao Genève PROD 2019/11/06", Map("passCaptcha" -> true, "page" -> 1)) + val m3 = Module("Tâche 3", Map("Oui" -> true, "non" -> false)) + + val t1 = Task((m1::Nil)) + val t2 = Task((m2::Nil)) + val t3 = Task((m3::Nil)) + + val t1p2 = reduce(List(t1, t2))(+) + val t1t2t3 = List(t1, t2, t3) + val t1t2 = List(t1, t2) + val t1t3 = List(t1, t3) + val t2t3 = List(t2,t3) + + + println("========== TEST ASSOCIATIVITE ===========\n") + println((reduce(List(t1, reduce(t2t3)(+)))(+) == reduce(List(reduce(t1t2)(+), t3))(+))) + println() + println("========== TEST ELEMENT NEUTRE ==========\n") + println(t1 == reduce(List(t1,Task(Nil)))(+) && t1 == reduce(List(Task(Nil), t1))(+)) + + } +} \ No newline at end of file diff --git a/TP3/src/test/scala/8.monoidTest.scala b/TP3/src/test/scala/8.monoidTest.scala index 736232e19902d929cb85b30235ce83a82e778738..00004d853b60aaaae16616df034023c6d3bad6b3 100755 --- a/TP3/src/test/scala/8.monoidTest.scala +++ b/TP3/src/test/scala/8.monoidTest.scala @@ -58,6 +58,11 @@ class Monoid8Suite extends AnyFunSuite { assert( forall( Nil )( 200 ) ) } + /*test("sort") { + val test1 = List(2.0,1.0,5.0,6.0,4.0,8.0,7.0,1.0) + assert(sort(test1) == List(1.0,1.0,2.0,4.0,5.0,6.0,7.0,8.0)) + }*/ + }