Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
fp2023:lab02 [2023/03/10 19:49]
bogdan.butnariu added solutions
fp2023:lab02 [2024/03/15 10:48] (current)
pdmatei
Line 19: Line 19:
 </​code>​ </​code>​
  
-<​hidden>​ 
-<code scala> 
-def fact (n: Int): Int = { 
-  def aux_fact(n: Int, acc: Int): Int = 
-    if (n == 0) acc 
-    else aux_fact(n - 1, acc * n) 
-  aux_fact(n, 1) 
-} 
-</​code>​ 
-</​hidden>​ 
  
 **2.2.** Implement a tail-recursive function that computes the greatest common divisor of a natural number: **2.2.** Implement a tail-recursive function that computes the greatest common divisor of a natural number:
Line 36: Line 26:
 </​code>​ </​code>​
  
-<​hidden>​ 
-<code scala> 
-def gcd(a: Int, b: Int): Int = 
-  if (b == 0) a 
-  else gcd(b, a % b) 
-</​code>​ 
-</​hidden>​ 
  
 **2.3.** Write a tail-recursive function takes an integer $math[n] and computes the value $math[1 + 2^2 + 3^2 + ... + (n-1)^2 + n^2]. (Hint: use inner functions). **2.3.** Write a tail-recursive function takes an integer $math[n] and computes the value $math[1 + 2^2 + 3^2 + ... + (n-1)^2 + n^2]. (Hint: use inner functions).
Line 49: Line 32:
 def sumSquares(n:​ Int): Int = ??? def sumSquares(n:​ Int): Int = ???
 </​code>​ </​code>​
- 
-<​hidden>​ 
-<code scala> 
-def sumSquares(n:​ Int): Int = { 
-  def powerTwo(n: Int) = n * n 
- 
-  def aux_squares(n:​ Int, acc: Int): Int = 
-    if (n == 0) acc 
-    else aux_squares(n - 1, acc + powerTwo(n)) 
-  aux_squares(n,​ 0) 
-} 
-</​code>​ 
-</​hidden>​ 
  
 **2.4.** Write a function which computes the sum of all natural numbers within a range. Use **two styles** to write this function: direct recursion, and tail recursion. **2.4.** Write a function which computes the sum of all natural numbers within a range. Use **two styles** to write this function: direct recursion, and tail recursion.
Line 68: Line 38:
 def tailSumNats(start:​ Int, stop: Int): Int = ??? def tailSumNats(start:​ Int, stop: Int): Int = ???
 </​code>​ </​code>​
- 
-<​hidden>​ 
-<code scala> 
-def sumNats(start:​ Int, stop: Int): Int = { 
-  if (start > stop) 0 
-  else start + sumNats(start + 1, stop) 
-} 
- 
-def tailSumNats(start:​ Int, stop: Int) = { 
-  def aux(crt: Int, acc: Int): Int = { 
-    if (crt > stop) acc 
-    else aux(crt + 1, acc + crt) 
-  } 
-  aux(start, 0) 
-} 
-</​code>​ 
-</​hidden>​ 
  
 **2.5.** (!) Write a function which takes an initial value $math[x] and a range of values $math[x_0, x_1, \ldots, x_n] and computes $math[((x - x_0) - x_1) - \ldots x_n]. Use the most appropriate **type of recursion** for this task. **2.5.** (!) Write a function which takes an initial value $math[x] and a range of values $math[x_0, x_1, \ldots, x_n] and computes $math[((x - x_0) - x_1) - \ldots x_n]. Use the most appropriate **type of recursion** for this task.
Line 91: Line 44:
 def subtractRange(x:​ Int, start: Int, stop: Int): Int = ??? def subtractRange(x:​ Int, start: Int, stop: Int): Int = ???
 </​code>​ </​code>​
