Compare commits
	
		
			8 Commits
		
	
	
		
			34b1ff39ce
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b7ca6610fc | |||
| ec0e1e8ae4 | |||
| 5365eabadd | |||
| 43e0694d9d | |||
| c13f9851e3 | |||
| bed771a04e | |||
| 6954695a0d | |||
| a16b70970f | 
							
								
								
									
										41
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								README.md
									
									
									
									
									
								
							| @@ -17,12 +17,22 @@ | |||||||
|     * [Lesson 5 - Advanced lists and High order functions](#lesson-5---advanced-lists-and-high-order-functions) |     * [Lesson 5 - Advanced lists and High order functions](#lesson-5---advanced-lists-and-high-order-functions) | ||||||
|     * [Midterm preparation](#midterm-preparation) |     * [Midterm preparation](#midterm-preparation) | ||||||
|     * [Midterm](#midterm) |     * [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) |   * [Assignments](#assignments) | ||||||
|     * [Assignment 1 - Square root](#assignment-1---square-root) |     * [Assignment 1 - Square root](#assignment-1---square-root) | ||||||
|     * [Assignment 2 - Map-reduce](#assignment-2---map-reduce) |     * [Assignment 2 - Map-reduce](#assignment-2---map-reduce) | ||||||
|     * [Assignment 3 - Binary tree](#assignment-3---binary-tree) |     * [Assignment 3 - Binary tree](#assignment-3---binary-tree) | ||||||
|     * [Assignment 4 - Lists and pattern matching](#assignment-4---lists-and-pattern-matching) |     * [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 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 --> | <!-- TOC --> | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -79,6 +89,23 @@ | |||||||
| - Variance, covariance and contra-variance | - Variance, covariance and contra-variance | ||||||
| - Infinite sequences | - 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 | ## Assignments | ||||||
|  |  | ||||||
| ### Assignment 1 - Square root | ### Assignment 1 - Square root | ||||||
| @@ -118,3 +145,17 @@ | |||||||
| [Files](src/Assignment6) | [Files](src/Assignment6) | ||||||
| - Tuples | - Tuples | ||||||
| - `for` comprehension | - `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 | ||||||
|   | |||||||
							
								
								
									
										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/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)*/ | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										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