Skip to content

Commit

Permalink
Change exercises
Browse files Browse the repository at this point in the history
- All exercises share the same `sbt` build definition
- Exercises 2 demonstrates a use case for `cmtc pull-template`
  • Loading branch information
eloots committed Aug 29, 2023
1 parent c4d271c commit b196ead
Show file tree
Hide file tree
Showing 32 changed files with 488 additions and 57 deletions.
27 changes: 20 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
*.class
*.log
.bookmark

# Metals/BSP
hypriot.img
collectedLogs/
collectedLogs.zip

# VSCode specific
.vscode
*.code-workspace

# Metals/Bloop/sbt BSP specific
.bloop/
.metals/
.swp
.bsp
metals.sbt

# scala-cli

**/project/metals.sbt
**/.scala-build

# sbt specific
Expand All @@ -29,6 +36,8 @@ project/plugins/project/
.classpath
.project
.settings/
.cache-main
.cache-tests

# Intellij specific
*.iml
Expand All @@ -40,4 +49,8 @@ project/plugins/project/
*.sublime-workspace

# OS specific
.DS_Store
**/.DS_Store
**/__MACOSX

# Other
Preci*.pdf
17 changes: 0 additions & 17 deletions exercises/exercise_001_getting_started/README.md

This file was deleted.

51 changes: 51 additions & 0 deletions exercises/exercise_001_initial_state/.scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version = 3.7.2
runner.dialect = scala3

style = defaultWithAlign
indentOperator.preset = akka
maxColumn = 120
rewrite.rules = [RedundantParens, AvoidInfix]
align.tokens = [{code = "=>", owner = "Case"}]
align.openParenDefnSite = false
align.openParenCallSite = false
optIn.breakChainOnFirstMethodDot = false
optIn.configStyleArguments = false
danglingParentheses.defnSite = false
danglingParentheses.callSite = false
rewrite.neverInfix.excludeFilters = [
and
min
max
until
to
by
eq
ne
"should.*"
"contain.*"
"must.*"
in
ignore
be
taggedAs
thrownBy
synchronized
have
when
size
only
noneOf
oneElementOf
noElementsOf
atLeastOneElementOf
atMostOneElementOf
allElementsOf
inOrderElementsOf
theSameElementsAs
message
]
rewriteTokens = {
"⇒": "=>"
"→": "->"
"←": "<-"
}
17 changes: 17 additions & 0 deletions exercises/exercise_001_initial_state/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Getting started with Scala 3

# Running "Hello World" application

We start with the simplest of simplest program.

Your task is to verify that the program prints
"Hello, world!" on standard out.

# Steps

- In a terminal, cd into the root folder of the
exercise project
- Start an `sbt` session
- Execute the main method by issuing the `run`
command at the `sbt` prompt

4 changes: 4 additions & 0 deletions exercises/exercise_001_initial_state/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scalaVersion := "3.3.0"

libraryDependencies ++=
Seq("org.scalatest" %% "scalatest" % "3.2.16")
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.9.4
1 change: 1 addition & 0 deletions exercises/exercise_001_initial_state/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

@main def main(): Unit =
println(s"Hello, world!")
27 changes: 0 additions & 27 deletions exercises/exercise_002_adding_a_build_definition/README.md

This file was deleted.

3 changes: 0 additions & 3 deletions exercises/exercise_002_adding_a_build_definition/build.sbt

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version = 3.7.2
runner.dialect = scala3

style = defaultWithAlign
indentOperator.preset = akka
maxColumn = 120
rewrite.rules = [RedundantParens, AvoidInfix]
align.tokens = [{code = "=>", owner = "Case"}]
align.openParenDefnSite = false
align.openParenCallSite = false
optIn.breakChainOnFirstMethodDot = false
optIn.configStyleArguments = false
danglingParentheses.defnSite = false
danglingParentheses.callSite = false
rewrite.neverInfix.excludeFilters = [
and
min
max
until
to
by
eq
ne
"should.*"
"contain.*"
"must.*"
in
ignore
be
taggedAs
thrownBy
synchronized
have
when
size
only
noneOf
oneElementOf
noElementsOf
atLeastOneElementOf
atMostOneElementOf
allElementsOf
inOrderElementsOf
theSameElementsAs
message
]
rewriteTokens = {
"⇒": "=>"
"→": "->"
"←": "<-"
}
25 changes: 25 additions & 0 deletions exercises/exercise_002_calculating_with_prime_numbers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Calculating the sum of a series of consecutive prime numbers

