-
Notifications
You must be signed in to change notification settings - Fork 23
Assignment 2 - Johnathan Ashley/Andrew Michaud #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ebbbc47
c8dba72
6c02013
41f32a8
1cc5f6b
7c1a517
c840caa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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. | ||
| * | ||
|
|
@@ -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 | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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... | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :( |
||
| 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 |
|---|---|---|
|
|
@@ -32,8 +32,44 @@ object CollectionExercise01 { | |
| * Case 3: so it is okay if you want to just give up | ||
| * | ||
| */ | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
| } | ||
| } | ||
| /*========================================================== */ | ||
|
|
@@ -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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could have been simplified by using |
||
| } | ||
| } | ||
|
|
||
|
|
@@ -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 | ||
| } | ||
| /*========================================================== */ | ||
|
|
||
|
|
@@ -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 |
|---|---|---|
|
|
@@ -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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -35,7 +34,7 @@ object ListManipulationExercise01 { | |
| * - ... etc | ||
| */ | ||
| def lastElementInList[T](l: List[T]): T = { | ||
| error("fix me") | ||
| l.last | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -47,7 +46,7 @@ object ListManipulationExercise01 { | |
| * - ... etc | ||
| */ | ||
| def nthElementInList[T](n: Int, l: List[T]): T = { | ||
| error("fix me") | ||
| l.drop(n).head | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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! There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. :) |
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -59,7 +58,7 @@ object ListManipulationExercise01 { | |
| * - ... etc | ||
| */ | ||
| def concatLists[T](l1: List[T], l2: List[T]): List[T] = { | ||
| error("fix me") | ||
| l1++l2 | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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! |
||
|
|
||
| /** | ||
|
|
@@ -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) | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very neat solution! |
||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
|
|
@@ -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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)) | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
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!