Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ object HelloWorld {
* More on variable declarations can be found here:
* http://programming-scala.labs.oreilly.com/ch02.html#VariableDeclarationsAndDefinitions
*/
val sayHello: String = "FixMe"
val sayHello: String = "Hello from Scala"


/**
Expand All @@ -45,7 +45,7 @@ object HelloWorld {
* More on method declarations can be found here:
* http://programming-scala.labs.oreilly.com/ch02.html#MethodDeclarationsAndDefinitions
*/
def echo(text: String): String = "FixMe"
def echo(text: String): String = text
}


Expand Down Expand Up @@ -79,7 +79,7 @@ object HelloWorld {
object HelloWorldClassAndObject {
def apply(initialText:String):HelloWorldClassAndObject = {
new HelloWorldClassAndObject {
val text="FixMe"
val text=initialText
}
}
}
Expand All @@ -99,11 +99,11 @@ object HelloWorldWithTraits extends HelloTrait with WorldTrait {
* - combine the 'helloMethod' of HelloTrait and the 'worldMethod' of WorldTrait to create a new message
* - just replacing the FixMe string would of course be cheating :)
*/
def hello:String = "FixMe"
def hello:String = helloMethod + " " + worldMethod
}

trait HelloTrait {
def helloMethod:String = "FixMe"
def helloMethod:String = "Hello"
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! These are the same solutions we had for HelloWorldExercise!

trait WorldTrait {
Expand Down
54 changes: 53 additions & 1 deletion labs/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package org.scalalabs.basic.lab01
import scala.language.implicitConversions
/**
* The goal of this exercise is to get familiar basic OO constructs in scala


*
* Fix the code so that the unit test 'CurrencyExerciseTest' passes.
*
Expand Down Expand Up @@ -40,6 +42,56 @@ import scala.language.implicitConversions
* of type [[org.scalalabs.basic.lab01.CurrencyConverter]]
* - Use the implicit CurrencyConverter to do the conversion.
*/
class Euro {

abstract class Currency(var symbol:String) {}

class Euro(var euro:Int=0, var cents:Int=0) extends Currency("EUR") with Ordered[Euro] {

def inCents: Int = 100*euro + cents

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could have used inCents/fromCents for + to save yourself some mods, but this works too!

def +(other: Euro): Euro = {
val badCents = this.cents+other.cents
val newCents = badCents%100
val newEuro = badCents/100+this.euro+other.euro
new Euro(newEuro, newCents)
}

def *(multiplicand: Int): Euro = {
new Euro(this.euro*multiplicand) + Euro.fromCents(this.cents*multiplicand)
}

// We didn't realize we didn't need all of these...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:(
You did a good job on them, though!

override def >(other: Euro): Boolean = {
if (this.euro > other.euro) true
else if (other.euro > this.euro) false
else this.cents > other.cents
}

def ==(other: Euro): Boolean = {
!(this>other || other>this)
}

override def <(other: Euro): Boolean = {
!(this>other || this==other)
}

override def compare(other: Euro): Int = {
if (this>other) 1
else if (other>this) -1
else 0
}

override def toString = {
if (this.cents == 0) {
this.symbol + ": " + this.euro + ",--"
} else if (this.cents<10) {
this.symbol + ": " + this.euro + "," + "0" + this.cents
} else {
this.symbol + ": " + this.euro + "," + this.cents
}
}
}

object Euro {
def fromCents(c:Int) = new Euro(c/100,c%100)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,44 @@ object CollectionExercise01 {
* Case 3: so it is okay if you want to just give up
*
*/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we struggled for a long time looking for a pattern too, and there isn't one. :(

I think we were supposed to use maps here, instead of cases (since the file is named CollectionExercise), so you might want to check out the given solution.

// We could not find a pattern to the decoding, so we did it the dumb way...
def charConvert(codeChar: Char): Char = codeChar match {
case 'a' => 'y'
case 'b' => 'h'
case 'c' => 'e'
case 'd' => 's'
case 'e' => 'o'
case 'f' => 'c'
case 'g' => 'v'
case 'h' => 'x'
case 'i' => 'd'
case 'j' => 'u'
case 'k' => 'i'
case 'l' => 'g'
case 'm' => 'l'
case 'n' => 'b'
case 'o' => 'k'
case 'p' => 'r'
case 'q' => 'z'
case 'r' => 't'
case 's' => 'n'
case 't' => 'w'
case 'u' => 'j'
case 'v' => 'p'
case 'w' => 'f'
case 'x' => 'm'
case 'y' => 'a'
case 'z' => 'q'
case _ => ' '
}

def deEncode(code: String): String = {
code.toList.map(charConvert).mkString
}

def googleCodeJamGooglerese(lines: String*): Seq[String] = {
error("fix me")
lines.map(deEncode)
}
}
/*========================================================== */
Expand All @@ -49,8 +85,19 @@ object CollectionExercise02 {
* Rewrite the method groupAdultsPerAgeGroup in the ImperativeSample java class
* using a functional approach.
*/

def groupAdultsPerAgeGroup(persons: Seq[Person]): Map[Int, Seq[Person]] = {
error("fix me")
val adults = persons.filter((p: Person) => p.age >= 18)

val nameSorted = adults.sortWith((p1: Person, p2: Person) => p1.name < p2.name)

def addToMap(acc: Map[Int, Seq[Person]], p: Person): Map[Int, Seq[Person]] = {
val key = p.age/10 * 10
val oldValue = acc.getOrElse(key, Seq[Person]())
val newValue = oldValue ++ Seq(p)
acc.updated(key, newValue)
}
nameSorted.foldLeft(Map[Int, Seq[Person]]())(addToMap)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could have been simplified by using groupBy(_.age / 10 * 10) to separate the adults into the different age groups. sortBy(/_.age) is also a bit simpler than sortWith, too. Good use of filter and foldLeft, though!

}
}

Expand All @@ -65,8 +112,7 @@ object CollectionExercise03 {
* checkValuesIncrease(Seq(1,2,2)) == false
*/
def checkValuesIncrease[T <% Ordered[T]](seq: Seq[T]): Boolean =
error("fix me")

seq.distinct.sorted == seq
}
/*========================================================== */

Expand All @@ -76,6 +122,17 @@ object CollectionExercise04 {
* To keep it simple it's ok to use String.split to extract all words of a sentence.
*/
def calcLengthLongestWord(lines: String*): Int = {
error("fix me")
def longestWord(line: String): String = {

def lengthSort(w1: String, w2: String): Boolean = {
if (w1.length() < w2.length()) true
else false
}

val words = line.split(" ").map((s: String) => s.replaceAll("[^a-zA-Z]",""))
words.sortWith(lengthSort).last
}

lines.map(longestWord).sorted.last.length()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ object ListManipulationExercise01 {
*
*/
def firstElementInList[T](l: List[T]): T = {
//buildin
null.asInstanceOf[T]
l.head
}

/**
* Get the sum of all the elements in the list, e.g. sumOfList(List(1,2,3)) = 6.
*/
def sumOfList(l: List[Int]): Int = {
error("fix me")
l.foldLeft(0)((x:Int, y:Int) => x+y)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A commenter on ours pointed out that l.sum also works for this.

}

/**
Expand All @@ -35,7 +34,7 @@ object ListManipulationExercise01 {
* - ... etc
*/
def lastElementInList[T](l: List[T]): T = {
error("fix me")
l.last
}

/**
Expand All @@ -47,7 +46,7 @@ object ListManipulationExercise01 {
* - ... etc
*/
def nthElementInList[T](n: Int, l: List[T]): T = {
error("fix me")
l.drop(n).head

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l(n) probably would have been an easier way to do this. Your solution is very creative, though!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way to do this would have been recursively, returning l.head in the base case (n == 1) and nthElementInList(n-1, l.tail) in the recursive case. But it's pretty excessive unless you feel super functional that day. :)

}

/**
Expand All @@ -59,7 +58,7 @@ object ListManipulationExercise01 {
* - ... etc
*/
def concatLists[T](l1: List[T], l2: List[T]): List[T] = {
error("fix me")
l1++l2
}

/**
Expand All @@ -71,15 +70,15 @@ object ListManipulationExercise01 {
*
*/
def sortList[T <% Ordered[T]](list: List[T]): List[T] = {
error("fix me")
list.sorted
}

/**
* Check whether a given element in a list exists, i.e. elementExists(List("a", "b", "c"), "b") = true
* Again, easy to implement using built-in functionality, but also possible to implement in your own free-style way.
*/
def elementExists[T](l: List[T], e: T): Boolean = {
error("fix me")
l.indexWhere((x: T) => x==e) != -1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again, very creative! l.contains(e) might have been a bit more elegant, though.

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And once again, you could also be really functional and do it recursively!


/**
Expand All @@ -88,7 +87,7 @@ object ListManipulationExercise01 {
* pattern match or some other method.
*/
def oddElements(iList: List[Int]): List[Int] = {
error("fix me")
iList.filter((x: Int) => x%2==1)
}

/**
Expand All @@ -99,7 +98,8 @@ object ListManipulationExercise01 {
* Implement it whatever way suites you best. Hint: it can be done in a neat way using recursion.
*/
def tails[T](l: List[T]): List[List[T]] = {
error("fix me")
if (l.isEmpty) List(l)
else List(l) ++ tails(l.tail)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very neat solution!

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,31 @@ object ListManipulationExercise02 {
* As usual, various ways exist: pattern matching, folding, ...
*/
def maxElementInList(l: List[Int]): Int = {
error("fix me")
l.foldLeft(Int.MinValue)((x: Int, y: Int) => if (x>=y) x else y)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l.max would also work here.

}

/**
* Calculate the sum of the equally position elements
* of the two list
*/
def sumOfTwo(l1: List[Int], l2: List[Int]): List[Int] = {
error("fix me")
var l1padded = l1
var l2padded = l2
if (l1.length < l2.length) {
l1padded = l1.padTo(l2.length, 0)
} else {
l2padded = l2.padTo(l1.length, 0)
}

l1padded.zip(l2padded).map((t: (Int, Int)) => t._1+t._2)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using zipAll instead would have made this simpler. You can give it values that it will use for its own padding.

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also have added the head of both lists and recursed on both tails.


/**
* For this exercise preferably make use of the sumOfTwo
* method above
*/
def sumOfMany(l: List[Int]*): List[Int] = {
error("fix me")
l.foldLeft(List[Int]())((x:List[Int], y:List[Int]) => sumOfTwo(x, y))
}

case class Person(age: Int, firstName: String, lastName: String)
Expand All @@ -38,30 +46,9 @@ object ListManipulationExercise02 {
* may be able to achieve the same functionality as implemented below
* in a one-liner.
*/
def separateTheYoungFromTheOld(persons: List[Person]): List[List[String]] = {
var youngins: ListBuffer[Person] = new ListBuffer[Person]()
var elders: ListBuffer[Person] = new ListBuffer[Person]()
var validYoungNames: ListBuffer[String] = new ListBuffer[String]()
var validOldNames: ListBuffer[String] = new ListBuffer[String]()

for (person <- persons) {
if (person.age < 18) {
youngins += person
} else {
elders += person
}
}

var sortedYoung = youngins.toList.sortBy(_.age)
var sortedOld = elders.toList.sortBy(_.age)

for (young <- sortedYoung) {
validYoungNames += young.firstName
}
for (old <- sortedOld) {
validOldNames += old.firstName
}
List(validYoungNames.toList, validOldNames.toList)
def separateTheYoungFromTheOld(persons: List[Person]): List[List[String]] = {
var sePersons = persons.sortBy(_.age).partition((person: Person) => person.age < 18)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function looks very good! I'm a bit iffy about the variable name 'sePersons', though.

List(sePersons._1.map((x: Person) => x.firstName), sePersons._2.map((x: Person) => x.firstName))
}

}
Loading