Compare commits
6 Commits
966767f58c
...
b18b92fb0b
| Author | SHA1 | Date | |
|---|---|---|---|
|
b18b92fb0b
|
|||
|
e9b68c0913
|
|||
|
bba0ee90d4
|
|||
|
34f88cdf28
|
|||
|
1dc768ae51
|
|||
|
a608a602ad
|
15
README.md
15
README.md
@@ -13,10 +13,12 @@
|
||||
* [Lesson 1 - Evaluation](#lesson-1---evaluation)
|
||||
* [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)
|
||||
* [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)
|
||||
<!-- TOC -->
|
||||
|
||||
|
||||
@@ -41,6 +43,12 @@
|
||||
- Binary tree
|
||||
- Operation precedence
|
||||
|
||||
### Lesson 4 - Lists and pattern matching
|
||||
[Files](src/Lesson4)
|
||||
- List
|
||||
- Pattern matching
|
||||
- Genericity
|
||||
|
||||
## Assignments
|
||||
|
||||
### Assignment 1 - Square root
|
||||
@@ -60,3 +68,10 @@
|
||||
- Int set
|
||||
- Binary tree
|
||||
- Union / intersection / foreach
|
||||
|
||||
### Assignment 4 - Lists and pattern matching
|
||||
[Files](src/Assignment4)
|
||||
- Expression interpreter
|
||||
- Binary tree
|
||||
- List functions
|
||||
- Predicates (any / every)
|
||||
60
src/Assignment4/Ex1_Expressions.sc
Normal file
60
src/Assignment4/Ex1_Expressions.sc
Normal file
@@ -0,0 +1,60 @@
|
||||
sealed abstract class Expr
|
||||
case class Number(n: Int) extends Expr
|
||||
case class Sum(e1: Expr, e2: Expr) extends Expr
|
||||
case class Product(e1: Expr, e2: Expr) extends Expr
|
||||
|
||||
def eval(e: Expr): Int = e match {
|
||||
case Number(n) => n
|
||||
case Sum(e1, e2) => eval(e1) + eval(e2)
|
||||
case Product(e1, e2) => eval(e1) * eval(e2)
|
||||
}
|
||||
|
||||
def show(e: Expr): String = e match {
|
||||
case Number(n) => n.toString
|
||||
case Sum(e1, e2) => show(e1) + " + " + show(e2)
|
||||
case Product(e1, e2) => {
|
||||
val left: String = e1 match {
|
||||
case Sum(e1a, e1b) => "(" + show(e1) + ")"
|
||||
case _ => show(e1)
|
||||
}
|
||||
val right: String = e2 match {
|
||||
case Sum(e2a, e2b) => "(" + show(e2) + ")"
|
||||
case _ => show(e2)
|
||||
}
|
||||
left + " * " + right
|
||||
}
|
||||
}
|
||||
|
||||
val e1: Expr = Sum(Number(1), Sum(Number(2), Number(3)))
|
||||
eval(e1)
|
||||
show(e1)
|
||||
|
||||
val e2: Expr = Sum(
|
||||
Number(2),
|
||||
Product(
|
||||
Number(3),
|
||||
Sum(
|
||||
Number(4),
|
||||
Number(5)
|
||||
)
|
||||
)
|
||||
)
|
||||
eval(e2)
|
||||
show(e2)
|
||||
|
||||
|
||||
val expr0 = Sum(Product(Number(2), Number(3)), Number(4))
|
||||
println("Expr0: " + show(expr0)) // Expr0: 2*3+4
|
||||
assert(eval(expr0) == 10)
|
||||
|
||||
val expr1 = Product(Number(4), Number(12))
|
||||
println("Expr1: " + show(expr1)) // Expr1: 4*12
|
||||
assert(eval(expr1) == 48)
|
||||
|
||||
val expr2 = Product(Sum(Number(2), Number(3)), Number(4))
|
||||
println("Expr2: " + show(expr2)) // Expr2: (2+3)*4
|
||||
assert(eval(expr2) == 20)
|
||||
|
||||
val expr3 = Product(Number(2), Sum(Number(3), Number(4)))
|
||||
println("Expr3: " + show(expr3)) // Expr3: 2*(3+4)
|
||||
assert(eval(expr3) == 14)
|
||||
22
src/Assignment4/Ex2_Trees.sc
Normal file
22
src/Assignment4/Ex2_Trees.sc
Normal file
@@ -0,0 +1,22 @@
|
||||
sealed abstract class BinaryTree
|
||||
case class Leaf(value: Int) extends BinaryTree
|
||||
case class Node(left: BinaryTree, right: BinaryTree) extends BinaryTree
|
||||
|
||||
def leafSum(tree: BinaryTree): Int = {
|
||||
tree match {
|
||||
case Leaf(value) => value
|
||||
case Node(left, right) => leafSum(left) + leafSum(right)
|
||||
}
|
||||
}
|
||||
|
||||
def min(a: Int, b: Int): Int = if (a < b) a else b
|
||||
def smallest(tree: BinaryTree): Int = {
|
||||
tree match {
|
||||
case Leaf(value) => value
|
||||
case Node(left, right) => min(smallest(left), smallest(right))
|
||||
}
|
||||
}
|
||||
|
||||
assert(leafSum(Node(Node(Leaf(3), Leaf(8)), Leaf(5))) == 16)
|
||||
|
||||
assert(smallest(Node(Node(Leaf(3), Leaf(5)), Leaf(-5))) == -5)
|
||||
64
src/Assignment4/Ex3_Lists.sc
Normal file
64
src/Assignment4/Ex3_Lists.sc
Normal file
@@ -0,0 +1,64 @@
|
||||
import scala.annotation.tailrec
|
||||
|
||||
|
||||
// Complexity: O(n)
|
||||
@tailrec
|
||||
def last[T](list: List[T]): T = {
|
||||
if (list.isEmpty) throw new NoSuchElementException()
|
||||
if (list.tail.isEmpty) list.head
|
||||
else last(list.tail)
|
||||
}
|
||||
|
||||
def init[T](list: List[T]): List[T] = {
|
||||
if (list.isEmpty) list
|
||||
else if (list.tail.isEmpty) Nil
|
||||
else list.head::init(list.tail)
|
||||
}
|
||||
|
||||
// Complexity: O(n)
|
||||
def concat[T](l1: List[T], l2: List[T]): List[T] = {
|
||||
if (l1.isEmpty) l2
|
||||
else l1.head::concat(l1.tail, l2)
|
||||
}
|
||||
|
||||
// Complexity: O(n²)
|
||||
def reverse[T](list: List[T]): List[T] = {
|
||||
if (list.isEmpty) Nil
|
||||
else last(list)::reverse(init(list))
|
||||
}
|
||||
|
||||
// Better -> O(n)
|
||||
/*
|
||||
def reverse[T](list: List[T], res: List[T] = Nil): List[T] = {
|
||||
if (list.isEmpty) res
|
||||
else reverse(list.tail, list.head::res)
|
||||
}
|
||||
*/
|
||||
|
||||
def take[T](list: List[T], n: Int): List[T] = {
|
||||
if (list.isEmpty || n <= 0) Nil
|
||||
else list.head::take(list.tail, n - 1)
|
||||
}
|
||||
|
||||
@tailrec
|
||||
def drop[T](list: List[T], n: Int): List[T] = {
|
||||
if (list.isEmpty || n <= 0) list
|
||||
else drop(list.tail, n - 1)
|
||||
}
|
||||
|
||||
@tailrec
|
||||
def apply[T](list: List[T], n: Int): T = {
|
||||
if (list.isEmpty) throw new NoSuchElementException()
|
||||
else if (n == 0) list.head
|
||||
else 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)
|
||||
24
src/Assignment4/Ex4_Predicates.sc
Normal file
24
src/Assignment4/Ex4_Predicates.sc
Normal file
@@ -0,0 +1,24 @@
|
||||
import scala.annotation.tailrec
|
||||
|
||||
@tailrec
|
||||
def any[T](p: T => Boolean)(l: List[T]): Boolean = {
|
||||
if (l.isEmpty) false
|
||||
else if (p(l.head)) true
|
||||
else any(p)(l.tail)
|
||||
}
|
||||
|
||||
@tailrec
|
||||
def every[T](p: T => Boolean)(l: List[T]): Boolean = {
|
||||
if (l.isEmpty) true
|
||||
else if (!p(l.head)) false
|
||||
else every(p)(l.tail)
|
||||
}
|
||||
|
||||
val a = List(1, 2, 3, 4, 5)
|
||||
assert(!any((x: Int) => x == 12)(a))
|
||||
assert(any((x: Int) => x > 4)(a))
|
||||
|
||||
val a = List(1, 2, 3, 4, 5)
|
||||
val b = List(2, 4, 6, 8, 10)
|
||||
assert(!every((x: Int) => (x % 2) == 0)(a))
|
||||
assert(every((x: Int) => (x % 2) == 0)(b))
|
||||
13
src/Lesson4/Lists.sc
Normal file
13
src/Lesson4/Lists.sc
Normal file
@@ -0,0 +1,13 @@
|
||||
def insert(x: Int, xs: List[Int]): List[Int] = {
|
||||
if (xs.isEmpty) x::Nil
|
||||
else if (x < xs.head) x::xs
|
||||
else xs.head::insert(x, xs.tail)
|
||||
}
|
||||
|
||||
def isort(xs: List[Int]): List[Int] = {
|
||||
if (xs.isEmpty) Nil
|
||||
else insert(xs.head, isort(xs.tail))
|
||||
}
|
||||
|
||||
|
||||
isort(7::3::9::2::Nil)
|
||||
35
src/Lesson4/PatternMatching.sc
Normal file
35
src/Lesson4/PatternMatching.sc
Normal file
@@ -0,0 +1,35 @@
|
||||
def patFoo(value: Any): Boolean = {
|
||||
value match {
|
||||
case a: Int => a % 4 == 0
|
||||
case c: Char => c.isUpper
|
||||
case b: Boolean => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Expr
|
||||
case class Number(n: Int) extends Expr
|
||||
case class Sum(e1: Expr, e2: Expr) extends Expr
|
||||
|
||||
def eval(e: Expr): Int = e match {
|
||||
case Number(n) => n
|
||||
case Sum(e1, e2) => eval(e1) + eval(e2)
|
||||
}
|
||||
|
||||
def show(e: Expr): String = e match {
|
||||
case Number(n) => n.toString
|
||||
case Sum(e1, e2) => "(" + show(e1) + " + " + show(e2) + ")"
|
||||
}
|
||||
|
||||
patFoo(23)
|
||||
patFoo(24)
|
||||
patFoo('a')
|
||||
patFoo('A')
|
||||
patFoo(false)
|
||||
patFoo(true)
|
||||
patFoo("Hello")
|
||||
patFoo(null)
|
||||
|
||||
val e: Expr = Sum(Number(3), Sum(Number(4), Number(5)))
|
||||
eval(e)
|
||||
show(e)
|
||||
4
src/Lesson4/Types.sc
Normal file
4
src/Lesson4/Types.sc
Normal file
@@ -0,0 +1,4 @@
|
||||
val a: String = "Hell" + "o" * 50
|
||||
def b(s: String): String = "Hell" + s
|
||||
|
||||
a == b("o" * 50)
|
||||
Reference in New Issue
Block a user