Hemanth Annavarapu Hemanth Annavarapu - 2 months ago 18
Scala Question

Functional Programming: Perimeter of a polygon.

I am trying to find the perimeter of a polygon in a functional way. I tried my best but I couldn't make it purely functional. This is my code:

object Solution {

def main(args: Array[String]) {
var x:Double = 0
val N = scala.io.StdIn.readInt
val points = scala.io.Source.stdin.getLines().take(N).map(x=>x).toList
for(i <- 0 to N-1){
if(i==N-1) x+=dist(List(points(i),points(0)))
else x += dist(List(points(i),points(i+1)))
}
println(x)
}
def dist(A: List[String]): Double = {
scala.math.sqrt(scala.math.pow((A(0).split(" ")(0).toDouble-A(1).split(" ")(0).toDouble),2) + scala.math.pow((A(0).split(" ")(1).toDouble-A(1).split(" ")(1).toDouble),2))
}
}


I enter the number of points of the polygon first and then enter Cartesian coordinates of each point in a new line.

Can anyone help me make it purely functional?

Answer

Start with separating concerns:

// dist should just take 2 points
def dist(a: (Double,Double), b: (Double,Double)): Double = ...

// calculate perimeter
def perimeter (points: List[(Double,Double)]): Double = {
  // create a list of lines by connecting adjacent points
  val lines = points zip (points.tail ++ List(points.head))
  // aggregate the length of each line using foldLeft (/:)
  (0d /: lines)((acc, line) => acc ++ dist(line._1, line._2))
}

def main (args: Array[String]) {
  // main just needs to parse the lines
  val points = ... // parse the points

  println(perimeter(points))
}