2
\$\begingroup\$

Given two equally sized arrays of integers A and B, compute the number of times A[i] > B[i] and the number of times A[i] < B[i] for each index i.

New to scala, I put together the following solution:

import scala.io.Source

object Solution {

    def main(args: Array[String]) {
        val lines = Source.stdin.getLines
        val alice = lines.next.split(" ").map(_.toInt)
        val bob = lines.next.split(" ").map(_.toInt)

        val competitions = alice zip bob
        val scoreA = competitions.count(c => c._1 > c._2)
        val scoreB = competitions.count(c => c._1 < c._2)

        printf("%d %d", scoreA, scoreB)
    }
}

I normally solve these problems using python, so I simply searched online for my usual programming constructs. I have a few questions.

  • Is there a more general way to print a list of space separated integers? Currently my use of printf is limited to exactly two.
  • Are there any pitfalls I'm unaware of?
  • Ideas of more concise solutions without sacrificing readability?

Any other insights would be greatly appreciated!

\$\endgroup\$
3
\$\begingroup\$

You don't have to traverse the competitions array twice. The results can be collected in a tuple result after a single traversal.

val results = competitions.foldLeft((0,0)){
                             case ((aw,bw),(a,b)) => 
                               if (a>b)      (aw+1,bw) //a won
                               else if (b>a) (aw,bw+1) //b won
                               else          (aw,bw)   //tie
                           }

The tuple's elements can be accessed via indexing, results._1 and results._2, but it can be more convenient to unpack it via pattern matching.

val (scoreA, scoreB) = results

So, putting it all together, and removing the competitions step (just because you can).

val (aWins
    ,bWins) = alice.zip(bob)
                   .foldLeft((0,0)){
                      case ((aw,bw),(a,b)) =>
                        if (a>b)      (aw+1,bw)
                        else if (b>a) (aw,bw+1)
                        else          (aw,bw)
                   }

Sending the results to STDOUT is usually done via println(), either with string catenation...

println(aWins + " " + bWins)

...or with string interpolation.

println(s"$aWins $bWins")
\$\endgroup\$
  • \$\begingroup\$ I am not a Scala expert, but it seems to me that your code handles the case A[i] == B[i]differently from the original code in the question. \$\endgroup\$ – Martin R Apr 9 '18 at 7:39
  • \$\begingroup\$ @MartinR; Good catch. While trying to demonstrate my major point on code efficiency I sort of glossed over the rules for a tie. A simple if else addition fixes that. \$\endgroup\$ – jwvh Apr 9 '18 at 8:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.