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 V0.1 |
39 //factorial V0.1 |
|
40 import scala.annotation.tailrec |
|
41 |
40 |
42 |
41 def fact(n: Long): Long = |
43 def fact(n: Long): Long = |
42 if (n == 0) 1 else n * fact(n - 1) |
44 if (n == 0) 1 else n * fact(n - 1) |
43 |
45 |
44 fact(10000) // produces a stackoverflow |
46 fact(10000) // produces a stackoverflow |
45 |
47 |
46 |
48 @tailrec |
47 def factT(n: BigInt, acc: BigInt): BigInt = |
49 def factT(n: BigInt, acc: BigInt): BigInt = |
48 if (n == 0) acc else factT(n - 1, n * acc) |
50 if (n == 0) acc else factT(n - 1, n * acc) |
49 |
51 |
50 |
52 |
51 factT(10000, 1) |
53 println(factT(10000, 1)) |
52 |
54 |
53 // the functions my_contains and factT are tail-recursive |
55 // the functions my_contains and factT are tail-recursive |
54 // you can check this with |
56 // you can check this with |
55 |
57 |
56 import scala.annotation.tailrec |
58 import scala.annotation.tailrec |
78 if (fx.isDefined) fx else first_positive(xs, f) |
80 if (fx.isDefined) fx else first_positive(xs, f) |
79 } |
81 } |
80 } |
82 } |
81 |
83 |
82 |
84 |
|
85 import scala.annotation.tailrec |
|
86 |
83 def search(total: Int, coins: List[Int], cs: List[Int]): Option[List[Int]] = { |
87 def search(total: Int, coins: List[Int], cs: List[Int]): Option[List[Int]] = { |
84 if (total < cs.sum) None |
88 if (total < cs.sum) None |
85 else if (cs.sum == total) Some(cs) |
89 else if (cs.sum == total) Some(cs) |
86 else first_positive(coins, (c: Int) => search(total, coins, c::cs)) |
90 else first_positive(coins, (c: Int) => search(total, coins, c::cs)) |
87 } |
91 } |
96 |
100 |
97 |
101 |
98 import scala.annotation.tailrec |
102 import scala.annotation.tailrec |
99 |
103 |
100 @tailrec |
104 @tailrec |
101 def searchT(total: Int, coins: List[Int], acc_cs: List[List[Int]]): Option[List[Int]] = acc_cs match { |
105 def searchT(total: Int, coins: List[Int], |
|
106 acc_cs: List[List[Int]]): Option[List[Int]] = acc_cs match { |
102 case Nil => None |
107 case Nil => None |
103 case x::xs => |
108 case x::xs => |
104 if (total < x.sum) searchT(total, coins, xs) |
109 if (total < x.sum) searchT(total, coins, xs) |
105 else if (x.sum == total) Some(x) |
110 else if (x.sum == total) Some(x) |
106 else searchT(total, coins, coins.filter(_ > 0).map(_::x) ::: xs) |
111 else searchT(total, coins, coins.filter(_ > 0).map(_::x) ::: xs) |
117 |
122 |
118 |
123 |
119 // Polymorphic Types |
124 // Polymorphic Types |
120 //=================== |
125 //=================== |
121 |
126 |
122 // You do not want to frite functions like contains, first |
127 // You do not want to write functions like contains, first |
123 // and so on for every type of lists. |
128 // and so on for every type of lists. |
124 |
129 |
125 |
130 |
126 def length_int_list(lst: List[Int]): Int = lst match { |
131 def length_string_list(lst: List[String]): Int = lst match { |
127 case Nil => 0 |
132 case Nil => 0 |
128 case x::xs => 1 + length_int_list(xs) |
133 case x::xs => 1 + length_string_list(xs) |
129 } |
134 } |
130 |
135 |
131 length_int_list(List(1, 2, 3, 4)) |
136 length_string_list(List("1", "2", "3", "4")) |
132 |
137 |
133 |
138 |
134 def length[A](lst: List[A]): Int = lst match { |
139 def length[A](lst: List[A]): Int = lst match { |
135 case Nil => 0 |
140 case Nil => 0 |
136 case x::xs => 1 + length(xs) |
141 case x::xs => 1 + length(xs) |
153 //(trees with some content) |
158 //(trees with some content) |
154 |
159 |
155 abstract class Tree[+A] |
160 abstract class Tree[+A] |
156 case class Node[A](elem: A, left: Tree[A], right: Tree[A]) extends Tree[A] |
161 case class Node[A](elem: A, left: Tree[A], right: Tree[A]) extends Tree[A] |
157 case object Leaf extends Tree[Nothing] |
162 case object Leaf extends Tree[Nothing] |
|
163 |
|
164 val t0 = Node('4', Node('2', Leaf, Leaf), Node('7', Leaf, Leaf)) |
158 |
165 |
159 def insert[A](tr: Tree[A], n: A): Tree[A] = tr match { |
166 def insert[A](tr: Tree[A], n: A): Tree[A] = tr match { |
160 case Leaf => Node(n, Leaf, Leaf) |
167 case Leaf => Node(n, Leaf, Leaf) |
161 case Node(m, left, right) => |
168 case Node(m, left, right) => |
162 if (n == m) Node(m, left, right) |
169 if (n == m) Node(m, left, right) |
166 |
173 |
167 |
174 |
168 // the A-type needs to be ordered |
175 // the A-type needs to be ordered |
169 |
176 |
170 abstract class Tree[+A <% Ordered[A]] |
177 abstract class Tree[+A <% Ordered[A]] |
171 case class Node[A <% Ordered[A]](elem: A, left: Tree[A], right: Tree[A]) extends Tree[A] |
178 case class Node[A <% Ordered[A]](elem: A, left: Tree[A], |
|
179 right: Tree[A]) extends Tree[A] |
172 case object Leaf extends Tree[Nothing] |
180 case object Leaf extends Tree[Nothing] |
173 |
181 |
174 |
182 |
175 def insert[A <% Ordered[A]](tr: Tree[A], n: A): Tree[A] = tr match { |
183 def insert[A <% Ordered[A]](tr: Tree[A], n: A): Tree[A] = tr match { |
176 case Leaf => Node(n, Leaf, Leaf) |
184 case Leaf => Node(n, Leaf, Leaf) |
196 abstract class Rexp |
204 abstract class Rexp |
197 case object ZERO extends Rexp |
205 case object ZERO extends Rexp |
198 case object ONE extends Rexp |
206 case object ONE extends Rexp |
199 case class CHAR(c: Char) extends Rexp |
207 case class CHAR(c: Char) extends Rexp |
200 case class ALT(r1: Rexp, r2: Rexp) extends Rexp // alternative r1 + r2 |
208 case class ALT(r1: Rexp, r2: Rexp) extends Rexp // alternative r1 + r2 |
201 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp // sequence r1 r2 |
209 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp // sequence r1 r2 |
202 case class STAR(r: Rexp) extends Rexp // star r* |
210 case class STAR(r: Rexp) extends Rexp // star r* |
203 |
211 |
204 |
212 |
205 // (ab)* |
213 // (ab)* |
206 val r0 = ?? |
214 val r0 = STAR(SEQ(CHAR('a'), CHAR('b'))) |
207 |
215 |
208 |
216 |
209 // some convenience for typing in regular expressions |
217 // some convenience for typing in regular expressions |
210 import scala.language.implicitConversions |
218 import scala.language.implicitConversions |
211 import scala.language.reflectiveCalls |
219 import scala.language.reflectiveCalls |
218 implicit def string2rexp(s: String): Rexp = charlist2rexp(s.toList) |
226 implicit def string2rexp(s: String): Rexp = charlist2rexp(s.toList) |
219 |
227 |
220 |
228 |
221 val r1 = STAR("ab") |
229 val r1 = STAR("ab") |
222 val r2 = STAR("") |
230 val r2 = STAR("") |
223 val r3 = STAR(ALT("ab", "ba")) |
231 val r3 = STAR(ALT("ab", "baa baa black sheep")) |
224 |
|
225 |
232 |
226 implicit def RexpOps (r: Rexp) = new { |
233 implicit def RexpOps (r: Rexp) = new { |
227 def | (s: Rexp) = ALT(r, s) |
234 def | (s: Rexp) = ALT(r, s) |
228 def % = STAR(r) |
235 def % = STAR(r) |
229 def ~ (s: Rexp) = SEQ(r, s) |
236 def ~ (s: Rexp) = SEQ(r, s) |
257 // this is called strict evaluation |
264 // this is called strict evaluation |
258 |
265 |
259 |
266 |
260 def expensiveOperation(n: BigInt): Boolean = expensiveOperation(n + 1) |
267 def expensiveOperation(n: BigInt): Boolean = expensiveOperation(n + 1) |
261 val a = "foo" |
268 val a = "foo" |
262 val b = "foo" |
269 val b = "bar" |
263 |
270 |
264 val test = if ((a == b) || expensiveOperation(0)) true else false |
271 val test = if ((a == b) || expensiveOperation(0)) true else false |
265 |
272 |
266 // this is called lazy evaluation |
273 // this is called lazy evaluation |
267 // you delay compuation until it is really |
274 // you delay compuation until it is really |