Challenge Two
Instructions
## Test #2: Implement code in each ChallengeProblems.scala to pass the tests
In the /exercises/ChallengeTests package, you'll find
tests for every challenge in ChallengeProblems.scala. Implement code with passing tests before
moving on to the next challenge. There are 12 challenges total.
*Note- Make sure to name each function with the name you find in the tests
*Additional Note - Uncomment test cases one at a time to run the tests
Now we’re speaking my language, time to write some code to pass some tests.
Test One
describe("Challenge One") {
it("Checks if the string returned is the same as the string passed in"){
val input: String = "Hello!"
val expected: String = "Hello!"
val actual = ChallengeProblems.sameString(input)
assert(expected === actual)
}
}
My Solution
def sameString(someString: String): String = {
someString
}
Result: PASS
I did not know how to create methods in scala
.
These feel like a hybrid they’ve got the def
keyword I am familiar with from python
, but required type declarations like Pydantic
, Java
, or Rust
, they write like Node
functions, they don’t require a return
statement like Rust
. The combination of a bunch of pieces from other languages I’ve worked with. Overall I already feel pretty comfortable with them.
I can see how using this syntax would allow you to write very concise methods or functions that fit nicely into the functional paradigm.
Test Two
describe("Challenge Two") {
it("Checks if the string returned is the same as the string passed in"){
val expected: String = "Hello World!"
val actual = ChallengeProblems.helloWorld()
assert(expected === actual)
}
}
My Solution
def helloWorld(): String = "Hello World!"
Result: PASS
Test Three
describe("Challenge Three") {
it("Checks if list size is correct"){
val input:List[Int] = List(1,2,3,4,5,6)
val expected = 6
val actual = ChallengeProblems.listSize(input)
assert(expected === actual)
}
}
My Solution
def listSize(someList: List[Int]): Int = someList.size;
Result: PASS
Test Four
describe("Challenge Four") {
it("Checks if sum is correct"){
val input:Int = 7
val expected = 32
val actual = ChallengeProblems.sumInts(input)
assert(expected === actual)
}
}
Challenge note:
/*
4. Write a function that takes in an int and adds an int that you create within the function and returns the addition of the two together
Note - Your variable must be a val and must be equal to 25
Params - Int
Returns - Int
*/
My Solution
def sumInts(someInt: Int): Int = {
val addition = 25;
someInt + addition;
}
It could have been possible to solve the challenge with:
def sumInts(someInt: Int): Int = someInt + 25;
However, this would not have needed the inclusion of the variable with the val
keyword. Which I had to look up the syntax.
Test Five
describe("Challenge Five") {
it("Uses .map to uppercase everything") {
val input = List("Scala", "is", "dope")
val expected = List("SCALA", "IS", "DOPE")
val actual = ChallengeProblems.upper(input)
assert(expected === actual)
}
}
My Solution
def upper(someList: List[String]): List[String] = someList.map(_.toUpperCase())
Result: PASS
Test Six
describe("Challenge Six") {
it("Checks if filtered out values are correct") {
val input = List(0,-3,13,25)
val expected = List(0,13,25)
val actual = ChallengeProblems.filterNegatives(input)
assert(expected === actual)
}
it("Checks if all negatives, then should be an empty list") {
val input = List(-3,-5,-6)
val expected = List()
val actual = ChallengeProblems.filterNegatives(input)
assert(expected === actual)
}
}
Two test cases. Now we’re getting serious.
My Solution
def filterNegatives(someList: List[Int]): List[Int] = someList.filter(_ > -1);
Result: PASS
So far everything has been around some scala
basics and really emphasizing the functional
paradigm. I’ve already played with functional a fair amount with both Node
and Python
.
Looking at the standard library for scala
it seems like there are many more methods available to create very specific functional solutions.
Test Seven
describe("Challenge Seven") {
it("Checks if words with car in it are kept") {
val input = List("racecar", "cardinal", "dancer")
val expected = List("racecar", "cardinal")
val actual = ChallengeProblems.containsCar(input)
assert(expected === actual)
}
}
My Solution
def containsCar(someList: List[String]): List[String] = someList.filter(_.contains("car"));
Result: PASS
Test Eight
describe("Challenge Eight") {
it("Checks if sum of all ints is correct") {
val input = List(0,23,4,-1,8)
val expected = 34
val actual = ChallengeProblems.sumList(input)
assert(expected === actual)
}
}
My Solution
def sumList(someList: List[Int]): Int = someList.sum;
Result: PASS
I originally wrote:
def sumList(someList: List[Int]): Int = someList.reduceLeft(_ + _);
But IntelliJ told me to replace .reduceLeft(_ + _)
with .sum
. I like that. The method name sum
is more clear than simply performing an aggregation with reduce
.
Test Nine
describe("Challenge Nine") {
it("Returns cat age from human age when passed an int") {
val input = 3
val expected = 12
val actual = ChallengeProblems.catsAge(input)
assert(expected === actual)
}
}
My Solution
def catsAge(someInt: Int): Int = someInt * 4;
Result: PASS
Test Ten
describe("Challenge 10") {
it("Returns the cat age from a human age when passed a Some") {
val input: Option[Int] = Some(4)
val expected: Option[Int] = Some(16)
val actual = ChallengeProblems.catsAgeOption(input)
assert(expected === actual)
}
it("Returns a None when passed a None") {
val input: Option[Int] = None
val expected: Option[Int] = None
val actual = ChallengeProblems.catsAgeOption(input)
assert(expected === actual)
}
}
My Solution
def catsAgeOption(someInt: Option[Int]): Option[Int] = {
if (someInt.isEmpty) return None else return Some(someInt.get * 4);
}
It’s a little gross, but I think it will work.
Result: PASS
Refactor
def catsAgeOption(someInt: Option[Int]): Option[Int] = if (someInt.isEmpty) return None else return Some(someInt.get * 4);
Result: PASS
A little better, little worse. I don’t know any of the scala
best practices. Is it preferred to write one liners, or to break them up to make them readable?
I’ll find out later I’m sure.
Test Eleven
describe("Challenge Eleven") {
it("Checks if minimum value in list is returned") {
val input:List[Int] = List(1,-4,19,10,0)
val expected = -4
val actual = ChallengeProblems.minimum(input)
assert(expected === actual)
}
}
My Solution
def minimum(someList: List[Int]): Int = someList.min;
Result: PASS
Test Twelve
describe("Challenge Twelve") {
it("Checks if minimum is returned") {
val input:List[Option[Int]] = List(Some(1),Some(-4),Some(19),Some(10),Some(-3))
val expected = Some(-4)
val actual = ChallengeProblems.minimumOption(input)
assert(expected === actual)
}
it("Returns a None when passed a None") {
val input:List[Option[Int]] = List(None, None)
val expected = None
val actual = ChallengeProblems.minimumOption(input)
assert(expected === actual)
}
}
My Solution
def minimumOption(someList: List[Option[Int]]): Option[Int] = {
var theReturn: Option[Int] = None;
for (possibleNum <- someList) {
if (possibleNum.isDefined) {
val num = possibleNum.get;
if (num < theReturn) {
theReturn = Some(num);
}
}
}
theReturn;
}
Result: Compile Error
overloaded method value < with alternatives:
(x: Double)Boolean <and>
(x: Float)Boolean <and>
(x: Long)Boolean <and>
(x: Int)Boolean <and>
(x: Char)Boolean <and>
(x: Short)Boolean <and>
(x: Byte)Boolean
cannot be applied to (Option[Int])
if (num < theReturn) {
That makes sense I’m currently comparing an Int
to an Option[Int]
. I need to get the Int
out of theReturn
, but it may not exist. I can probably use .getOrElse()
.
Fix
def minimumOption(someList: List[Option[Int]]): Option[Int] = {
var theReturn: Option[Int] = None;
for (possibleNum <- someList) {
if (possibleNum.isDefined) {
val num = possibleNum.get;
if (num < theReturn.getOrElse(num + 1)) {
theReturn = Some(num);
}
}
}
theReturn;
}
Result: PASS
Meh. The solution passes both tests. I don’t like that it’s a traditional for
loop instead of some snazzy functional solution, but I couldn’t wrap my head around how I could mold a functional method to arrive at this solution.