stringscalashortest

Find the shortest word, in a string of words


I am doing a bit of Code-Wars Challenges again and I have a question about this particular one:

Task: " Given a string of words, return the length of the shortest word(s).

String will never be empty and you do not need to account for different data types."

I've looked up the answers available on SO and I've managed to create the program on my own based on foreign ideas.

The problem is it still does not produce the desired output.

I run- through the code and I think the problem lies with the variables, and my inability to assign to correct sections of the code.(although I may be wrong)

So below, I attach the code as well as the tests.

Hope, any of you can find the answer to the problem.

Cheers

object Shortest{
  def findShort(str:String):Int ={

    var smallestLength = 99
    var currentLength = 0

    for(word <- str.split("")) {
      currentLength = 0

      for(letter <- word){
        currentLength +=1
      }

      if(currentLength < smallestLength)
        smallestLength = currentLength         
    }
    smallestLength            
  } 
}

Here are the tests:

Test Results:

ShortestTest findShort(bitcoin take over the world maybe who knows perhaps) should return 3

Test Failed 1 was not equal to 3 Stack Trace Completed in 45ms findShort(turns out random test cases are easier than writing out basic ones) should return 3 Test Failed

1 was not equal to 3 Stack Trace Completed in 1ms findShort(lets talk about javascript the best language) should return 3 Test Failed 1 was not equal to 3 Stack Trace Completed in 1ms findShort(i want to travel the world writing code one day) should return 1 findShort(Lets all go on holiday somewhere very cold) should return 2 Test Failed

1 was not equal to 2 Stack Trace Completed in 1ms findShort(Steem Dogecoin 21inc Dash MadeSafeCoin) should return 4 Test Failed

1 was not equal to 4 Stack Trace Completed in 1ms findShort(Bitcoin Lisk) should return 4 Test Failed 1 was not equal to 4 Stack Trace Completed in 1ms findShort(ProofOfStake Ripple) should return 6 Test Failed

1 was not equal to 6 Stack Trace findShort(ProofOfWork Dogecoin BTC Classic Dash Ripple ProofOfWork) should return 3 Test Failed

1 was not equal to 3 Stack Trace Completed in 1ms findShort(LiteCoin Bitcoin LiteCoin Bitcoin Waves Waves Bitcoin Dash Ripple Ripple Ethereum Classic Factom LiteCoin Factom Waves Factom) should return 4 Test Failed

1 was not equal to 4 Stack Trace Completed in 2ms findShort(Bitcoin Waves MadeSafeCoin DarkCoin ProofOfStake Classic BTC) should return 3 Test Failed

1 was not equal to 3 Stack Trace Completed in 1ms findShort(ProofOfStake Waves Ethereum Ethereum Ripple LiteCoin Steem Classic LiteCoin Ripple ProofOfStake Steem Monero Dogecoin Factom) should return 5 Test Failed


Solution

  • Your solution is ok actually, all you need to change is str.split("") to str.split(" ") (note the space).

    Here is a way to do it relying on built-in method:

    def findShort(wordsString: String): Int = {
      val wordsArray = wordsString.split(" ")
      wordsArray.minBy(_.length).length
    }
    
    println(findShort("LiteCoin Bitcoin LiteCoin Bitcoin Waves Waves Bitcoin Dash Ripple Ripple Ethereum Classic Factom LiteCoin Factom Waves Factom"))
    // Display 4
    println(findShort("Bitcoin Waves MadeSafeCoin DarkCoin ProofOfStake Classic BTC"))
    // Display 3
    

    And here a version that use foldLeft, if you don't want to rely on built in method:

    def length(word: String): Int =
      word.foldLeft(0){case (acc, _) => acc + 1}
    
    def findShort(str:String):Int = {
    
       str.split(" ").foldLeft(99){ case (smallestLength, word) =>
          val currentLength = length(word)
          if(currentLength < smallestLength)
             currentLength
           else smallestLength
       }
    }