4
\$\begingroup\$

Given an array of integers, update the index with multiplication of previous and next integers,

 Input: 2 , 3, 4, 5, 6 Output: 2*3, 2*4, 3*5, 4*6, 5*6 

Following is a scala implementation for the same. Kindly review.

import scala.util.Random object NeighborMultiplication extends App { val numbers = List.fill(10)(Random.nextInt(10)) println(numbers mkString ",") def multiplication(l: List[Int], carryOver: Int = 1, useCarryOver: Boolean = false ): List[Int] = l match { case Nil => List() case x::Nil => List(carryOver * x) case x::y::Nil => List(carryOver * x * y, y * x) case x::y::z::Nil => List(carryOver * x * y, x * z, y * z) case x::y::z::tail => if (useCarryOver) List(carryOver * y, x * z, y * tail.head) ++ multiplication(tail, z, true) else List(x * y, x * z, y * tail.head) ++ multiplication(tail, z, true) } println(multiplication(numbers).mkString(",")) } 
\$\endgroup\$

    2 Answers 2

    5
    \$\begingroup\$

    The tricky part of this problem is how to handle the special cases for the start and end of the list, as well as how to handle short lists with fewer than three elements.

    The fact that you need to consider up to three elements at a time means that you need a lot of base cases for recursion, though. It's also undesirable to expose the special cases in the form of the carryOver and useCarryOver parameters.

    A better approach would be to take advantage of the List.sliding function. (Note that .sliding may produce a group with just two elements instead of three, if the input lst has length two.)

    def multiplication(lst: List[Int]): List[Int] = lst match { case _::_::_ => (lst.head :: lst ++ List(lst.last)) .sliding(3) .map(group => group.head * group.last) .toList case _ => lst } 
    \$\endgroup\$
    1
    • \$\begingroup\$thanks for your answer, sliding fits here beautifully.\$\endgroup\$
      – vikrant
      CommentedDec 28, 2018 at 20:20
    1
    \$\begingroup\$

    This can be done using tail recursion as well.

    def mulSeq(numbers: Seq[Int]): Seq[Long] = { @tailrec def recurMul(numbersPart: Seq[Int], mul: Int, acc: List[Long]): Seq[Long] = { numbersPart match { case num1::num2::Nil => (num1*num2) :: ((mul*num2).toLong :: acc) case num1::num2::tail => recurMul(num2::tail, num1, (mul*num2)::acc) case _ => acc } } numbers.headOption match { case Some(first) => recurMul(numbers, first, Nil).reverse case None => Nil } } 

    Although the solution above with List.sliding is a little bit shorter, tail recursion is a beloved thing in Scala ^_^. Also, I think in the proposed solution edge cases are more clear.

    \$\endgroup\$

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.