34 |
34 |
35 my_contains(1000000, (1 to 1000000).toList) |
35 my_contains(1000000, (1 to 1000000).toList) |
36 my_contains(1000001, (1 to 1000000).toList) |
36 my_contains(1000001, (1 to 1000000).toList) |
37 |
37 |
38 |
38 |
39 //factorial 0.1 |
39 //factorial V0.1 |
40 |
40 |
41 def fact(n: Long): Long = |
41 def fact(n: Long): Long = |
42 if (n == 0) 1 else n * fact(n - 1) |
42 if (n == 0) 1 else n * fact(n - 1) |
43 |
43 |
44 fact(10000) |
44 fact(10000) // produces a stackoverflow |
45 |
45 |
46 |
46 |
47 def factT(n: BigInt, acc: BigInt): BigInt = |
47 def factT(n: BigInt, acc: BigInt): BigInt = |
48 if (n == 0) acc else factT(n - 1, n * acc) |
48 if (n == 0) acc else factT(n - 1, n * acc) |
49 |
49 |
50 |
50 |
51 factT(10000, 1) |
51 factT(10000, 1) |
52 |
52 |
53 // my_contains and factT are tail recursive |
53 // the functions my_contains and factT are tail-recursive |
54 // you can check this with |
54 // you can check this with |
55 |
55 |
56 import scala.annotation.tailrec |
56 import scala.annotation.tailrec |
57 |
57 |
58 // and the annotation @tailrec |
58 // and the annotation @tailrec |
59 |
59 |
60 // for tail-recursive functions the compiler |
60 // for tail-recursive functions the scala compiler |
61 // generates a loop-like code, which does not |
61 // generates loop-like code, which does not need |
62 // to allocate stack-space in each recursive |
62 // to allocate stack-space in each recursive |
63 // call; scala can do this only for tail-recursive |
63 // call; scala can do this only for tail-recursive |
64 // functions |
64 // functions |
65 |
65 |
66 // consider the following "stupid" version of the |
66 // consider the following "stupid" version of the |
67 // coin exchange problem: given some coins and a, |
67 // coin exchange problem: given some coins and a |
68 // total, what is the change can you get |
68 // total, what is the change can you get? |
69 |
69 |
70 val coins = List(4,5,6,8,10,13,19,20,21,24,38,39, 40) |
70 val coins = List(4,5,6,8,10,13,19,20,21,24,38,39,40) |
71 |
71 |
72 def first_positive[B](lst: List[Int], f: Int => Option[B]): Option[B] = lst match { |
72 def first_positive[B](lst: List[Int], f: Int => Option[B]): Option[B] = lst match { |
73 case Nil => None |
73 case Nil => None |
74 case x::xs => |
74 case x::xs => |
75 if (x <= 0) first_positive(xs, f) |
75 if (x <= 0) first_positive(xs, f) |
96 |
96 |
97 |
97 |
98 import scala.annotation.tailrec |
98 import scala.annotation.tailrec |
99 |
99 |
100 @tailrec |
100 @tailrec |
101 def asearch(total: Int, coins: List[Int], acc_cs: List[List[Int]]): Option[List[Int]] = acc_cs match { |
101 def searchT(total: Int, coins: List[Int], acc_cs: List[List[Int]]): Option[List[Int]] = acc_cs match { |
102 case Nil => None |
102 case Nil => None |
103 case x::xs => |
103 case x::xs => |
104 if (total < x.sum) asearch(total, coins, xs) |
104 if (total < x.sum) searchT(total, coins, xs) |
105 else if (x.sum == total) Some(x) |
105 else if (x.sum == total) Some(x) |
106 else asearch(total, coins, coins.filter(_ > 0).map(_::x) ::: xs) |
106 else searchT(total, coins, coins.filter(_ > 0).map(_::x) ::: xs) |
107 } |
107 } |
108 |
108 |
109 val start_acc = coins.filter(_ > 0).map(List(_)) |
109 val start_acc = coins.filter(_ > 0).map(List(_)) |
110 asearch(11, junk_coins, start_acc) |
110 searchT(11, junk_coins, start_acc) |
111 asearch(111, junk_coins, start_acc) |
111 searchT(111, junk_coins, start_acc) |
112 asearch(111111, junk_coins, start_acc) |
112 searchT(111111, junk_coins, start_acc) |
113 |
113 |
114 // moral: whenever a recursive function is resource-critical |
114 // moral: whenever a recursive function is resource-critical |
115 // (i.e. works on large recursion depth), then you need to |
115 // (i.e. works on large recursion depth), then you need to |
116 // write it in tail-recursive fashion |
116 // write it in tail-recursive fashion |
117 |
117 |
118 |
118 |
119 // Polymorphism |
119 // Polymorphic Types |
120 //============== |
120 //=================== |
|
121 |
|
122 // You do not want to frite functions like contains, first |
|
123 // and so on for every type of lists. |
|
124 |
121 |
125 |
122 def length_int_list(lst: List[Int]): Int = lst match { |
126 def length_int_list(lst: List[Int]): Int = lst match { |
123 case Nil => 0 |
127 case Nil => 0 |
124 case x::xs => 1 + length_int_list(xs) |
128 case x::xs => 1 + length_int_list(xs) |
125 } |
129 } |
183 val t2 = Node('b', Node('a', Leaf, Leaf), Node('f', Leaf, Leaf)) |
187 val t2 = Node('b', Node('a', Leaf, Leaf), Node('f', Leaf, Leaf)) |
184 insert(t2, 'e') |
188 insert(t2, 'e') |
185 |
189 |
186 |
190 |
187 |
191 |
188 // Regular expressions - the power of DSLs |
192 // Regular expressions - the power of DSLs in Scala |
189 //========================================= |
193 //================================================== |
190 |
194 |
191 |
195 |
192 abstract class Rexp |
196 abstract class Rexp |
193 case object ZERO extends Rexp |
197 case object ZERO extends Rexp |
194 case object ONE extends Rexp |
198 case object ONE extends Rexp |
195 case class CHAR(c: Char) extends Rexp |
199 case class CHAR(c: Char) extends Rexp |
196 case class ALT(r1: Rexp, r2: Rexp) extends Rexp |
200 case class ALT(r1: Rexp, r2: Rexp) extends Rexp // alternative r1 + r2 |
197 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp |
201 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp // sequence r1 r2 |
198 case class STAR(r: Rexp) extends Rexp |
202 case class STAR(r: Rexp) extends Rexp // star r* |
199 |
203 |
200 |
204 |
201 // (ab)* |
205 // (ab)* |
202 val r0 = ?? |
206 val r0 = ?? |
203 |
207 |