Your task is to calculate the sum of all the prime numbers
smaller than 3,000,000

You can write your own Prime number generator, but you can also
use one that is provided by executing the following `cmtc` command
on the command line:

`cmtc pull-template src/main/scala/primes/EratosthenesSieve.scala`

Have a look at the provided class and look at
how you can use it to calculate a series of prime
numbers starting from 2 upto a given number.

# Steps

- Create a new object `SumOfPrimes`
- Define a method `sumOfPrimesBelow` with a single parameter
`limit` of type `Int`.
- Implement the method to return the sum of all primes numbers
below `limit`.
- What should the return type of `sumOfPrimesBelow` be?

- Run `test` from the `sbt` prompt and check if all tests pass.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scalaVersion := "3.3.0"

libraryDependencies ++=
Seq("org.scalatest" %% "scalatest" % "3.2.16")
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.9.4
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

@main def main(): Unit =
println(s"Hello, world!")
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package primes

import collection.mutable.ArrayBuffer

/** A memory intensive, but very fast implementation of Eratosthenes' Sieve using a mutable collection
*
* Taken from: https://lombardo-chcg.github.io/code-challenge/2017/10/09/sieve-of-eratosthenes.html
*/

class EratosthenesSieve:
def primesUnder(n: Int): List[Int] =
// Input: an integer n > 1.
if n <= 1 then List()
else {
// Let A be an array of Boolean values, indexed by integers 2 to n, initially all set to true.
val numbers = ArrayBuffer.fill(n + 1)(true)
// for i = 2, 3, 4, ..., not exceeding √n: if A[i] is true:
for (i <- 2 to Math.sqrt(n).toInt if numbers(i)) {
// for j = i2, i2+i, i2+2i, i2+3i, ..., not exceeding n:
for (j <- (i * i) to n by i) {
// A[j] := false.
numbers.update(j, false)
}
}

// Output: all i such that A[i] is true.
(for (m <- numbers.indices if numbers(m)) yield m)
.drop(2) // handling the 'off by 2' problem of the 0th index'ed array
.takeWhile(_ < n)
.toList
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package primes

object Primes {
def sumOfPrimesBelow(limit: Int): BigInt =
val primesBelow = EratosthenesSieve().primesUnder(limit)
primesBelow.foldLeft(BigInt(0)) { case (sum, n) =>
sum + n
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package primes

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class EratosthenesSieveSpec extends AnyFlatSpec with Matchers {
it should "return a list of all primes under a given number" in {
val expected30 = List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29)
val expected100 =
List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97)
val expected1000 = List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487,
491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953,
967, 971, 977, 983, 991, 997)
val primeCalculator = new EratosthenesSieve
primeCalculator.primesUnder(1) should equal(List())
primeCalculator.primesUnder(2) should equal(List())
primeCalculator.primesUnder(3) should equal(List(2))
primeCalculator.primesUnder(4) should equal(List(2, 3))
primeCalculator.primesUnder(30) should equal(expected30)
primeCalculator.primesUnder(100) should equal(expected100)
primeCalculator.primesUnder(1000) should equal(expected1000)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package primes

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class PrimesSpec extends AnyFlatSpec with Matchers {
it should "calculate the correct sum of all primes smaller than 3,000,000" in {
val expectedSum = BigInt("312471072265")
val calculatedSum = Primes.sumOfPrimesBelow(3_000_000)
calculatedSum shouldBe expectedSum
}

it should "calculate the correct sum of all primes smaller than 11" in {
val expectedSum = BigInt("17")
val calculatedSum = Primes.sumOfPrimesBelow(11)
calculatedSum shouldBe expectedSum
}

}
Loading

0 comments on commit b196ead

Please sign in to comment.