1
\$\begingroup\$

I am new to Scala have to solve this problem:

If you have number "xy" should equal sum of consecutive powers of its digits

xy = x^1 + y^2

For example, take the number 89 and you should have:

89 = 8^1+ 9^2

And if we have a list we should filter with the matched numbers based on the above role.

For example:

Consider these range of numbers:

(1, 100) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 89]

(90, 100) == []

This code works fine, but is this a pure functional programming style or are there some best practices in terms of performance and functionality?

def myFun(str: String):Double ={

   val myDigits=str.toList.map(_.asDigit)

   (myDigits.indices zip myDigits).toMap.map({case(x , y) =>  pow(y,x+1)}).reduce(_+_)

}

(1 to 100 ) .toList.filter({ case(x) => x == myFun(x.toString) })
\$\endgroup\$
3
  • \$\begingroup\$ What does 17 have to do with anything? \$\endgroup\$ Nov 11, 2017 at 23:56
  • \$\begingroup\$ @200_success you are right I have been edited it. \$\endgroup\$
    – Elsayed
    Nov 12, 2017 at 0:10
  • \$\begingroup\$ On an algorithmic note, maintaining an array $$ \{0^n, 1^n, 2^n, \ldots, 9^n\} $$ as you go along will be asymptotically more efficient than calling pow each iteration. \$\endgroup\$
    – Veedrac
    Dec 2, 2017 at 14:59

1 Answer 1

3
\$\begingroup\$

Recommendations:

  • For starters I would recommend passing an Int to your function and then converting it to a String before splitting it up and mapping it to its digit components.
  • Next, Scala has a useful built in function called zipWithIndex that you could use over (myDigits.indices zip myDigits). Granted it will reverse the ordering from what you have, but that can be handled as you can see in the code below.
  • I would also recommend splitting any map / filter / etc over multiple lines to increase readability.
  • When you are using reduce to sum the elements of a container you can instead apply the built in sum method.
  • Finally, I would hold off on converting the (1 to 100) from a Range to a List until after your filter operation is complete.

Code:

def f(i: Int): Int ={
  val myDigits = i.toString.map(_.asDigit)

  myDigits.zipWithIndex.map { case (y, x) =>
    pow(y, x+1).toInt
  }.sum
}

val x = (1 to 100).filter(i => i == f(i)).toList
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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