Finding the nearest defibrillator exercise from CodingGames For my first attempt at Scala I decided to solve a simple exercise on codingame.com.

Based on a string input containing the user location, the defibrillators count and a list of defibrillators entries (id, name, address, phone number, longitude, latitude), I have to print the closest defibrillator from the user. The distance formula is given in the rules.

An example of input: 




3,879483
43,608177
3
1;Maison de la Prevention Sante;6 rue Maguelone 340000 Montpellier;;3,87952263361082;43,6071285339217
2;Hotel de Ville;1 place Georges Freche 34267 Montpellier;;3,89652239197876;43,5987299452849
3;Zoo de Lunaret;50 avenue Agropolis 34090 Mtp;;3,87388031141133;43,6395872778854





import math._
import scala.util._

object Solution extends App {
    val playerLongitude = readLine
    val playerLatitude = readLine
    val defibrilatorCount = readInt

    def sanitizeString(string : String) : String = string.replace(',', '.')
    def stringToDouble(string : String) : Double =  sanitizeString(string).toDouble

    val playerLongitudeValue = stringToDouble(playerLongitude)
    val playerLatitudeValue = stringToDouble(playerLatitude)

    def distanceToPlayer(long : Double, lat : Double) :  Double = {
        val x = (long - playerLongitudeValue) * cos((playerLatitudeValue + lat) / 2)
        val y  = lat - playerLatitudeValue
        sqrt(x * x + y * y) * 6371;
    }

    def distanceToPlayer(stringInput : String) : Double = {
        val tokens = sanitizeString(stringInput).split(";")
        distanceToPlayer(tokens(4).toDouble, tokens(5).toDouble)
    }

    var smallestDistance = Double.MaxValue
    var closestDefibName = ""

    for(i &lt;- 0 until defibrilatorCount) {
        val defib = readLine
        val distance = distanceToPlayer(defib)
        if(distance &lt; smallestDistance) {
            smallestDistance = distance
            closestDefibName = defib.split(";")(1)
        }
    }

    println(closestDefibName)
}
The main observation I would make is that this code — particularly the for loop — looks very procedural.  To find the minimum of some collection as determined by some metric, use .minBy[B](f: (A) ⇒ B): A.

For readability, avoid interleaving function definitions with the execution flow.  Put all of the definitions first, if possible.

You potentially split each defibrillator input line twice: once to extract the coordinates, then maybe again if you are interested in extracting the name.  I suggest parsing each line once and constructing a case class object from it.

Your sanitizeString function is rather heavy-handed.  To parse French-formatted decimals, use java.text.NumberFormat.

Note that defibrilatorCount is misspelled.

Suggested solution

import math.{cos, sqrt}
import io.StdIn.{readInt, readLine}
import java.text.NumberFormat
import java.util.Locale

object Solution extends App {
  val frenchFmt = NumberFormat.getInstance(Locale.FRANCE)
  def parseDouble(s: String): Double = frenchFmt.parse(s).doubleValue

  case class GeoObject(long: Double, lat: Double, name: String)

  def parseDefibrillator(line: String): GeoObject = {
    val fields = line.split(";")
    GeoObject(parseDouble(fields(4)), parseDouble(fields(5)), fields(1))
  }

  def distanceMetric(a: GeoObject, b: GeoObject): Double = {
    val x = (a.long - b.long) * cos((a.lat + a.lat) / 2)
    val y = a.lat - b.lat
    6371 * sqrt(x * x + y * y)
    // Note: 6371 * sqrt is optional, if just comparing distances
  }

  val player = GeoObject(parseDouble(readLine), parseDouble(readLine), null)
  val count = readInt
  val nearest = (0 until count).map(_ =&gt; parseDefibrillator(readLine))
                               .minBy(distanceMetric(player, _))
  println(nearest.name)
}