- 
-<​hidden>​ 
-<code scala> 
-def subtractRange1(x:​ Int, start: Int, stop: Int): Int = { 
-  def loop(i: Int, acc: Int): Int =  
-    if (i > stop) 0 
-    else loop(i+1, acc - i) 
-  loop(start,​x) 
-} 
-</​code>​ 
-</​hidden>​ 
  
 **2.6.** (!) Write a function which takes an initial value $math[x] and a range of values $math[x_0, x_1, \ldots, x_n] and computes $math[x_0 - (x_1 - (x_2 - (\ldots - (x_n - x)\ldots )]. Use the most appropriate **type of recursion** for this task. **2.6.** (!) Write a function which takes an initial value $math[x] and a range of values $math[x_0, x_1, \ldots, x_n] and computes $math[x_0 - (x_1 - (x_2 - (\ldots - (x_n - x)\ldots )]. Use the most appropriate **type of recursion** for this task.
  
-<​hidden>​ 
-<code scala> 
-def subtractRange2(x:​ Int, start: Int, stop: Int): Int = { 
-  if (start > stop) x 
-  else start - subtractRange2(x,​ start + 1, stop) 
-} 
-</​code>​ 
-</​hidden>​ 
  
 ===== Newton'​s Square Root method ===== ===== Newton'​s Square Root method =====
Line 124: Line 58:
 def improve(xn: Double, a: Double): Double = ??? def improve(xn: Double, a: Double): Double = ???
 </​code>​ </​code>​
- 
-<​hidden>​ 
-<code scala> 
-def improve(xn: Double, a: Double): Double = 
-  (1.toDouble / 2) * (xn + a / xn) 
-</​code>​ 
-</​hidden>​ 
  
 **2.5.** Implement the function ''​nthGuess''​ which starts with $math[x_0 = 1] and computes the nth estimate $math[x_n] of $math[\sqrt{a}]:​ **2.5.** Implement the function ''​nthGuess''​ which starts with $math[x_0 = 1] and computes the nth estimate $math[x_n] of $math[\sqrt{a}]:​
Line 136: Line 63:
 def nth_guess(n:​ Int, a: Double): Double = ??? def nth_guess(n:​ Int, a: Double): Double = ???
 </​code>​ </​code>​
- 
-<​hidden>​ 
-<code scala> 
-def nth_guess(n:​ Int, a: Double): Double = { 
-  def aux(n: Int, xn: Double): Double = 
-    if (n == 0) xn 
-    else aux(n - 1, improve(xn, a)) 
-  aux(n, 1) 
-} 
-</​code>​ 
-</​hidden>​ 
  
 Note that: Note that:
Line 155: Line 71:
   def acceptable(xn:​ Double, a: Double): Boolean = ???   def acceptable(xn:​ Double, a: Double): Boolean = ???
 </​code>​ </​code>​
- 
-<​hidden>​ 
-<code scala> 
-def acceptable(xn:​ Double, a: Double): Boolean = 
-  (xn * xn - a).abs <= 0.001 
-</​code>​ 
-</​hidden>​ 
  
 **2.7.** Implement the function ''​mySqrt''​ which computes the square root of an integer ''​a''​. Modify the previous implementations to fit the following code structure: **2.7.** Implement the function ''​mySqrt''​ which computes the square root of an integer ''​a''​. Modify the previous implementations to fit the following code structure:
Line 174: Line 83:
 } }
 </​code>​ </​code>​
- 
-<​hidden>​ 
-<code scala> 
-def mySqrt(a: Double): Double = { 
-  def improve(xn: Double): Double = (1.toFloat / 2) * (xn + a / xn) 
- 
-  def acceptable(xn:​ Double): Boolean = (xn * xn - a).abs <= 0.001 
- 
-  def tailSqrt(estimate:​ => Double): Double = 
-    if (acceptable(estimate)) estimate 
-    else tailSqrt(improve(estimate)) 
- 
-  tailSqrt(1) 
-} 
-</​code>​ 
-</​hidden>​ 
  
 **2.8. (!) **  Try out your code for: ''​2.0e50''​ (which is $math[2.0\cdot 10^{50}]) or ''​2.0e-50''​. The code will likely take a very long time to finish. The reason is that $math[xn^2 - a] will suffer from rounding error which may be larger than 0.001. Can you find a different implementation for the function ''​acceptable''​ which takes that into account? (Hint: the code is just as simple as the original one).  **2.8. (!) **  Try out your code for: ''​2.0e50''​ (which is $math[2.0\cdot 10^{50}]) or ''​2.0e-50''​. The code will likely take a very long time to finish. The reason is that $math[xn^2 - a] will suffer from rounding error which may be larger than 0.001. Can you find a different implementation for the function ''​acceptable''​ which takes that into account? (Hint: the code is just as simple as the original one). 
  
-<​hidden>​ 
-<code scala> 
-def acceptableGood(xn:​ Double): Boolean =  
-  (xn * xn/a - 1).abs <= 0.001 
-</​code>​ 
-</​hidden>​