Compare commits
	
		
			31 Commits
		
	
	
		
			b18b92fb0b
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b7ca6610fc | |||
| ec0e1e8ae4 | |||
| 5365eabadd | |||
| 43e0694d9d | |||
| c13f9851e3 | |||
| bed771a04e | |||
| 6954695a0d | |||
| a16b70970f | |||
| 34b1ff39ce | |||
| e58c399bad | |||
| 95fdbf7abf | |||
| 17c1e4170d | |||
| d4878015e3 | |||
| f693d69366 | |||
| d8b22157c5 | |||
| 9ad00e6182 | |||
| b53e0677cc | |||
| 056305fd72 | |||
| f4e417571a | |||
| 4eba7f3587 | |||
| 76a4f50075 | |||
| 41c0b80d8b | |||
| 3f648b7fc9 | |||
| 84315955f8 | |||
| bbfcb31026 | |||
| 03c383fb35 | |||
| eebfe377c7 | |||
| 8c01471dda | |||
| 56f41ecc22 | |||
| 2f72fbb599 | |||
| 9eeb59f1e0 | 
							
								
								
									
										86
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								README.md
									
									
									
									
									
								
							| @@ -14,11 +14,25 @@ | ||||
|     * [Lesson 2 - Higher order functions](#lesson-2---higher-order-functions) | ||||
|     * [Lesson 3 - Data structures](#lesson-3---data-structures) | ||||
|     * [Lesson 4 - Lists and pattern matching](#lesson-4---lists-and-pattern-matching) | ||||
|     * [Lesson 5 - Advanced lists and High order functions](#lesson-5---advanced-lists-and-high-order-functions) | ||||
|     * [Midterm preparation](#midterm-preparation) | ||||
|     * [Midterm](#midterm) | ||||
|     * [Lesson 6 - Tuples and comprehensions](#lesson-6---tuples-and-comprehensions) | ||||
|     * [Lesson 7 - Advanced typing and infinite lists](#lesson-7---advanced-typing-and-infinite-lists) | ||||
|     * [Lesson 8 - Futures and parallel collections](#lesson-8---futures-and-parallel-collections) | ||||
|     * [Lesson 9 - DSLs](#lesson-9---dsls) | ||||
|     * [Final preparation](#final-exam-preparation) | ||||
|     * [Final](#final-exam) | ||||
|   * [Assignments](#assignments) | ||||
|     * [Assignment 1 - Square root](#assignment-1---square-root) | ||||
|     * [Assignment 2 - Map-reduce](#assignment-2---map-reduce) | ||||
|     * [Assignment 3 - Binary tree](#assignment-3---binary-tree) | ||||
|     * [Assignment 4 - Lists and pattern matching](#assignment-4---lists-and-pattern-matching) | ||||
|     * [Assignment 5 - High-order functions on lists](#assignment-5---high-order-functions-on-lists) | ||||
|     * [Assignment 6 - Sequence comprehension and tuples](#assignment-6---sequence-comprehension-and-tuples) | ||||
|     * [Assignment 7 - Advanced typing and infinite lists](#assignment-7---advanced-typing-and-infinite-lists) | ||||
|     * [Assignment 8 - Advanced typing and infinite lists](#assignment-8---advanced-typing-and-infinite-lists) | ||||
|     * [Assignment 9 - DSLs](#assignment-9---dsls) | ||||
| <!-- TOC --> | ||||
|  | ||||
|  | ||||
| @@ -49,6 +63,49 @@ | ||||
| - Pattern matching | ||||
| - Genericity | ||||
|  | ||||
| ### Lesson 5 - Advanced lists and High order functions | ||||
| [Files](src/Lesson5) | ||||
| - Lists | ||||
| - High order functions | ||||
|  | ||||
| ### Midterm preparation | ||||
| [Files](src/MidTermPrep1) | ||||
|  | ||||
| ### Midterm | ||||
| [Files](src/MidTerm1) | ||||
|  | ||||
| ### Lesson 6 - Tuples and comprehensions | ||||
| [Files](src/Lesson6) | ||||
| - Tuples | ||||
| - For-comprehension | ||||
| - Yield | ||||
| - Flatmap | ||||
|  | ||||
| ### Lesson 7 - Advanced typing and infinite lists | ||||
| [Files](src/Lesson7) | ||||
| - Types | ||||
| - Bounds | ||||
| - Traits | ||||
| - Variance, covariance and contra-variance | ||||
| - Infinite sequences | ||||
|  | ||||
| ### Lesson 8 - Futures and parallel collections | ||||
| [Files](src/Lesson8) | ||||
| - Futures | ||||
| - Actors | ||||
| - Parallel collections | ||||
|  | ||||
| ### Lesson 9 - DSLs | ||||
| [Files](src/Lesson9) | ||||
| - DSL | ||||
|  | ||||
| ### Final exam preparation | ||||
| [Files](src/FinalPrep1) | ||||
|  | ||||
| ### Final exam | ||||
| [Files](src/Final1) | ||||
|  | ||||
|  | ||||
| ## Assignments | ||||
|  | ||||
| ### Assignment 1 - Square root | ||||
| @@ -74,4 +131,31 @@ | ||||
| - Expression interpreter | ||||
| - Binary tree | ||||
| - List functions | ||||
| - Predicates (any / every) | ||||
| - Predicates (any / every) | ||||
|  | ||||
| ### Assignment 5 - High-order functions on lists | ||||
| [Files](src/Assignment5) | ||||
| - High-order functions | ||||
| - Lists | ||||
| - Map | ||||
| - Fold | ||||
| - Zip | ||||
|  | ||||
| ### Assignment 6 - Sequence comprehension and tuples | ||||
| [Files](src/Assignment6) | ||||
| - Tuples | ||||
| - `for` comprehension | ||||
|  | ||||
| ### Assignment 7 - Advanced typing and infinite lists | ||||
| [Files](src/Assignment7) | ||||
| - Genericity | ||||
| - Infinite lazy lists | ||||
|  | ||||
| ### Assignment 8 - Advanced typing and infinite lists | ||||
| [Files](src/Assignment8) | ||||
| - Parallel collections | ||||
| - Futures | ||||
|  | ||||
| ### Assignment 9 - DSLs | ||||
| [Files](src/Assignment9) | ||||
| - DSL | ||||
|   | ||||
							
								
								
									
										79
									
								
								src/Assignment4/Ex3_ListsMatch.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/Assignment4/Ex3_ListsMatch.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| import scala.annotation.tailrec | ||||
|  | ||||
|  | ||||
| // Complexity: O(n) | ||||
| @tailrec | ||||
| def last[T](list: List[T]): T = { | ||||
|   list.tail match { | ||||
|     case Nil => list.head | ||||
|     case _ => last(list.tail) | ||||
|   } | ||||
| } | ||||
|  | ||||
| def init[T](list: List[T]): List[T] = { | ||||
|   list.tail match { | ||||
|     case Nil => Nil | ||||
|     case _ => list.head::init(list.tail) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Complexity: O(n) | ||||
| def concat[T](l1: List[T], l2: List[T]): List[T] = { | ||||
|   l1 match { | ||||
|     case Nil => l2 | ||||
|     case _ => l1.head::concat(l1.tail, l2) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Complexity: O(n²) | ||||
| def reverse[T](list: List[T]): List[T] = { | ||||
|   list match { | ||||
|     case Nil => Nil | ||||
|     case _ => last(list)::reverse(init(list)) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Better -> O(n) | ||||
| /* | ||||
| def reverse[T](list: List[T], res: List[T] = Nil): List[T] = { | ||||
|   list match { | ||||
|     case Nil => res | ||||
|     case _ => reverse(list.tail, list.head::res) | ||||
|   } | ||||
| } | ||||
| */ | ||||
|  | ||||
| def take[T](list: List[T], n: Int): List[T] = { | ||||
|   if (n <= 0) Nil | ||||
|   else list match { | ||||
|     case Nil => Nil | ||||
|     case _ => list.head::take(list.tail, n - 1) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @tailrec | ||||
| def drop[T](list: List[T], n: Int): List[T] = { | ||||
|   if (n <= 0) list | ||||
|   else list match { | ||||
|     case Nil => list | ||||
|     case _ => drop(list.tail, n - 1) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @tailrec | ||||
| def apply[T](list: List[T], n: Int): T = { | ||||
|   n match { | ||||
|     case 0 => list.head | ||||
|     case _ => apply(list.tail, n - 1) | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| assert(last(List(1,2,3)) == 3) | ||||
| assert(init(List(1,2,3)) == List(1,2)) | ||||
| assert(concat(List(1,2,3), List(4,5,6)) == List(1,2,3,4,5,6)) | ||||
| assert(reverse(List(1,2,3)) == List(3,2,1)) | ||||
| assert(take(List(1,2,3), 2) == List(1,2)) | ||||
| assert(drop(List(1,2,3), 2) == List(3)) | ||||
| assert(drop(List(1,2,3), 4) == Nil) | ||||
| assert(apply(List(1,2,3), 2) == 3) | ||||
							
								
								
									
										36
									
								
								src/Assignment5/Folds.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/Assignment5/Folds.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| def areTrue(booleans: List[Boolean]): Boolean = { | ||||
|   booleans.foldLeft(true)((acc, value) => acc && value) | ||||
| } | ||||
|  | ||||
| def lString(strings: List[String]): Int = { | ||||
|   strings.foldLeft(0)((len, str) => len + str.length) | ||||
| } | ||||
|  | ||||
| def longest(strings: List[String]): Int = { | ||||
|   strings.foldLeft(0)((maxLen, str) => if (str.length > maxLen) str.length else maxLen) | ||||
| } | ||||
|  | ||||
| def isPresent[T](list: List[T], target: T): Boolean = { | ||||
|   list.foldLeft(false)((res, value) => res || value == target) | ||||
| } | ||||
|  | ||||
| def flattenList(list: List[Any]): List[Any] = { | ||||
|   list.foldRight(List.empty[Any])((elem, acc) => { | ||||
|     elem match { | ||||
|       case l: List[Any] => flattenList(l).foldRight(acc)((e, l) => e::l) | ||||
|       case _ => elem::acc | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| assert(!areTrue(List(true, true, false))) | ||||
| assert(areTrue(List(true, true, true))) | ||||
|  | ||||
| assert(lString(List("Folding", "is", "fun")) == 12) | ||||
|  | ||||
| assert(longest(List("What", "is", "the", "longest?")) == 8) | ||||
|  | ||||
| assert(!isPresent(List(1, 2, 3, 4), 5)) | ||||
| assert(isPresent(List(1, 2, 3, 4), 3)) | ||||
|  | ||||
| assert(flattenList(List(List(1, 1), 2, List(3, List(5, 8)))) == List(1, 1, 2, 3, 5, 8)) | ||||
							
								
								
									
										18
									
								
								src/Assignment5/HOFOnLists.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/Assignment5/HOFOnLists.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| def lengthStrings(strings: List[String]): List[Int] = { | ||||
|   strings map (s => s.length) | ||||
| } | ||||
|  | ||||
| def dup[T](elem: T, n: Int): List[T] = { | ||||
|   (1 to n).toList map (_ => elem) | ||||
| } | ||||
|  | ||||
| def dot(list1: List[Int], list2: List[Int]): List[Int] = { | ||||
|   list1 zip list2 map (p => p._1 * p._2) | ||||
| } | ||||
|  | ||||
| assert(lengthStrings(List("How","long","are","we?")) == List(3, 4, 3, 3)) | ||||
|  | ||||
| assert(dup("foo", 5) == List("foo", "foo", "foo", "foo", "foo")) | ||||
| assert(dup(List(1,2,3), 2) == List(List(1,2,3), List(1,2,3))) | ||||
|  | ||||
| assert(dot(List(1,2,3), List(2,4,3)) == List(2,8,9)) | ||||
							
								
								
									
										17
									
								
								src/Assignment6/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/Assignment6/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| def flattenList(list: List[Any]): List[Any] = { | ||||
|   list.foldRight(List.empty[Any])( | ||||
|     (e, acc) => { | ||||
|       e match { | ||||
|         case l: List[Any] => flattenList(l) concat acc | ||||
|         case _ => e::acc | ||||
|       } | ||||
|     } | ||||
|   ) | ||||
| } | ||||
|  | ||||
| assert( | ||||
|   flattenList( | ||||
|     List(List(1,1), 2, List(3, List(5, 8))) | ||||
|   ) == List(1,1,2,3,5,8) | ||||
| ) | ||||
|  | ||||
							
								
								
									
										38
									
								
								src/Assignment6/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/Assignment6/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
|  | ||||
| def isPrime(i: Int): Boolean = | ||||
|     i match { | ||||
|         case i if i <= 1 => false | ||||
|         case 2 => true | ||||
|         case _ => !(2 to (i - 1)).exists(x => i % x == 0) | ||||
|     } | ||||
|  | ||||
| def primeSum(max: Int): List[(Int, Int)] = | ||||
|     for { | ||||
|         i <- (1 to max).toList | ||||
|         j <- (1 to max).toList | ||||
|         if (isPrime(i + j)) | ||||
|     } yield (i, j) | ||||
|  | ||||
|  | ||||
| def uniquePermutations(permutations: List[(Int, Int)]): List[(Int, Int)] = { | ||||
|   permutations match { | ||||
|     case Nil => Nil | ||||
|     case (a, b)::rest if rest contains(b, a) => uniquePermutations(rest) | ||||
|     case head::rest => head::uniquePermutations(rest) | ||||
|   } | ||||
| } | ||||
|  | ||||
| def uniquePermutations2(permutations: List[(Int, Int)]): List[(Int, Int)] = { | ||||
|   permutations.foldRight(List.empty[(Int, Int)])( | ||||
|     (e, acc) => { | ||||
|       e match { | ||||
|         case (a, b) if acc contains (b, a) => acc | ||||
|         case _ => e::acc | ||||
|       } | ||||
|     } | ||||
|   ) | ||||
| } | ||||
|  | ||||
| val perms = primeSum(10) | ||||
| uniquePermutations(perms) | ||||
| uniquePermutations2(perms) | ||||
							
								
								
									
										22
									
								
								src/Assignment6/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/Assignment6/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| val cities = List("Paris", "London", "Berlin", "Lausanne") | ||||
| val relatives = List("Grandma", "Grandpa", "Aunt Lottie", "Dad") | ||||
| val travellers = List("Pierre-Andre", "Rachel") | ||||
|  | ||||
| def generatePostcards(cities: List[String], relatives: List[String], travellers: List[String]): List[String] = { | ||||
|   for (t <- travellers; | ||||
|        r <- relatives; | ||||
|        c <- cities) yield s"Dear $r, Wish you were here in $c! Love, $t" | ||||
| } | ||||
|  | ||||
| def generatePostcards2(cities: List[String], relatives: List[String], travellers: List[String]): List[String] = { | ||||
|   for (t <- travellers; | ||||
|        r <- relatives; | ||||
|        c <- cities; | ||||
|        if r.startsWith("G")) yield s"Dear $r, Wish you were here in $c! Love, $t" | ||||
| } | ||||
|  | ||||
| val cards: List[String] = generatePostcards(cities, relatives, travellers) | ||||
| println(cards.mkString("\n")) | ||||
|  | ||||
| val cards2: List[String] = generatePostcards2(cities, relatives, travellers) | ||||
| println(cards2.mkString("\n")) | ||||
							
								
								
									
										39
									
								
								src/Assignment6/Ex4.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/Assignment6/Ex4.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| def inCheck(q1: (Int, Int), q2: (Int, Int)) = | ||||
|     q1._1 == q2._1 || // same row | ||||
|     q1._2 == q2._2 || // same column | ||||
|     (q1._1 - q2._1).abs == (q1._2 - q2._2).abs // on diagonal | ||||
|  | ||||
| def isSafe(queen: (Int, Int), queens: List[(Int, Int)]) = | ||||
|     queens forall (q => !inCheck(queen, q)) | ||||
|  | ||||
| def queens(n: Int): List[List[(Int, Int)]] = { | ||||
|     def placeQueens(k: Int): List[List[(Int, Int)]] = | ||||
|         if (k == 0) | ||||
|             List(List()) | ||||
|         else | ||||
|             for { | ||||
|                 queens <- placeQueens(k - 1) | ||||
|                 column <- 1 to n | ||||
|                 queen = (k, column) | ||||
|                 if isSafe(queen, queens) | ||||
|             } yield queen :: queens | ||||
|  | ||||
|     placeQueens(n) | ||||
| } | ||||
|  | ||||
| def printChessBoard(solutions: List[List[(Int, Int)]]): String = { | ||||
|   val sols: List[String] = for ((sol, i) <- solutions.zipWithIndex) yield { | ||||
|     val lines: IndexedSeq[String] = for (y <- 1 to sol.length) yield { | ||||
|       val line: IndexedSeq[String] = { | ||||
|         for (x <- 1 to sol.length) yield { | ||||
|           if (sol contains (y, x)) "♕" else "_" | ||||
|         } | ||||
|       } | ||||
|       line.mkString("|", "|", "|") | ||||
|     } | ||||
|     s"Solution $i:\n" + lines.mkString("\n") | ||||
|   } | ||||
|   sols.mkString("\n\n") | ||||
| } | ||||
|  | ||||
| println(printChessBoard(queens(4))) | ||||
							
								
								
									
										35
									
								
								src/Assignment7/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/Assignment7/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| trait Stack[+A] { | ||||
|     def push[B >: A](elem: B) : Stack[B] = ElemStack(elem, this) | ||||
|     def top: A | ||||
|     def pop: Stack[A] | ||||
| } | ||||
|  | ||||
| case class EmptyStack[+A]() extends Stack[A] { | ||||
|   override def top: A = throw new IndexOutOfBoundsException("Stack is empty") | ||||
|   override def pop: Stack[A] = this | ||||
| } | ||||
|  | ||||
| case class ElemStack[+A](elmt: A, base: Stack[A]) extends Stack[A] { | ||||
|   override def top: A = elmt | ||||
|   override def pop: Stack[A] = base | ||||
|   override def toString: String = elmt.toString + "," + base.toString | ||||
| } | ||||
|  | ||||
| // Construction, pop and toString | ||||
| val a = EmptyStack().push("hello").push("world").push("it's fun").pop | ||||
| assert(a.toString() == "world,hello,EmptyStack()") | ||||
|  | ||||
| // Getting top | ||||
| val b = EmptyStack().push(1).push(3) | ||||
| assert(b.top == 3) | ||||
|  | ||||
| // Variance checks | ||||
| class Foo | ||||
| class Bar extends Foo | ||||
| val c: Stack[Bar] = EmptyStack().push(new Bar()).push(new Bar()) | ||||
| assert(c.top.isInstanceOf[Bar] == true) | ||||
| assert(c.top.isInstanceOf[Foo] == true) | ||||
|  | ||||
| // Variance check 2 | ||||
| val d: Stack[Foo] = EmptyStack().push(new Bar()).push(new Bar()) | ||||
| assert(d.top.isInstanceOf[Foo]) | ||||
							
								
								
									
										9
									
								
								src/Assignment7/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/Assignment7/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| def intsFrom(n: Int): LazyList[Int] = { | ||||
|   n #:: intsFrom(n + 1) | ||||
| } | ||||
|  | ||||
| def primeNumbers(list: LazyList[Int]): LazyList[Int] = { | ||||
|   list.head #:: primeNumbers(list.tail.filter(n => n % list.head != 0)) | ||||
| } | ||||
| val ints: LazyList[Int] = intsFrom(2) | ||||
| primeNumbers(ints).take(10).toList | ||||
							
								
								
									
										12
									
								
								src/Assignment7/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Assignment7/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| def addStream(s1: LazyList[Int], s2: LazyList[Int]): LazyList[Int] = { | ||||
|   s1 zip s2 map (p => p._1 + p._2) | ||||
| } | ||||
|  | ||||
| def fibonacci(): LazyList[Int] = { | ||||
|   0 #:: 1 #:: addStream( | ||||
|     fibonacci(), | ||||
|     fibonacci().tail | ||||
|   ) | ||||
| } | ||||
|  | ||||
| fibonacci().take(10).toList | ||||
							
								
								
									
										19
									
								
								src/Assignment7/Ex4.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/Assignment7/Ex4.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
|  | ||||
| def THRESHOLD: Double = 0.0001 | ||||
|  | ||||
| def sqr(x: Double): Double = x * x | ||||
|  | ||||
| def sqrt_stream(value: Double): LazyList[Double] = { | ||||
|   def helper(target: Double, approx: Double): LazyList[Double] = { | ||||
|     approx #:: helper(target, approx - (sqr(approx) - target) / (2 * approx)) | ||||
|   } | ||||
|   helper(value, value) | ||||
| } | ||||
|  | ||||
| sqrt_stream(2).take(10).toList | ||||
|  | ||||
| def threshold(list: LazyList[Double], thresh: Double) = { | ||||
|   list.zip(list.drop(1)).filter(p => math.abs(p._2 - p._1) < thresh).head._2 | ||||
| } | ||||
|  | ||||
| threshold(sqrt_stream(2), 1e-15) | ||||
							
								
								
									
										26
									
								
								src/Assignment7/Ex5.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/Assignment7/Ex5.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| /* | ||||
| 1 | ||||
| 1 1 | ||||
| 2 1 | ||||
| 1 2 1 1 | ||||
| 1 1 1 2 2 1 | ||||
| 3 1 2 2 1 1 | ||||
| Next : | ||||
| 1 3 1 1 2 2 2 1 | ||||
|  */ | ||||
|  | ||||
| def nextLine(current: List[Int]) : List[Int] = { | ||||
|   current.foldRight(List.empty[(Int, Int)])((x, acc) => { | ||||
|     (x, acc) match { | ||||
|       case (a, p :: rest) if a == p._2 => (p._1 + 1, p._2) :: rest | ||||
|       case _ => (1, x) :: acc | ||||
|     } | ||||
|   }).flatten(p => List(p._1, p._2)) | ||||
| } | ||||
|  | ||||
| def makeSequence(start: List[Int]): LazyList[List[Int]] = { | ||||
|   start #:: makeSequence(nextLine(start)) | ||||
| } | ||||
|  | ||||
| lazy val sequence: LazyList[List[Int]] = makeSequence(List(1)) | ||||
| sequence.take(7).toList | ||||
							
								
								
									
										24
									
								
								src/Assignment8/Ex1.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/Assignment8/Ex1.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| package Assignment8 | ||||
|  | ||||
| import utils.timeVerbose | ||||
|  | ||||
| import scala.collection.parallel.CollectionConverters._ | ||||
|  | ||||
| object Ex1 extends App { | ||||
|   def integrate(a: Double, b: Double, nIntervals: Int, f: (Double => Double)): Double = { | ||||
|     val dx: Double = (b - a) / nIntervals | ||||
|     //val y: Double = (1 until nIntervals).map(i => f(i * dx + a)).sum | ||||
|     //val y: Double = (1 until nIntervals).view.map(i => f(i * dx + a)).sum | ||||
|     val y: Double = (1 until nIntervals).par.map(i => f(i * dx + a)).sum | ||||
|     return (2 * y + f(a) + f(b)) * dx / 2 | ||||
|   } | ||||
|  | ||||
|   println(integrate(1, 2, 500, math.sin)) | ||||
|  | ||||
|   println(integrate(0, 1, 500, math.sin _ compose math.cos)) | ||||
|  | ||||
|   timeVerbose { | ||||
|     val i = integrate(0, 1, math.pow(20, 6).toInt, math.sin) | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										62
									
								
								src/Assignment8/Ex2.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/Assignment8/Ex2.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| package Assignment8 | ||||
|  | ||||
| import net.liftweb.json | ||||
| import net.liftweb.json.DefaultFormats | ||||
|  | ||||
| import java.net.URI | ||||
| import scala.concurrent.duration.Duration | ||||
| import scala.concurrent.{Await, Future} | ||||
| import scala.sys.process._ | ||||
| import scala.util.{Failure, Success} | ||||
|  | ||||
| object Ex2 extends App { | ||||
|   implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global | ||||
|   implicit val formats: DefaultFormats.type = DefaultFormats | ||||
|  | ||||
|   case class Coin(id: String, icon: String, name: String, symbol: String, rank: Int, price: Double, priceBtc: Double, volume: Double, marketCap: Double, availableSupply: Double, totalSupply: Double, fullyDilutedValuation: Double, priceChange1h: Double, priceChange1d: Double, priceChange1w: Double, redditUrl: String, websiteUrl: String, twitterUrl: String, explorers: List[String]) | ||||
|   case class Currency(name: String, rate: Double, symbol: String, imageUrl: String) | ||||
|  | ||||
|   val BITCOIN_TO_USD: String = "https://openapiv1.coinstats.app/coins/bitcoin" | ||||
|   val USD_TO_CHF: String = "https://openapiv1.coinstats.app/fiats" | ||||
|   private val API_KEY: String = sys.env.getOrElse("OPENAPI_KEY", "") | ||||
|  | ||||
|   def getUrl(url: String): Future[String] = { | ||||
|     Future { | ||||
|       val uri: URI = new URI(url) | ||||
|       val cmd: String = "curl -s -H 'X-API-KEY: " + API_KEY + "' " + uri.toString | ||||
|       cmd.!! | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def extractBitcoinToUSDRate(jsonStr: String): Double = { | ||||
|     val data: Coin = json.parse(jsonStr).extract[Coin] | ||||
|     return data.price | ||||
|   } | ||||
|  | ||||
|   def extractUSDToCHFRate(jsonStr: String): Double = { | ||||
|     val data: List[Currency] = json.parse(jsonStr).extract[List[Currency]] | ||||
|     return data.find(currency => currency.name == "CHF") | ||||
|                .map(currency => currency.rate) | ||||
|                .get | ||||
|   } | ||||
|  | ||||
|   def getBitcoinToUSD: Future[Double] = { | ||||
|     getUrl(BITCOIN_TO_USD) map extractBitcoinToUSDRate | ||||
|   } | ||||
|  | ||||
|   def getUSDToCHF: Future[Double] = { | ||||
|     getUrl(USD_TO_CHF) map extractUSDToCHFRate | ||||
|   } | ||||
|  | ||||
|   val f: Future[Double] = for { | ||||
|     btc2usd <- getBitcoinToUSD | ||||
|     usd2chf <- getUSDToCHF | ||||
|   } yield btc2usd * usd2chf | ||||
|  | ||||
|   f onComplete { | ||||
|     case Success(value) => println(s"1 BTC == $value CHF") | ||||
|     case Failure(e) => println(s"An error occurred: $e") | ||||
|   } | ||||
|  | ||||
|   Await.ready(f, Duration.Inf) | ||||
| } | ||||
							
								
								
									
										29
									
								
								src/Assignment9/Assignment9.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/Assignment9/Assignment9.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| import Assignment9.Kelvin.kel2cel | ||||
|  | ||||
| import scala.language.implicitConversions | ||||
|  | ||||
|  | ||||
| package object Assignment9 { | ||||
|   sealed trait Temperature { | ||||
|   } | ||||
|  | ||||
|   object Temperature { | ||||
|     implicit def cel2kel(celsius: Celsius): Kelvin = new Kelvin(celsius.value + 273.15) | ||||
|     implicit def kel2cel(kelvin: Kelvin): Celsius = new Celsius(kelvin.value - 273.15) | ||||
|   } | ||||
|  | ||||
|   case class Celsius(value: Double) extends Temperature { | ||||
|     override def toString: String = s"$value°C" | ||||
|   } | ||||
|   object Celsius { | ||||
|     implicit def val2cel(value: Double): Celsius = new Celsius(value) | ||||
|   } | ||||
|  | ||||
|   case class Kelvin(value: Double) extends Temperature { | ||||
|     override def toString: String = s"$value K" | ||||
|   } | ||||
|   object Kelvin { | ||||
|     implicit def kel2cel(value: Double): Kelvin = new Kelvin(value) | ||||
|  | ||||
|   } | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/Assignment9/Ex1.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/Assignment9/Ex1.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| package Assignment9 | ||||
|  | ||||
| import scala.language.implicitConversions | ||||
|  | ||||
| object Ex1 extends App { | ||||
|   val a: Celsius = 30 | ||||
|   val b: Kelvin = 30 | ||||
|   val c: Kelvin = Celsius(10) | ||||
|   val d: Celsius = c | ||||
|   val e: Temperature = d | ||||
|  | ||||
|   println(a) // Should print "30°C" | ||||
|   println(b) // Should print "30 K" | ||||
|  | ||||
|   println() | ||||
| } | ||||
							
								
								
									
										36
									
								
								src/Final1/Exercise1.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/Final1/Exercise1.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| package exercises | ||||
|  | ||||
| object Exercise1 extends App { | ||||
|   def dup[A](r: List[Int], l: List[A]): List[A] = { | ||||
|     r.zip(l).flatMap(p => { | ||||
|       List.fill(p._1)(p._2) | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   def removeDup[A](l: List[A]): List[A] = { | ||||
|     l match { | ||||
|       case head::tail => { | ||||
|         head::removeDup(tail.filterNot(e => e == head)) | ||||
|       } | ||||
|       case _ => l | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def zip[A, B](first: List[A], second: List[B]): List[(A, B)] = { | ||||
|     first match { | ||||
|       case head1::tail1 => { | ||||
|         second match { | ||||
|           case head2::tail2 => { | ||||
|             (head1, head2)::zip(tail1, tail2) | ||||
|           } | ||||
|           case _ => Nil | ||||
|         } | ||||
|       } | ||||
|       case _ => Nil | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def zipWith[A, B, C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = { | ||||
|     zip(xs, ys).map((p: (A, B)) => f(p._1, p._2)) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										10
									
								
								src/Final1/Exercise2.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/Final1/Exercise2.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| package exercises | ||||
|  | ||||
| object Exercise2 extends App { | ||||
|   def gen(charSet: String, length: Int): List[String] = { | ||||
|     if (length <= 0) List("") | ||||
|     else charSet.toList.flatMap(c => { | ||||
|       gen(charSet, length - 1).map(pwd => c.toString + pwd) | ||||
|     }) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										55
									
								
								src/Final1/Exercise3.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/Final1/Exercise3.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| package exercises | ||||
|  | ||||
| object Exercise3 extends App { | ||||
|   sealed abstract class Tree { | ||||
|     def isMirrorOf(other: Tree): Boolean | ||||
|     def isSymmetric(): Boolean | ||||
|     def computeDepth(): Int = { | ||||
|       this match { | ||||
|         case Empty => 1 | ||||
|         case Node(left, _, right) => 1 + Math.max(left.computeDepth(), right.computeDepth()) | ||||
|       } | ||||
|     } | ||||
|     def traverseBreadthFirst(): List[Int] = { | ||||
|       val depth: Int = computeDepth() | ||||
|       // Construct list of levels | ||||
|       def helper(tree: Tree, curDepth: Int = 0): List[List[Int]] = { | ||||
|         tree match { | ||||
|           // Add empty levels for consistent indices | ||||
|           case Empty => List.fill(depth - curDepth)(List.empty[Int]) | ||||
|           case Node(left, elem, right) => { | ||||
|             val leftList: List[List[Int]] = helper(left, curDepth + 1) | ||||
|             val rightList: List[List[Int]] = helper(right, curDepth + 1) | ||||
|             val res: List[List[Int]] = (0 until depth - curDepth - 1).map(i => { | ||||
|               leftList(i) ::: rightList(i) | ||||
|             }).toList | ||||
|  | ||||
|             // Add this level | ||||
|             List(elem)::res | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       helper(this).flatten | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   case class Node(left: Tree, elem: Int, right: Tree) extends Tree { | ||||
|     def isMirrorOf(other: Tree): Boolean = { | ||||
|       other match { | ||||
|         case Node(left2, _, right2) => (left isMirrorOf right2) && (right isMirrorOf left2) | ||||
|         case _ => false | ||||
|       } | ||||
|     } | ||||
|     def isSymmetric: Boolean = left isMirrorOf right | ||||
|   } | ||||
|  | ||||
|   case object Empty extends Tree { | ||||
|     def isMirrorOf(other: Tree): Boolean = { | ||||
|       other match { | ||||
|         case Empty => true | ||||
|         case _ => false | ||||
|       } | ||||
|     } | ||||
|     def isSymmetric: Boolean = true | ||||
|   } | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/FinalPrep1/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/FinalPrep1/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| def insertion[T](x: T, xs: List[T]): List[List[T]] = { | ||||
|   return (0 to xs.length).map((i: Int) => { | ||||
|     val p = xs.splitAt(i) | ||||
|     p._1 ::: (x :: p._2) | ||||
|   }).toList | ||||
|  | ||||
|   def buildInsertions(x: T, xs: List[T], before: List[T]): List[List[T]] = { | ||||
|     xs match { | ||||
|       case Nil => (before :+ x) :: Nil | ||||
|       case head::tail => (before ::: (x :: xs)) :: buildInsertions(x, tail, before :+ head) | ||||
|     } | ||||
|   } | ||||
|   buildInsertions(x, xs, Nil) | ||||
| } | ||||
|  | ||||
| insertion(1, List(2,3,4)) | ||||
|  | ||||
| def permutation[T](xs: List[T]): List[List[T]] = { | ||||
|   xs match { | ||||
|     case head::tail => permutation(tail) flatMap (perm => insertion(head, perm)) | ||||
|     case _ => List(xs) | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| permutation(List(1,2,3)) | ||||
							
								
								
									
										18
									
								
								src/FinalPrep1/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/FinalPrep1/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| import scala.math.{ceil, min, sqrt} | ||||
|  | ||||
| def fourSquares(n: Int): List[Tuple4[Int, Int, Int, Int]] = { | ||||
|   val tups = for ( | ||||
|     d: Int <- ceil(sqrt(n)).toInt to 0 by -1; | ||||
|     c: Int <- min(d, ceil(sqrt(n - d*d))).toInt to 0 by -1; | ||||
|     b: Int <- min(c, ceil(sqrt(n - d*d - c*c))).toInt to 0 by -1; | ||||
|     a: Int <- min(b, ceil(sqrt(n - d*d - c*c - b*b))).toInt to 0 by -1 | ||||
|     if (a*a + b*b + c*c + d*d == n) | ||||
|   ) yield Tuple4(a, b, c, d) | ||||
|  | ||||
|   tups.toList | ||||
| } | ||||
|  | ||||
| fourSquares(0)  // List(Tuple4(0, 0, 0, 0)) | ||||
| fourSquares(3)  // List(Tuple4(0, 1, 1, 1)) | ||||
| fourSquares(15)  // List(Tuple(1, 1, 2, 3)) | ||||
| fourSquares(88)  // List(Tuple4(0, 4, 6, 6), Tuple4(2, 2, 4, 8)) | ||||
							
								
								
									
										165
									
								
								src/FinalPrep1/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								src/FinalPrep1/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| sealed abstract class Tree { | ||||
|   // Additional | ||||
|   def toTree(indent: String = ""): String = indent | ||||
|   // End | ||||
|   def eval(): Double = { | ||||
|     this match { | ||||
|       case Sum(l, r) => l.eval() + r.eval() | ||||
|       case Var(n) => throw new RuntimeException("Cannot evaluate " + this) | ||||
|       case Const(v) => v | ||||
|       case Power(x, y) => Math.pow(x.eval(), y.eval()) | ||||
|       case Product(x, y) => x.eval() * y.eval() | ||||
|     } | ||||
|   } | ||||
|   def simplify(): Tree = { | ||||
|     this match { | ||||
|       case Sum(Const(v1), Const(v2)) => Const(v1 + v2) | ||||
|       case Sum(l, r) if l == r => Product(Const(2), l) | ||||
|       case Product(_, Const(0)) | Product(Const(0), _) => Const(0) | ||||
|       case Product(v, Const(1)) => v | ||||
|       case Product(Const(1), v) => v | ||||
|       case Product(Const(v1), Const(v2)) => Const(v1 * v2) | ||||
|  | ||||
|       // Additional | ||||
|       case Sum(l, Const(0)) => l | ||||
|       case Sum(Const(0), r) => r | ||||
|       case Product(l, c: Const) => Product(c, l) | ||||
|       case Product(Const(v1), Product(Const(v2), r)) => Product(Const(v1 * v2), r) | ||||
|       case Product(Product(Const(v1), l), Const(v2)) => Product(Const(v1 * v2), l) | ||||
|       case Product(Product(Const(v1), l), Product(Const(v2), r)) => Product(Const(v1 * v2), Product(l, r)) | ||||
|       // End | ||||
|  | ||||
|       case Power(_, Const(0)) => Const(1) | ||||
|       case Power(v, Const(1)) => v | ||||
|       case _ => this | ||||
|     } | ||||
|   } | ||||
|   def fullSimplify(): Tree = { | ||||
|     (this match { | ||||
|       case Sum(l, r) => Sum(l.fullSimplify(), r.fullSimplify()) | ||||
|       case Power(x, y) => Power(x.fullSimplify(), y.fullSimplify()) | ||||
|       case Product(x, y) => Product(x.fullSimplify(), y.fullSimplify()) | ||||
|       case _ => this | ||||
|     }).simplify() | ||||
|   } | ||||
|   def derive(s: String): Tree = { | ||||
|     val simplified = this.fullSimplify() | ||||
|     (simplified match { | ||||
|       case Const(_) => Const(0) | ||||
|       case Product(c: Const, other) => Product(c, other.derive(s)) | ||||
|       case Product(other, c: Const) => Product(other.derive(s), c) | ||||
|       case Sum(l, r) => Sum(l.derive(s), r.derive(s)) | ||||
|  | ||||
|       // Additional | ||||
|       case Product(l, r) => Sum( | ||||
|         Product(l.derive(s), r), | ||||
|         Product(l, r.derive(s)) | ||||
|       ) | ||||
|       case Power(b, Const(e)) => Product(Const(e), Power(b, Const(e - 1))) | ||||
|       case Power(b, e) => Product(Product(e, Power(b, Sum(e, Const(-1)))), e.derive(s)) | ||||
|       case Var(n) if n == s => Const(1) | ||||
|       // End | ||||
|  | ||||
|       case _ => simplified | ||||
|     }).fullSimplify() | ||||
|   } | ||||
| } | ||||
|  | ||||
| case class Sum(l: Tree, r: Tree) extends Tree { | ||||
|   override def toString(): String = | ||||
|     l.toString() + "+" + r.toString() | ||||
|  | ||||
|   // Additional | ||||
|   override def toTree(indent: String = ""): String = { | ||||
|     (indent + "Sum(\n" | ||||
|       + l.toTree(indent + "  ") + ",\n" | ||||
|       + r.toTree(indent + "  ") + "\n" | ||||
|       + indent + ")") | ||||
|   } | ||||
|   // End | ||||
| } | ||||
| case class Var(n: String) extends Tree { | ||||
|   override def toString() = n | ||||
|  | ||||
|   // Additional | ||||
|   override def toTree(indent: String = ""): String = { | ||||
|     indent + "Var(" + n + ")" | ||||
|   } | ||||
|   // End | ||||
| } | ||||
| case class Const(v: Double) extends Tree { | ||||
|   override def toString() = v.toString | ||||
|   // Additional | ||||
|   override def toTree(indent: String = ""): String = { | ||||
|     indent + "Const(" + v + ")" | ||||
|   } | ||||
|   // End | ||||
| } | ||||
| case class Power(x: Tree, y: Tree) extends Tree { | ||||
|   override def toString() = x + "^" + y | ||||
|   // Additional | ||||
|   override def toTree(indent: String = ""): String = { | ||||
|     (indent + "Power(\n" | ||||
|       + x.toTree(indent + "  ") + ",\n" | ||||
|       + y.toTree(indent + "  ") + "\n" | ||||
|       + indent + ")") | ||||
|   } | ||||
|   // End | ||||
| } | ||||
| case class Product(x: Tree, y: Tree) extends Tree { | ||||
|   override def toString() = x + "*" + y | ||||
|   // Additional | ||||
|   override def toTree(indent: String = ""): String = { | ||||
|     (indent + "Sum(\n" | ||||
|       + x.toTree(indent + "  ") + ",\n" | ||||
|       + y.toTree(indent + "  ") + "\n" | ||||
|       + indent + ")") | ||||
|   } | ||||
|   // End | ||||
| } | ||||
|  | ||||
| val p = Product( | ||||
|   Sum( | ||||
|     Const(3), | ||||
|     Const(-3) | ||||
|   ), | ||||
|   Const(10) | ||||
| ) | ||||
|  | ||||
| p.eval() | ||||
| p.fullSimplify() | ||||
|  | ||||
| // 23x^3 + 6x^2 -268x + pi | ||||
| val p = Sum( | ||||
|   Sum( | ||||
|     Sum( | ||||
|       Product( | ||||
|         Power( | ||||
|           Var("x"), | ||||
|           Const(3) | ||||
|         ), | ||||
|         Const(23), | ||||
|       ), | ||||
|       Product( | ||||
|         Const(6), | ||||
|         Power( | ||||
|           Var("x"), | ||||
|           Const(2) | ||||
|         ) | ||||
|       ) | ||||
|     ), | ||||
|     Product( | ||||
|       Const(-268), | ||||
|       Var("x") | ||||
|     ) | ||||
|   ), | ||||
|   Const(Math.PI) | ||||
| ) | ||||
|  | ||||
| p.toTree() | ||||
|  | ||||
| p.derive("x").toTree() | ||||
|  | ||||
| p.derive("x") | ||||
|  | ||||
| // (23x^3 + 6x^2 -268x + pi)' = 69x^2 + 12x - 268 | ||||
							
								
								
									
										19
									
								
								src/Lesson5/Ex5_2.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/Lesson5/Ex5_2.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| def length[A](x: List[A]): Int = { | ||||
|   x.foldRight(0)((elem: A, len: Int) => len + 1) | ||||
| } | ||||
|  | ||||
| def map[A, B](x: List[A], f: A => B): List[B] = { | ||||
|   x.foldRight(List.empty[B])((elem: A, list: List[B]) => f(elem)::list) | ||||
| } | ||||
|  | ||||
| def dup[A](l: List[A]): List[A] = { | ||||
|   l.flatMap(e => List(e, e)) | ||||
| } | ||||
|  | ||||
| def dup2[A](l: List[A]): List[A] = { | ||||
|   l.foldRight(List.empty[A])((e, l) => e::e::l) | ||||
| } | ||||
|  | ||||
| length(1::2::3::4::Nil) | ||||
| map(1::2::3::4::Nil, (x: Int) => x * 2) | ||||
| dup(1::2::3::Nil) | ||||
							
								
								
									
										18
									
								
								src/Lesson6/Comprehension.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/Lesson6/Comprehension.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| (2 to 10).foreach(i => | ||||
|   (2 to 10) | ||||
|     .filter(j => i % j == 0) | ||||
|     .foreach(j => | ||||
|       println(s"$i is an integer multiple of $j") | ||||
|     ) | ||||
| ) | ||||
|  | ||||
| val positions = for ( | ||||
|   col <- 'a' to 'h'; | ||||
|   row <- 1 to 8 | ||||
| ) yield (col, row) | ||||
|  | ||||
| val whites = for ( | ||||
|   col <- 'a' to 'h'; | ||||
|   row <- 1 to 8; | ||||
|   if ((col - 'a' + row) % 2 == 0) | ||||
| ) yield (col, row) | ||||
							
								
								
									
										40
									
								
								src/Lesson6/Ex_6.1.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Lesson6/Ex_6.1.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| def filter[T](func: T => Boolean, list: List[T]): List[T] = { | ||||
|   list match { | ||||
|     case Nil => Nil | ||||
|     case e::rest if func(e) => e::filter(func, rest) | ||||
|     case _::rest => filter(func, rest) | ||||
|   } | ||||
| } | ||||
|  | ||||
| def partition[T](func: T => Boolean, list: List[T]): (List[T], List[T]) = { | ||||
|   list match { | ||||
|     case Nil => (List.empty[T], List.empty[T]) | ||||
|     case e::rest => { | ||||
|       val part = partition(func, rest) | ||||
|       if (func(e)) { | ||||
|         (e::part._1, part._2) | ||||
|       } else { | ||||
|         (part._1, e::part._2) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| def partition[T](func: T => Boolean, list: List[T]): (List[T], List[T]) = { | ||||
|   list.foldRight((List.empty[T], List.empty[T]))( | ||||
|     (e: T, prev: (List[T], List[T])) => { | ||||
|       if (func(e)) { | ||||
|         (e::prev._1, prev._2) | ||||
|       } else { | ||||
|         (prev._1, e::prev._2) | ||||
|       } | ||||
|     } | ||||
|   ) | ||||
| } | ||||
|  | ||||
|  | ||||
| val b = (1 to 10).toList | ||||
|  | ||||
| filter((x: Int) => x % 2 == 0, b) | ||||
|  | ||||
| partition((x: Int) => x % 2 == 0, b) | ||||
							
								
								
									
										29
									
								
								src/Lesson6/Primes.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/Lesson6/Primes.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| def time(f: => Unit => Any): Long = { | ||||
|   val start = System.currentTimeMillis() | ||||
|   f() | ||||
|   val end = System.currentTimeMillis() | ||||
|   end - start | ||||
| } | ||||
|  | ||||
| def timeVerbose(s: String)(f: => Unit => Any): Unit = { | ||||
|   println(s"[$s] Measuring time...") | ||||
|   val duration = time(f) | ||||
|   println(s"[$s] It took ${duration}ms") | ||||
| } | ||||
|  | ||||
| def isPrime(i: Int): Boolean = | ||||
|   i match { | ||||
|     case i if i <= 1 => false | ||||
|     case 2 => true | ||||
|     case _ => !(2 until i).exists(x => i%x == 0) | ||||
|   } | ||||
|  | ||||
| def primeSum(max: Int)(isPrimeFunc: Int => Boolean): List[(Int, Int)] = { | ||||
|   for (i <- (1 to max).toList; | ||||
|        j <- (1 to max).toList; | ||||
|        if isPrimeFunc(i + j)) yield (i, j) | ||||
| } | ||||
|  | ||||
| timeVerbose("Normal Prime"){ | ||||
|   primeSum(1000)(isPrime) | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/Lesson6/Translations.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/Lesson6/Translations.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| val q: List[Int] = List(1, 2, 3) | ||||
| val p: List[Int] = List(4, 5, 6) | ||||
|  | ||||
| // 1. | ||||
| for (x <- q) yield x * 2 | ||||
| q.map(x => x * 2) | ||||
|  | ||||
| // 2. | ||||
| for (x <- q if x != 2) yield x * 2 | ||||
| q.filter(x => x !=2).map(x => x * 2) | ||||
|  | ||||
| // 3. | ||||
| for (x <- q; | ||||
|      y <- p) yield (x, y) | ||||
| q.flatMap(x => p.map(y => (x, y))) | ||||
|  | ||||
| // 4. | ||||
| for (x <- q if (x < 2); | ||||
|      y <- p) yield (x, y) | ||||
| q.filter(x => x < 2).flatMap(x => p.map(y => (x, y))) | ||||
|  | ||||
|  | ||||
| for (x <- 1 to 2; | ||||
|      y <- 'a' to 'b') yield (x, y) | ||||
| (1 to 2).flatMap(x => ('a' to 'b').map(y => (x, y))) | ||||
							
								
								
									
										13
									
								
								src/Lesson6/Tuples.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/Lesson6/Tuples.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| def merge(x: List[Int], y: List[Int]): List[Int] = { | ||||
|   (x, y) match { | ||||
|     case (list, Nil) => list | ||||
|     case (Nil, list) => list | ||||
|     case (e1::rest1, e2::rest2) => | ||||
|       if (e1 < e2) e1::merge(rest1, y) | ||||
|       else e2::merge(x, rest2) | ||||
|   } | ||||
| } | ||||
|  | ||||
| val n1 = List(0, 2, 4, 6) | ||||
| val n2 = List(1, 3, 5, 7) | ||||
| merge(n1, n2) | ||||
							
								
								
									
										12
									
								
								src/Lesson7/Daltons.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Lesson7/Daltons.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| case class Dalton(n: Int) extends Ordered[Dalton] { | ||||
|   //override def compare(that: Dalton): Int = this.n compare that.n | ||||
|   override def compare(that: Dalton): Int = this.n - that.n | ||||
| } | ||||
|  | ||||
| val a = Dalton(2); val b = Dalton(3); val c = Dalton(2) | ||||
|  | ||||
| a < b | ||||
| a > b | ||||
| a == b | ||||
| a == c | ||||
| a >= c | ||||
							
								
								
									
										6
									
								
								src/Lesson7/LazyEvaluation.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/Lesson7/LazyEvaluation.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| val expr = { | ||||
|   val x = {print("x"); 1} | ||||
|   lazy val y = {print("y"); 2} | ||||
|   def z = {print("z"); 3} | ||||
|   z + y + x + z + y + x | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/Lesson7/LazyList.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/Lesson7/LazyList.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| def range(low: Int, high: Int): LazyList[Int] = { | ||||
|   println(s"Calling range with low=$low / high=$high") | ||||
|   if (low >= high) LazyList.empty[Int] | ||||
|   else low #:: range(low + 1, high) | ||||
| } | ||||
|  | ||||
| range(1, 10)(0) | ||||
|  | ||||
| range(1, 10) map (x => x + 1) | ||||
|  | ||||
| (range(1, 10) map (x => x + 1)).toList | ||||
							
								
								
									
										16
									
								
								src/Lesson7/LoggingFactory.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/Lesson7/LoggingFactory.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| trait Logged { | ||||
|   def log(msg: String) | ||||
| } | ||||
|  | ||||
| trait ConsoleLogger extends Logged { | ||||
|   override def log(msg: String) = println("[LOG] " + msg) | ||||
| } | ||||
|  | ||||
| abstract class Person(name: String) | ||||
|  | ||||
| class Customer(n: String) extends Person(n) with Logged { | ||||
|   log(s"Person $n created") | ||||
| } | ||||
|  | ||||
| val a = new Customer("Patrick Jane") with ConsoleLogger | ||||
|  | ||||
							
								
								
									
										25
									
								
								src/Lesson7/Variance.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/Lesson7/Variance.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| class Animal(val name: String, val kind: String) | ||||
| class Cat(name: String) extends Animal(name, "Cat") | ||||
| class Dog(name: String) extends Animal(name, "Dog") | ||||
|  | ||||
| val anim1: Animal = new Animal("Booboo", "Baboon") | ||||
| val cat1 = new Cat("Miaou") | ||||
|  | ||||
| // Standard polymorphism | ||||
| val anim2: Animal = cat1 | ||||
|  | ||||
| val dog1: Dog = new Dog("Choucroute") | ||||
| val anim3: Animal = dog1 | ||||
|  | ||||
| class Container[+A](val elems: List[A]) { | ||||
|   def get(i: Int): A = elems(i) | ||||
|   def put[B >: A](elem: B) = new Container(elem::elems) | ||||
| } | ||||
|  | ||||
| val animalCollection = new Container[Animal](Nil).put(anim1) | ||||
|  | ||||
| val catCollection = new Container[Cat](Nil).put(cat1).put(new Cat("Garfield")) | ||||
|  | ||||
| animalCollection.put(cat1) | ||||
|  | ||||
| val animalCollection2: Container[Animal] = catCollection | ||||
							
								
								
									
										19
									
								
								src/Lesson8/Actors.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/Lesson8/Actors.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| package Lesson8 | ||||
|  | ||||
| import akka.actor.{Actor, ActorSystem, Props} | ||||
|  | ||||
| object Actors extends App { | ||||
|   case class Greetings(who: String) | ||||
|  | ||||
|   class SimplestActor extends Actor { | ||||
|     def receive = { | ||||
|       case Greetings(who) => println(s"Hello $who, pleased to meet you") | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   val system = ActorSystem("MySystem") | ||||
|   val simple_greeter = system.actorOf(Props[SimplestActor]) | ||||
|  | ||||
|   simple_greeter ! Greetings("Dr Who") | ||||
| } | ||||
|  | ||||
							
								
								
									
										18
									
								
								src/Lesson8/Futures.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/Lesson8/Futures.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| package Lesson8 | ||||
|  | ||||
| import scala.concurrent.Future | ||||
| import scala.util.{Failure, Success} | ||||
|  | ||||
| object Futures extends App { | ||||
|   implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global | ||||
|  | ||||
|   val f: Future[Int] = Future { | ||||
|     Thread.sleep(650) | ||||
|     3 + 4 | ||||
|   } | ||||
|  | ||||
|   f onComplete { | ||||
|     case Success(x: Int) => println(s"Computing done, result is $x") | ||||
|     case Failure(ex) => println("Error") | ||||
|   } | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/Lesson9/PimpMyLibrary.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/Lesson9/PimpMyLibrary.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| package Lesson9 | ||||
|  | ||||
| import scala.language.{implicitConversions, postfixOps} | ||||
|  | ||||
| object PimpMyLibrary extends App{ | ||||
|   /*class PimpedString(s: String) { | ||||
|     def increment: String = new String(s.toCharArray.map(_ + 1)) | ||||
|   } | ||||
|  | ||||
|   implicit def str2Pimped(s: String): PimpedString = new PimpedString(s) | ||||
|  | ||||
|   println("Hal" increment)*/ | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										7
									
								
								src/MidTerm1/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/MidTerm1/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| val pi: List[Long] = List(3, 1, 4, 1, 5, 9, 2) | ||||
| val slice: List[Int] = List(4, 1, 5) | ||||
|  | ||||
| pi.indexOfSlice(slice) | ||||
|  | ||||
| //List("Hello", "world", "Scala").foldRight(0)((a, b) => a + b.length) | ||||
| List("Hello", "world", "Scala").foldLeft(0)((a, b) => a + b.length) | ||||
							
								
								
									
										55
									
								
								src/MidTerm1/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/MidTerm1/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| import scala.annotation.tailrec | ||||
|  | ||||
| @tailrec | ||||
| def foldLeft[A, B](list: List[A])(init: B)(f: (B, A) => B): B = { | ||||
|   list match { | ||||
|     case Nil => init | ||||
|     case head::tail => foldLeft(tail)(f(init, head))(f) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @tailrec | ||||
| def dropWhile[T](list: List[T])(predicate: T => Boolean): List[T] = { | ||||
|   list match { | ||||
|     case head::tail if predicate(head) => dropWhile(tail)(predicate) | ||||
|     case _ => list | ||||
|   } | ||||
| } | ||||
|  | ||||
| def predicates[T](list: List[T])(preds: List[T => Boolean]): List[T] = { | ||||
|   list.foldRight(List.empty[T])((e: T, l: List[T]) => { | ||||
|     //if (preds.foldLeft(true)((a, b) => a && b(e))) e::l | ||||
|     if (preds.forall(b => b(e))) e::l | ||||
|     else l | ||||
|   }) | ||||
| } | ||||
|  | ||||
| val l1 = (1 to 10).toList | ||||
| val f1 = ((a: Int) => a % 2 == 0) | ||||
| val f2 = ((a: Int) => a > 5) | ||||
| predicates(l1)(List(f1, f2))  // List(6, 8, 10) | ||||
|  | ||||
| val l2 = ("Hello Scala Echo").toList | ||||
| val f4 = ((a: Char) => a == 'a' || a == 'e' || a == 'o') | ||||
| val f3 = ((a: Char) => !a.isUpper) | ||||
| predicates(l2)(List(f3, f4))  // List('e', 'o', 'a', 'a', 'o') | ||||
|  | ||||
| /* | ||||
| // Better solution | ||||
| def predicates[T](list: List[T])(preds: List[T => Boolean]): List[T] = { | ||||
|   preds.foldLeft(list)((acc, fun) => acc.filter(fun)) | ||||
| } | ||||
| */ | ||||
|  | ||||
| def fixedPoint(f: Int => Int): Int => Int = { | ||||
|   @tailrec | ||||
|   def func(x: Int): Int = { | ||||
|     val y: Int = f(x) | ||||
|     if (x == y) y | ||||
|     else func(y) | ||||
|   } | ||||
|   func | ||||
| } | ||||
|  | ||||
| fixedPoint(x => if (x % 10 == 0) x else x + 1)(35)  // 40 | ||||
| fixedPoint(x => x / 2 + 5)(20)  // 10 | ||||
							
								
								
									
										37
									
								
								src/MidTerm1/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/MidTerm1/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import scala.annotation.tailrec | ||||
|  | ||||
| abstract class Text { | ||||
|   def isEmpty: Boolean = { | ||||
|     this match { | ||||
|       case Chars(cs) => cs.isEmpty | ||||
|       case Concat(t1, t2) => t1.isEmpty && t2.isEmpty | ||||
|     } | ||||
|   } | ||||
|   def head: Char = { | ||||
|     this match { | ||||
|       case Chars(cs) => cs.head | ||||
|       case Concat(t1, t2) => if (t1.isEmpty) t2.head else t1.head | ||||
|     } | ||||
|   } | ||||
|   def tail: Text = { | ||||
|     this match { | ||||
|       case Chars(cs) => Chars(cs.tail) | ||||
|       case Concat(t1, t2) => if (t1.isEmpty) t2.tail else Concat(t1.tail, t2) | ||||
|     } | ||||
|   } | ||||
|   def map(f: Char => Char): Text = { | ||||
|     this match { | ||||
|       case Chars(cs) => Chars(cs.map(f)) | ||||
|       case Concat(t1, t2) => Concat(t1.map(f), t2.map(f)) | ||||
|     } | ||||
|   } | ||||
| } | ||||
| case class Chars(cs: List[Char]) extends Text | ||||
| case class Concat(t1: Text, t2: Text) extends Text | ||||
|  | ||||
| @tailrec | ||||
| def equals(t1: Text, t2: Text): Boolean = { | ||||
|   if (t1.isEmpty) t2.isEmpty | ||||
|   else if (t2.isEmpty) false | ||||
|   else (t1.head == t2.head) && equals(t1.tail, t2.tail) | ||||
| } | ||||
							
								
								
									
										29
									
								
								src/MidTermPrep1/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/MidTermPrep1/Ex1.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| import scala.annotation.tailrec | ||||
|  | ||||
| def foo(x: Int): Int = { | ||||
|   println("Foo !") | ||||
|   x + 1 | ||||
| } | ||||
|  | ||||
| def bar(x: => Int): Unit = { | ||||
|   println("x1=" + x) | ||||
|   println("x2=" + x) | ||||
| } | ||||
|  | ||||
| bar(foo(3)) | ||||
| // Foo ! | ||||
| // x1=4 | ||||
| // Foo ! | ||||
| // x2=4 | ||||
|  | ||||
|  | ||||
| def toUpper(s: String): String = { | ||||
|   @tailrec | ||||
|   def helper(s: String, res: String): String = { | ||||
|     if (s.isEmpty) res | ||||
|     else helper(s.tail, res + s.head.toUpper) | ||||
|   } | ||||
|   helper(s, "") | ||||
| } | ||||
|  | ||||
| toUpper("hello") | ||||
							
								
								
									
										36
									
								
								src/MidTermPrep1/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/MidTermPrep1/Ex2.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| import scala.annotation.tailrec | ||||
|  | ||||
| def balanceMatch(chars: List[Char]): Boolean = { | ||||
|   @tailrec | ||||
|   def checkStep(chars: List[Char], n: Int): Boolean = { | ||||
|     if (chars.isEmpty) n == 0 | ||||
|     else if (n < 0) false | ||||
|     else checkStep(chars.tail, chars.head match { | ||||
|       case '(' => n + 1 | ||||
|       case ')' => n - 1 | ||||
|       case _ => n | ||||
|     }) | ||||
|   } | ||||
|   checkStep(chars, 0) | ||||
| } | ||||
|  | ||||
| def balanceMatch2(chars: List[Char]): Boolean = { | ||||
|   @tailrec | ||||
|   def checkStep(chars: List[Char], n: Int): Boolean = { | ||||
|     chars match { | ||||
|       case Nil => n == 0 | ||||
|       case _ if n < 0 => false | ||||
|       case '('::rest => checkStep(rest, n + 1) | ||||
|       case ')'::rest => checkStep(rest, n - 1) | ||||
|       case _::rest => checkStep(rest, n) | ||||
|     } | ||||
|   } | ||||
|   checkStep(chars, 0) | ||||
| } | ||||
|  | ||||
| balanceMatch2("(if (x == 0) then max (1, x))".toList) | ||||
| balanceMatch2("I told him (that it's not (yet) done). (But he wasn't listening)".toList) | ||||
| balanceMatch2(")".toList) | ||||
| balanceMatch2("())()".toList) | ||||
| balanceMatch2("())(()".toList) | ||||
| balanceMatch2("(".toList) | ||||
							
								
								
									
										36
									
								
								src/MidTermPrep1/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/MidTermPrep1/Ex3.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| import scala.annotation.tailrec | ||||
|  | ||||
| def countTrue(bools: List[Boolean]): Int = { | ||||
|   bools.foldLeft(0)((n, bool) => if (bool) n + 1 else n) | ||||
| } | ||||
|  | ||||
| countTrue(List(true, true, false, true, false, false)) | ||||
|  | ||||
| def remDup[T](list: List[T]): List[T] = { | ||||
|   list.foldRight(List.empty[T])((elem: T, res: List[T]) => { | ||||
|     if (res.contains(elem)) res | ||||
|     else elem::res | ||||
|   }) | ||||
| } | ||||
|  | ||||
| def remDup2[T](list: List[T]): List[T] = { | ||||
|   list.foldLeft(List.empty[T])((res: List[T], elem: T) => { | ||||
|     if (res.contains(elem)) res | ||||
|     else res :+ elem | ||||
|   }) | ||||
| } | ||||
|  | ||||
| def remDup3[T](list: List[T]): List[T] = { | ||||
|   @tailrec | ||||
|   def helper(list: List[T], distinct: List[T]): List[T] = { | ||||
|     list match { | ||||
|       case head::rest if distinct.contains(head) => helper(rest, distinct) | ||||
|       case head::rest => helper(rest, distinct :+ head) | ||||
|       case Nil => distinct | ||||
|     } | ||||
|   } | ||||
|   helper(list, List.empty[T]) | ||||
| } | ||||
|  | ||||
| remDup(List(5,3,2,4,3,2,3,3)) // List(5,3,2,4) | ||||
| remDup(List("hello", "youpi", "hello", "hello")) // List("hello", "youpi") | ||||
							
								
								
									
										8
									
								
								src/MidTermPrep1/Exercices.sc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/MidTermPrep1/Exercices.sc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| def compress[T](list: List[T]): List[T] = { | ||||
|   list.foldRight(List.empty[T])((elmt: T, res: List[T]) => res match { | ||||
|     case head::_ if head == elmt => res | ||||
|     case _ => elmt::res | ||||
|   }) | ||||
| } | ||||
|  | ||||
| compress(List('a', 'a', 'a', 'a', 'b', 'c', 'c', 'a', 'a', 'd', 'e', 'e', 'e', 'e')) | ||||
							
								
								
									
										57
									
								
								src/utils/package.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/utils/package.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| /** | ||||
|  * Some useful functions for Scala. | ||||
|  * | ||||
|  * @author Pierre-André Mudry | ||||
|  * @version 1.0 | ||||
|  */ | ||||
|  | ||||
| import java.io.{BufferedOutputStream, File, FileOutputStream} | ||||
| import scala.io.{Codec, Source} | ||||
|  | ||||
| package object utils { | ||||
|  | ||||
| 	/** | ||||
| 	 * There are functions for micro-benchmarking, but you should not | ||||
| 	 * rely on those functions for measuring short durations! | ||||
| 	 */ | ||||
|  | ||||
| 	// Measure the time for a block of code to run, approximately | ||||
| 	def timeVerbose(f: ⇒ Unit) = { | ||||
| 		println("[Time] Start of measure") | ||||
| 		val duration = time(f) | ||||
| 		println(s"[Time] Block duration was $duration ms\n") | ||||
| 		duration | ||||
| 	} | ||||
|  | ||||
| 	// With a customized error message | ||||
| 	def timeVerbose(s: String)(f: ⇒ Unit) = { | ||||
| 		println(s"[$s] Start of measure") | ||||
| 		val duration = time(f) | ||||
| 		println(s"[$s] Block duration was $duration ms\n") | ||||
| 		duration | ||||
| 	} | ||||
|  | ||||
| 	// Measure the time for a block of code to run, approximately | ||||
| 	def time(f: ⇒ Unit) = { | ||||
| 		val start = System.currentTimeMillis | ||||
| 		f // Execute the block | ||||
| 		val duration = System.currentTimeMillis - start | ||||
| 		duration | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * A class for reading and writing to files easily | ||||
| 	 */ | ||||
| 	implicit class RichFile(file: File) { | ||||
| 		def read() = Source.fromFile(file)(Codec.UTF8).mkString | ||||
|  | ||||
| 		def write(data: String) { | ||||
| 			val fos = new BufferedOutputStream(new FileOutputStream(file)) | ||||
| 			try { | ||||
| 				fos.write(data.getBytes("UTF-8")) | ||||
| 			} finally { | ||||
| 				fos.close | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user