1

I am doing some of the CodeWars challenges again.

I have a problem with this one:

"Given a string of words, you need to find the highest scoring word.

Each letter of a word scores points according to its position in the alphabet: a = 1, b = 2, c = 3 etc.

You need to return the highest scoring word as a string.

If two words score the same, return the word that appears earliest in the original string.

All letters will be lowercase and all inputs will be valid."

I've already looked up the solutions on SO, and have used the idea of one person(although I did change it a bit).

It still does not work.

Any ideas?

object Scoring {

def high(s: String): String = {

        var max = 0
                var whichWord = 0     
                var x = 0
                var y = new Array[Int](100)


                for(word <- s.split(" ")){
                    for(letter <- word) letter match{
                    case 'a' => y(x)+=1
                    case 'b' => y(x)+=2
                    case 'c' => y(x)+=3
                    case 'd' => y(x)+=4
                    case 'e' => y(x)+=5
                    case 'f' => y(x)+=6
                    case 'g' => y(x)+=7
                    case 'h' => y(x)+=8
                    case 'i' => y(x)+=9
                    case 'j' => y(x)+=10
                    case 'k' => y(x)+=11
                    case 'l' => y(x)+=12
                    case 'm' => y(x)+=13
                    case 'n' => y(x)+=14
                    case 'o' => y(x)+=15
                    case 'p' => y(x)+=16
                    case 'q' => y(x)+=17
                    case 'r' => y(x)+=18
                    case 's' => y(x)+=19
                    case 't' => y(x)+=20
                    case 'u' => y(x)+=21
                    case 'v' => y(x)+=22
                    case 'w' => y(x)+=23
                    case 'x' => y(x)+=24
                    case 'y' => y(x)+=25
                    case 'z' => y(x)+=26

                    }
                    x +=1
                }

        for(x <- 0 until y.length){

            if(y(x) > max)
            { 
                max = y(x)
                        whichWord = x
            }
        }

        s.substring(whichWord-1, whichWord)
}
}

Here are the tests:

test Results:

  RandomTestSpec
     high("ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm") should return "lierziuopbcsutm"
    Test Failed

    "[s]" was not equal to "[lierziuopbcsutm]"

 Stack Trace

    Completed in 34ms
     high("skwwwm") should return "skwwwm"

Test Failed

String index out of range: -1
 Stack Trace
Completed in 1ms
 high("a") should return "a"
Test Failed

String index out of range: -1
 Stack Trace
Completed in 1ms
 high("gykoialocufuc wcdwuxksqk bvapztcnqwx") should return "bvapztcnqwx"
Test Failed

"[y]" was not equal to "[bvapztcnqwx]"
 Stack Trace
Completed in 1ms
 high("gdhfoonwtih xbvsiaqhsesl obrndpz nxt inkklyo lf oyoadxqhuys lbqr oxbqq bopalqknjxvpg") should return "oyoadxqhuys"
Test Failed

"o[]" was not equal to "o[yoadxqhuys]"
 Stack Trace
Completed in 1ms
 high("bbzlmqhsypato pfufsi ryu oboklfa iigha h m") should return "bbzlmqhsypato"
Test Failed

String index out of range: -1
 Stack Trace
Completed in 1ms
 high("dbtfwvhk kadarmvldjhkx dgxffryldcxodtn hoffibiayxriqe gtqzeuywpgc nqlgvudy") should return "dgxffryldcxodtn"
Test Failed

"[b]" was not equal to "[dgxffryldcxodtn]"
 Stack Trace
Completed in 1ms
 high("vhyxdefryeznlkz fcaenzsnoxsn phdqu zjbbbybjmdn dbfhvxwnusz dqbqskfbwuomzsl ogsdioilk") should return "vhyxdefryeznlkz"
Test Failed

String index out of range: -1
 Stack Trace
 high("yqbzfuprmezbgee yxsewucg u") should return "yqbzfuprmezbgee"
Test Failed
String index out of range: -1
 Stack Trace
Completed in 1ms
 high("zifha") should return "zifha"
Test Failed

String index out of range: -1
 Stack Trace
 high("moroydyolj tcfpokvitzwzor rnzeacau") should return "tcfpokvitzwzor"
Test Failed

"[m]" was not equal to "[tcfpokvitzwzor]"
 Stack Trace
Completed in 1ms
 high("jhieih m") should return "jhieih"
Test Failed

