Take a number and sum its digits raised to the consecutive powers

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) })

• What does 17 have to do with anything? – 200_success Nov 11 '17 at 23:56
• @200_success you are right I have been edited it. – Elsayed Nov 12 '17 at 0:10
• 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. – Veedrac Dec 2 '17 at 14:59

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