Permalink
Browse files

Add more exercises

  • Loading branch information...
julienrf committed Nov 25, 2016
1 parent b6ef557 commit c0b588549cd69b212079c4ce3a4a327b95542acc
@@ -204,7 +204,19 @@ object DefinitionsAndEvaluation extends ScalaTutorialSection {
* corresponding parameter is unused in the evaluation of the function body.
*
* Scala normally uses call-by-value.
*
* = Exercise =
*
* Complete the following definition of the `triangleArea` function,
* which takes a triangle base and height as parameters and returns
* its area:
*/
def nothing(): Unit = ()
def triangleAreaExercise(res0: Double, res1: Double): Unit = {
def triangleArea(base: Double, height: Double): Double =
base * height / res0
triangleArea(3, 4) shouldBe 6
triangleArea(5, 6) shouldBe res1
}
}
@@ -320,14 +320,33 @@ object ImperativeProgramming extends ScalaTutorialSection {
* Example:
*
* {{{
* for (i <- 1 until 3; j <- "abc") println(i + " " + j)
* for (i <- 1 until 3; j <- "abc") println(s"$i $j")
* }}}
*
* translates to:
*
* {{{
* (1 until 3) foreach (i => "abc" foreach (j => println(i + " " + j)))
* (1 until 3) foreach (i => "abc" foreach (j => println(s"$i $j")))
* }}}
*
* = Exercise =
*
* Complete the following imperative implementation of `factorial`:
*/
def nothing(): Unit = ()
def factorialExercise(res0: Int, res1: Int, res2: Int): Unit = {
def factorial(n: Int): Int = {
var result = res0
var i = res1
while (i <= n) {
result = result * i
i = i + res2
}
result
}
factorial(2) shouldBe 2
factorial(3) shouldBe 6
factorial(4) shouldBe 24
factorial(5) shouldBe 120
}
}
@@ -267,6 +267,22 @@ object LexicalScopes extends ScalaTutorialSection {
* {{{
* $ scala Hello
* }}}
*
* = Exercise =
*
*/
def nothing(): Unit = ()
def objectScopes(res0: Int): Unit = {
object Foo {
val x = 1
}
object Bar {
val x = 2
}
object Baz {
import Bar.x
val y = x + Foo.x
}
Baz.y shouldBe res0
}
}
@@ -304,7 +304,7 @@ object ObjectOrientedProgramming extends ScalaTutorialSection {
* a computation model based on substitution. Now we extend this
* model to classes and objects.
*
* How is an instantiation of the class `new C(e1, …, en)` evaluted?
* How is an instantiation of the class `new C(e1, …, en)` evaluated?
*
* The expression arguments `e1, …, en`
* are evaluated like the arguments of a normal function. That's it.
@@ -627,6 +627,35 @@ object ObjectOrientedProgramming extends ScalaTutorialSection {
* val y: String = null // y: String
* val z: Int = null // error: type mismatch
* }}}
*
* = Exercise =
*
* The following `Reducer` abstract class defines how to
* reduce a list of values into a single value by starting
* with an initial value and combining it with each element
* of the list:
*/
def nothing(): Unit = ()
def reducer(res0: Int, res1: Int): Unit = {
abstract class Reducer(init: Int) {
def combine(x: Int, y: Int): Int
def reduce(xs: List[Int]): Int =
xs match {
case Nil => init
case y :: ys => combine(y, reduce(ys))
}
}
object Product extends Reducer(1) {
def combine(x: Int, y: Int): Int = x * y
}
object Sum extends Reducer(0) {
def combine(x: Int, y: Int): Int = x + y
}
val nums = List(1, 2, 3, 4)
Product.reduce(nums) shouldBe res0
Sum.reduce(nums) shouldBe res1
}
}
@@ -419,7 +419,21 @@ object PolymorphicTypes extends ScalaTutorialSection {
*
* - covariant type parameters may appear in lower bounds of method type parameters
* - contravariant type parameters may appear in upper bounds of method
*
* = Exercise =
*
* Complete the following implementation of the `size` function that returns
* the size of a given list.
*/
def nothing(): Unit = ()
def sizeExercise(res0: Int, res1: Int): Unit = {
def size[A](xs: List[A]): Int =
xs match {
case Nil => res0
case y :: ys => res1 + size(ys)
}
size(Nil) shouldBe 0
size(List(1, 2)) shouldBe 2
size(List("a", "b", "c")) shouldBe 3
}
}
@@ -261,21 +261,32 @@ object StandardLibrary extends ScalaTutorialSection {
*
* === Manipulating `Either[A, B]` Values ===
*
* `Either` has `map` and `flatMap`. These methods transform the `Right`
* case only. Way say that `Either` is “right biased”:
* Since Scala 2.12, `Either` has `map` and `flatMap`. These methods
* transform the `Right` case only. Way say that `Either` is “right biased”:
*
* {{{
* Right(1).map((x: Int) => x + 1) shouldBe Right(2)
* Left("foo").map((x: Int) => x + 1) shouldBe Left("foo")
* }}}
*
* `Either` also has a `filterOrElse` method that turn a `Right` value
* `Either` also has a `filterOrElse` method that turns a `Right` value
* into a `Left` value if it does not satisfy a given predicate:
*
* {{{
* Right(1).filterOrElse(x => x % 2 == 0, "Odd value") shouldBe Left("Odd value")
* }}}
*
* However, prior to Scala 2.12, `Either` was “unbiased”. You had to explicitly
* specify which “side” (`Left` or `Right`) you wanted to `map`:
*/
def nothing(): Unit = ()
def either(res0: Either[String, Int], res1: Either[String, Int]): Unit = {
def triple(x: Int): Int = 3 * x
def tripleEither(x: Either[String, Int]): Either[String, Int] =
x.right.map(triple)
tripleEither(Right(1)) shouldBe res0
tripleEither(Left("not a number")) shouldBe res1
}
}
@@ -42,6 +42,9 @@ object StructuringInformation extends ScalaTutorialSection {
* val c3 = Note("C", "Quarter", 3)
* }}}
*
* `c3` is a value that aggregates the arguments passed to the `Note`
* constructor.
*
* Then, you can retrieve the information carried by each ''member'' (`name`,
* `duration` and `octave`) by using the dot notation:
*/
@@ -221,6 +224,28 @@ object StructuringInformation extends ScalaTutorialSection {
* {{{
* case class Note(name: String, duration: String, octave: Int) extends Symbol
* }}}
*
* = Exercise =
*
* Consider the following algebraic data type that models note durations.
* Complete the implementation of the function `fractionOfWhole`, which
* takes as parameter a duration and returns the corresponding fraction
* of the `Whole` duration.
*/
def nothing(): Unit = ()
def adts(res0: Double, res1: Double): Unit = {
sealed trait Duration
case object Whole extends Duration
case object Half extends Duration
case object Quarter extends Duration
def fractionOfWhole(duration: Duration): Double =
duration match {
case Whole => 1.0
case Half => res0
case Quarter => res1
}
fractionOfWhole(Half) shouldBe 0.5
fractionOfWhole(Quarter) shouldBe 0.25
}
}
@@ -164,13 +164,23 @@ object TermsAndTypes extends ScalaTutorialSection {
/**
* = Common Types =
*
* - `Int`: 32-bit integers
* - `Double`: 64-bit floating point numbers
* - `Boolean`: boolean values
* - `String`: text
* - `Int`: 32-bit integers (e.g. `1`, `23`, `456`)
* - `Double`: 64-bit floating point numbers (e.g. `1.0`, `2.3`, `4.56`)
* - `Boolean`: boolean values (`true` and `false`)
* - `String`: text (e.g. `"foo"`, `"bar"`)
*
* Note that type names always begin with an upper case.
* Note that type names always begin with an upper case letter.
*
* = Exercise =
*
* Here are some more methods of standard types. Can you guess what they do?
*/
def nothing(): Unit = ()
def moreMethods(res0: String, res1: Boolean, res2: String): Unit = {
16.toHexString shouldBe res0
(0 to 10).contains(10) shouldBe true
(0 until 10).contains(10) shouldBe res1
"foo".drop(1) shouldBe "oo"
"bar".take(2) shouldBe res2
}
}
@@ -16,4 +16,8 @@ class DefinitionsAndEvaluationSpec extends Spec with Checkers {
check(Test.testSuccess(DefinitionsAndEvaluation.areaExercise _, 314.159 :: HNil))
}
def `check triangle area`: Unit = {
check(Test.testSuccess(DefinitionsAndEvaluation.triangleAreaExercise _, 2.0 :: 15.0 :: HNil))
}
}
@@ -8,8 +8,8 @@ import shapeless.HNil
class HigherOrderFunctionsSpec extends Spec with Checkers {
def `check tail rec sum`: Unit = {
check(Test.testSuccess(HigherOrderFunctions.tailRecSum _, 1 :: 0 :: HNil))
}
// def `check tail rec sum`: Unit = {
// check(Test.testSuccess(HigherOrderFunctions.tailRecSum _, 1 :: 0 :: HNil))
// }
}
@@ -12,4 +12,9 @@ class ImperativeProgrammingSpec extends Spec with Checkers {
check(Test.testSuccess(ImperativeProgramming.observationalEquivalence _, 10 :: HNil))
}
// Disabled because property based testing generates numbers that are too expensive too compute
// def `check factorial`: Unit = {
// check(Test.testSuccess(ImperativeProgramming.factorialExercise _, 1 :: 2 :: 1 :: HNil))
// }
}
@@ -12,4 +12,8 @@ class LexicalScopesSpec extends Spec with Checkers {
check(Test.testSuccess(LexicalScopes.scopeRules _, 16 :: HNil))
}
def `check objects scopes`: Unit = {
check(Test.testSuccess(LexicalScopes.objectScopes _, 3 :: HNil))
}
}
@@ -12,6 +12,9 @@ class ObjectOrientedProgrammingSpec extends Spec with Checkers {
check(Test.testSuccess(ObjectOrientedProgramming.dynamicBinding _, false :: true :: HNil))
}
def `check reducer`: Unit = {
check(Test.testSuccess(ObjectOrientedProgramming.reducer _, 24 :: 10 :: HNil))
}
}
@@ -0,0 +1,15 @@
package scalatutorial.sections
import org.scalacheck.Shapeless._
import org.scalaexercises.Test
import org.scalatest.Spec
import org.scalatest.prop.Checkers
import shapeless.HNil
class PolymorphicTypesSpec extends Spec with Checkers {
def `check size`: Unit = {
check(Test.testSuccess(PolymorphicTypes.sizeExercise _, 0 :: 1 :: HNil))
}
}
@@ -12,4 +12,8 @@ class StandardLibrarySpec extends Spec with Checkers {
check(Test.testSuccess(StandardLibrary.insertionSort _, ((_: Int) < (_: Int)) :: List.empty[Int] :: HNil))
}
def `check either`: Unit = {
check(Test.testSuccess(StandardLibrary.either _, (Right[String, Int](3): Either[String, Int]) :: (Left[String, Int]("not a number"): Either[String, Int]) :: HNil))
}
}
@@ -16,6 +16,8 @@ class StructuringInformationSpec extends Spec with Checkers {
check(Test.testSuccess(StructuringInformation.caseClassEquals _, true :: false :: HNil))
}
def `check adts`: Unit = {
check(Test.testSuccess(StructuringInformation.adts _, 0.5 :: 0.25 :: HNil))
}
}
@@ -8,8 +8,8 @@ import shapeless.HNil
class TailRecursionSpec extends Spec with Checkers {
def `check tail recursive factorial`: Unit = {
check(Test.testSuccess(TailRecursion.tailRecFactorial _, 0 :: 1 :: 1 :: HNil))
}
// def `check tail recursive factorial`: Unit = {
// check(Test.testSuccess(TailRecursion.tailRecFactorial _, 0 :: 1 :: 1 :: HNil))
// }
}
@@ -20,4 +20,8 @@ class TermsAndTypesSpec extends Spec with Checkers {
// check(Test.testSuccess(TermsAndTypes.staticTyping _, 10 :: HNil))
// }
def `check more methods`: Unit = {
check(Test.testSuccess(TermsAndTypes.moreMethods _, "10" :: false :: "ba" :: HNil))
}
}

0 comments on commit c0b5885

Please sign in to comment.