String index out of range: -1
 Stack Trace
 high("yn ounbzw wk eldpjyikbfs nzm") should return "eldpjyikbfs"
Test Failed

"[ ]" was not equal to "[eldpjyikbfs]"
 Stack Trace
Completed in 1ms
Zim84
  • 3,404
  • 2
  • 35
  • 40
Mateusz Woś
  • 333
  • 2
  • 10
  • can you add a link to the CodeWars challenges? I would like to check it out. – pme Jun 24 '19 at 11:42
  • The challenge is inside my account I don't know if you will be able to access it. I will post the link, let me know if you are able to do it. https://www.codewars.com/kata/highest-scoring-word/train/scala – Mateusz Woś Jun 24 '19 at 11:47
  • thanks - link works – pme Jun 24 '19 at 12:12

4 Answers4

3

In Scala it is easier/ (better) to use the functions that are provided in the collections.

In your example - here a possibility:

First to add the scoring you can use this:

"hello".map(_.toInt).sum // 532

This returns the sum of all the chars as Int values (a=97; ...; z=122)

To find the highest weight you can use foldLeft, starting from "".

scala> List("a", "ab","ba").foldLeft("")((a,b)=> higher(a,b))
res10: String = ab

Here the complete higher function:

def higher(a:String, b:String):String=
  if(a.map(_.toInt).sum >= b.map(_.toInt).sum) a else b

There are many cool possibilities to do this with collection functions - don't use mutable state! That is an important reason why to switch to Scala.

Update: After playing on https://www.codewars.com I found a bug and a shorter solution:

s.split(" ").map(w => (w, w.map(_.toInt - 96).sum)).maxBy(_._2)._1
pme
  • 14,156
  • 3
  • 52
  • 95
  • Ok cheers, I was actually wondering about the function you have provided, and it did seem only to include two words, rather than a whole string. Everything clear now . – Mateusz Woś Jun 25 '19 at 10:36
  • By the way, I am at uni currently and they have only thought to program in one way(a more complex one now that I look at it). The post which I published, my way of completing the task is totally opposite to yours. Is there any I can get a hand on, your way of doing things? Any resources that you would recommend for example? It would be much appreciated, as I think I make it too complicated for myself sometimes. – Mateusz Woś Jun 25 '19 at 10:41
  • 1
    there are many good resources - check https://www.reddit.com/r/scala/ - e.g. https://www.reddit.com/r/scala/comments/7l4dla/resources_for_learning_scala/ – pme Jun 25 '19 at 12:31
2

Let's say your input is

val str = "ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm"

You can maintain a map with values for each char as

val charMap = Map(
  'a' -> 1,
  'b' -> 2,
  'c' -> 3,
  'd' -> 4,
  'e' -> 5,
  'f' -> 6,
  'g' -> 7,
  'h' -> 8,
  'i' -> 9,
  'j' -> 10,
  'k' -> 11,
  'l' -> 12,
  'm' -> 13,
  'n' -> 14,
  'o' -> 15,
  'p' -> 16,
  'q' -> 17,
  'r' -> 18,
  's' -> 19,
  't' -> 20,
  'u' -> 21,
  'v' -> 22,
  'w' -> 23,
  'x' -> 24,
  'y' -> 25,
  'z' -> 26,
)

You can then add a simple function that will compute the count of each word

def countOfWord(str : String): Int = str.map(charMap).sum

Then an applying the following operation on your input string str will fetch you the desired results

str.split(" ").map(word => (word, countOfWord(word))).maxBy(_._2)._1

This fetches you your desired output

res0: String = lierziuopbcsutm
Chaitanya
  • 3,590
  • 14
  • 33
1
val words = s.split(" ")
val scores = words.map(w => (w, w.map(_ - 'a' + 1).sum))
val max = scores.maxBy(_._2)._2
scores.find(_._2 == max).get._1
pasha701
  • 6,831
  • 1
  • 15
  • 22
1

What about this?

object HighestWord extends App {
  val inputStr: String = "ykvhorsqve kfkq jhjibercdptf efevxax ccr vnsmumqby jwhxvamegupfcj lierziuopbcsutm"

  val answer = inputStr.split(" ").map {
    str: String =>
      val sum = str.map { chr: Char =>
        chr.toInt
      }.sum
      (str, sum)
  }.maxBy(_._2)._1

  println(answer)
}
Raman Mishra
  • 2,635
  • 2
  • 15
  • 32