From ebbbc47d02f38b93f88965b0eaa18ef841453f44 Mon Sep 17 00:00:00 2001 From: Johnathan Ashley Date: Fri, 12 Sep 2014 19:46:00 -0700 Subject: [PATCH 1/6] Finished HelloWorld --- .../org/scalalabs/basic/lab01/HelloWorldExercise.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab01/HelloWorldExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab01/HelloWorldExercise.scala index 14876dd..d011a78 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab01/HelloWorldExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab01/HelloWorldExercise.scala @@ -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" /** @@ -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 } @@ -79,7 +79,7 @@ object HelloWorld { object HelloWorldClassAndObject { def apply(initialText:String):HelloWorldClassAndObject = { new HelloWorldClassAndObject { - val text="FixMe" + val text=initialText } } } @@ -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" } trait WorldTrait { From c8dba729f4fb7ccf7d2522593b55ce2c3a5761b4 Mon Sep 17 00:00:00 2001 From: Johnathan Ashley Date: Fri, 12 Sep 2014 21:20:47 -0700 Subject: [PATCH 2/6] Finished Lab 1 and a few Optional ones --- .../scalalabs/basic/lab01/OOExercise.scala | 54 +++++++++++++- .../basic/lab01/OOExerciseTest.scala | 70 ++++++++----------- 2 files changed, 83 insertions(+), 41 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala index a5424c4..ec78249 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab01/OOExercise.scala @@ -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 + + 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... + 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) } \ No newline at end of file diff --git a/labs/src/test/scala/org/scalalabs/basic/lab01/OOExerciseTest.scala b/labs/src/test/scala/org/scalalabs/basic/lab01/OOExerciseTest.scala index 5b15d36..16796f9 100644 --- a/labs/src/test/scala/org/scalalabs/basic/lab01/OOExerciseTest.scala +++ b/labs/src/test/scala/org/scalalabs/basic/lab01/OOExerciseTest.scala @@ -9,65 +9,55 @@ class OOExerciseTest extends Specification { "Exercise 1: Creating an Euro" should { "be initialized correctly" in { - skipped("Uncomment and fix me") - // val e = new Euro(1, 5) - // e.euro ==== 1 - // e.cents ==== 5 - + val e = new Euro(1, 5) + e.euro ==== 1 + e.cents ==== 5 } "have correct default value for cents" in { - skipped("Uncomment and fix me") - // val e = new Euro(2) - // e.euro ==== 2 - // e.cents ==== 0 + val e = new Euro(2) + e.euro ==== 2 + e.cents ==== 0 } "convert amount correctly to cents" in { - skipped("Uncomment and fix me") - // val e = new Euro(2, 45) - // e.inCents ==== 245 + val e = new Euro(2, 45) + e.inCents ==== 245 } "be created by cents" in { - skipped("Uncomment and fix me") - // val e = Euro.fromCents(245) - // e.euro ==== 2 - // e.cents ==== 45 + val e = Euro.fromCents(245) + e.euro ==== 2 + e.cents ==== 45 } "add another euro correctly" in { - skipped("Uncomment and fix me") - // val res = new Euro(1, 50) + new Euro(2, 70) - // res.euro ==== 4 - // res.cents ==== 20 + val res = new Euro(1, 50) + new Euro(2, 70) + res.euro ==== 4 + res.cents ==== 20 } "multiply correctly by a factor" in { - skipped("Uncomment and fix me") - // val res = new Euro(1, 50) * 3 - // res.euro ==== 4 - // res.cents ==== 50 + val res = new Euro(1, 50) * 3 + res.euro ==== 4 + res.cents ==== 50 } } "Exercise 2: an Euro" should { - "be a cubclass of Currency" in { - skipped("Uncomment and fix me") - // val e: Currency = new Euro(2, 5) - // e.symbol ==== "EUR" + "be a subclass of Currency" in { + val e: Currency = new Euro(2, 5) + e.symbol ==== "EUR" } "have correct toString representation" in { - skipped("Uncomment and fix me") - // val e = new Euro(2, 5) - // e.toString ==== "EUR: 2,05" - // val e2 = new Euro(2) - // e2.toString ==== "EUR: 2,--" + val e = new Euro(2, 5) + e.toString ==== "EUR: 2,05" + val e2 = new Euro(2) + e2.toString ==== "EUR: 2,--" } } "OPTIONAL Exercise 3: Euro with Order trait" should { "be correctly orderable" in { - skipped("Uncomment and fix me") - // val e1 = new Euro(1, 5) - // val e2 = new Euro(4, 53) - // val e3 = new Euro(8, 10) - // e3 > e1 must beTrue - // val list = List(e2, e1, e3) - // list.sorted ==== List(e1, e2, e3) + val e1 = new Euro(1, 5) + val e2 = new Euro(4, 53) + val e3 = new Euro(8, 10) + e3 > e1 must beTrue + val list = List(e2, e1, e3) + list.sorted ==== List(e1, e2, e3) } } From 6c02013381c35a24f248167706030fd694ab00c7 Mon Sep 17 00:00:00 2001 From: Johnathan Ashley Date: Sat, 13 Sep 2014 21:31:04 -0700 Subject: [PATCH 3/6] Finished ListManipulation 1 and 2 --- .../lab02/ListManipulationExercise01.scala | 20 +++--- .../lab02/ListManipulationExercise02.scala | 64 +++++++++++-------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise01.scala b/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise01.scala index 85734ae..2d95bc7 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise01.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise01.scala @@ -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) } /** @@ -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 } /** @@ -59,7 +58,7 @@ object ListManipulationExercise01 { * - ... etc */ def concatLists[T](l1: List[T], l2: List[T]): List[T] = { - error("fix me") + l1++l2 } /** @@ -71,7 +70,7 @@ object ListManipulationExercise01 { * */ def sortList[T <% Ordered[T]](list: List[T]): List[T] = { - error("fix me") + list.sorted } /** @@ -79,7 +78,7 @@ object ListManipulationExercise01 { * 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 } /** @@ -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) } } diff --git a/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala b/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala index 8fffd46..4ecf250 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala @@ -11,7 +11,7 @@ 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) } /** @@ -19,7 +19,15 @@ object ListManipulationExercise02 { * 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) } /** @@ -27,7 +35,7 @@ object ListManipulationExercise02 { * 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) @@ -39,29 +47,33 @@ object ListManipulationExercise02 { * 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) + + var sePersons = persons.sortBy(_.age).partition((person: Person) => person.age < 18) + List(sePersons._1.map((x: Person) => x.firstName), sePersons._2.map((x: Person) => x.firstName)) + +// 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) } } \ No newline at end of file From 41f32a8b4f3a47b552d1c5fd259a8a77b4143098 Mon Sep 17 00:00:00 2001 From: Johnathan Ashley Date: Sun, 14 Sep 2014 12:15:34 -0700 Subject: [PATCH 4/6] Finished collection exercise, started recursion --- .../basic/lab02/CollectionExercise.scala | 67 +++++++++++++++++-- .../lab02/ListManipulationExercise02.scala | 27 +------- .../RecursionPatternMatchingExercise.scala | 4 +- 3 files changed, 66 insertions(+), 32 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala index 7de52fb..dc78317 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab02/CollectionExercise.scala @@ -32,8 +32,44 @@ object CollectionExercise01 { * Case 3: so it is okay if you want to just give up * */ + + // 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) } } @@ -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() } } diff --git a/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala b/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala index 4ecf250..0525371 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab02/ListManipulationExercise02.scala @@ -46,34 +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]] = { - + def separateTheYoungFromTheOld(persons: List[Person]): List[List[String]] = { var sePersons = persons.sortBy(_.age).partition((person: Person) => person.age < 18) List(sePersons._1.map((x: Person) => x.firstName), sePersons._2.map((x: Person) => x.firstName)) - -// 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) } } \ No newline at end of file diff --git a/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala index 643a533..cbea672 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala @@ -29,7 +29,9 @@ object RecursionPatternMatchingExercise { * checkValuesIncrease(Seq(1,2,2)) == false */ def checkValuesIncrease(seq: Seq[Int]): Boolean = { - error("fix me") + if (seq.length < 2) true + else if (seq(0) < seq(1)) checkValuesIncrease(seq.tail) + else false } /** From 1cc5f6be7a6bbf75545e6788079ff64bc6eb0918 Mon Sep 17 00:00:00 2001 From: Johnathan Ashley Date: Sun, 14 Sep 2014 13:19:49 -0700 Subject: [PATCH 5/6] Finished RecursionPatternMatching --- .../RecursionPatternMatchingExercise.scala | 58 +++++++++++++++++-- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala b/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala index cbea672..a875e3c 100644 --- a/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala +++ b/labs/src/main/scala/org/scalalabs/basic/lab03/RecursionPatternMatchingExercise.scala @@ -38,24 +38,52 @@ object RecursionPatternMatchingExercise { * Group Consecutive values * List(1,1,2,3,1,1) -> List(1,1), List(2), List(3), List(1,1) */ + def tailGroupConsecutive[T](acc: List[List[T]], in: List[T]): List[List[T]] = { + if (in.isEmpty) acc + else if (acc.isEmpty || !acc.last.contains(in.head)) { + tailGroupConsecutive(acc ++ List(List(in.head)), in.tail) + } + else { + val newAcc = acc.init ++ List(acc.last ++ List(in.head)) + tailGroupConsecutive(newAcc, in.tail) + } + } + def groupConsecutive[T](in: List[T]): List[List[T]] = { - error("fix me") + tailGroupConsecutive(List[List[T]](), in) } /** * Group Equal values * List(1,1,2,3,1,1) -> List(1,1,1,1), List(2), List(3) */ + def placeInGroup[T](acc: List[List[T]], elem: T): List[List[T]] = { + if (acc.isEmpty) List(List(elem)) + else if (acc.head.contains(elem)) List((acc.head ++ List(elem))) ++ acc.tail + else List(acc.head) ++ placeInGroup(acc.tail, elem) + } + + def tailGroupEquals[T](acc: List[List[T]], in: List[T]): List[List[T]] = { + if (in.isEmpty) acc + else tailGroupEquals(placeInGroup(acc, in.head), in.tail) + } + def groupEquals[T](in: List[T]): List[List[T]] = { - error("fix me") + tailGroupEquals(List[List[T]](), in) } /** * Compress values * List(1,1,2,3,1,1) -> List(1,2,3) */ + def tailCompress[T](acc: List[T], in: List[T]): List[T] = { + if (in.isEmpty) acc + else if (acc.contains(in.head)) tailCompress(acc, in.tail) + else tailCompress(acc ++ List(in.head), in.tail) + } + def compress[T](in: List[T]): List[T] = { - error("fix me") + tailCompress(List[T](), in) } /** @@ -63,23 +91,41 @@ object RecursionPatternMatchingExercise { * List(1,1,2,3,1,1) -> List((4,1),(1,2),(1,3)) */ def amountEqualMembers[T](in: List[T]): List[(Int, T)] = { - error("fix me") + groupEquals(in).map((l: List[T]) => (l.length, l.head)) } /** * Zip multiple lists * List(List(1,2,3), List('A, 'B, 'C), List('a, 'b, 'c)) -> List(List(1, 'A, 'a), List(2, 'B, 'b), List(3, 'C, 'c)) */ + def tailZipMultiple(acc: List[List[_]], in: List[List[_]]): List[List[_]] = { + if (in.isEmpty || in.head.isEmpty) acc + else { + val newAcc = acc ++ List(in.map((l: List[_]) => l.head)) + val newIn = in.map((l: List[_]) => l.tail) + tailZipMultiple(newAcc, newIn) + } + } + def zipMultiple(in: List[List[_]]): List[List[_]] = { - error("fix me") + tailZipMultiple(List[List[_]](), in) } /** * Zip multiple lists with different sizes * List(List(1), List('A, 'B, 'C), List('a, 'b)) -> List(List(1, 'A, 'a)) */ + def tailZipMultipleDiff(acc: List[List[_]], in: List[List[_]]): List[List[_]] = { + if (in.isEmpty || in.map((l:List[_]) => l.isEmpty).contains(true)) acc + else { + val newAcc = acc ++ List(in.map((l: List[_]) => l.head)) + val newIn = in.map((l: List[_]) => l.tail) + tailZipMultipleDiff(newAcc, newIn) + } + } + def zipMultipleWithDifferentSize(in: List[List[_]]): List[List[_]] = { - error("fix me") + tailZipMultipleDiff(List[List[_]](), in) } } From 7c1a5176c6ed2ef0597376e5f4e383cf2da7fac3 Mon Sep 17 00:00:00 2001 From: Andrew Michaud Date: Sun, 14 Sep 2014 13:51:28 -0700 Subject: [PATCH 6/6] Added thoughts on scala --- scala-thoughts.md | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/scala-thoughts.md b/scala-thoughts.md index e69de29..aa121c4 100644 --- a/scala-thoughts.md +++ b/scala-thoughts.md @@ -0,0 +1,48 @@ +Scala thoughts! + +List manipulation was really easy, because it always broke down into some +combination of built-in functions. More generally, anything that broke down +into builtins or builtins and recursion was really nice. + +We really liked the automatic typing of values. It was really convenient to +let Scala figure out the types for us. It also wasn't very annoying when we +did have to annotate things with types - type annotations worked very nicely. + +It was really annoying not to be able to loop over lists, or loop over something +and break out if a case was met. Some of the examples would have been easier +with looping instead of folding or reducing or recursion. Though functional +programming is really nice, this is one of the downsides of it. The limitation +of not having looping constructs is one of the difficult things about Scala, +because you have to work around it with recursion and other functions. + +It's really nice that Scala is functional by default. All of the functional +features were really easy to access and use. + +We also liked the ability to define functions inside other functions, and the +ability to create lambda functions whenever we needed them. + +Though we didn't make use of it, we appreciated that we could use any Java +library we wanted in Scala because they both compile to the JVM. + +It was mildly annoying to have to create lists by wrapping something in List[] +instead of just being able to wrap something in brackets directly (which +Haskell can do, we believe). We think this was done so that square brackets +could be reserved for parameterizing on a type. + +It was mildly annoying to have to use parenthesis to index into lists, and +annoying to have to use special functions to index into tuples. We think +parenthesis indexing was chosen so that bracket notation could be used to +indicate parameterizing on a type for a function. We think the special +functions for tuples are there because they are auto-generated based on the +size of the tuple. Also, because tuples are different than lists in functional +programming and are usually treated differently. + +We would like to better learn how fold/foldl/foldr work, and how to use them +effectively. We know that you can do a lot with fold and feel like we only +scratched the surface in these labs. + +We would like to learn more about the philosophy of Scala and why it was +designed like it was. We have been speculating on why things were designed +like they were, and it would be nice to actually know why choices were made. +We would also like to know how closely our approaches to these examples were in +line with Scala philosophy and proper Scala programming.