1
\$\begingroup\$

Problem

Given an arithmetic string like 2+2*3 calculate result 8.

Assumptions you can make

  • string will be always well formed (no error checking needs to be done)
  • only operators passed in string will be + and *
  • only single digit numbers allowed

Example

input = 2*2*2+2*1*5
output = 18
input = 2+2*3
output = 8

Hers is scala code for the same

object Expression extends App {
 implicit class Converter(char: Char) {
 def toNum: Int = char - '0'
 }
 def evaluateExpression(s :List[Char]): Int = {
 s match {
 case left::op::List(right) => // a+b or a*b
 op match {
 case '+' => left.toNum + right.toNum
 case _ => left.toNum * right.toNum
 }
 case left::op::right => // a+b*c or a*b+c
 op match {
 case '+' =>
 left.toNum + evaluateExpression(right)
 case '*' =>
 val nextAdd = right indexOf '+'
 val (multiplication ,pendingExpression) = if (nextAdd == -1) {
 (right,List[Char]())
 } else {
 (right.take(nextAdd), right.drop(nextAdd + 1))
 }
 val product = (multiplication.filter( _ != '*') map (_.toNum)).foldLeft(left.toNum) (_ * _)
 if (pendingExpression.isEmpty) product
 else product + evaluateExpression(pendingExpression)
 }
 }
 }
 List("3*3*3", "2+2*3", "0*0*1", "0+0*1", "0*0*1", "2+2*3*3", "2+2+2*3+2+2") foreach { expr =>
 println(expr + " = " + evaluateExpression(expr.toList))
 }
}

Output for above code

3*3*3 = 27
2+2*3 = 8
0*0*1 = 0
0+0*1 = 0
0*0*1 = 0
2+2*3*3 = 20
2+2+2*3+2+2 = 14
Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
asked Dec 5, 2018 at 19:02
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I rolled back your last edit. After getting an answer you are not allowed to change your code anymore. This is to ensure that answers do not get invalidated and have to hit a moving target. If you have changed your code you can either post it as an answer (if it would constitute a code review) or ask a new question with your changed code (linking back to this one as reference). Refer to this post for more information \$\endgroup\$ Commented Dec 6, 2018 at 18:34

1 Answer 1

2
\$\begingroup\$

You might want to spend some time becoming more familiar with the Standard Library. You're doing a few things that are already provided for.

implicit class Converter(char: Char) {
 def toNum: Int = char - '0'
}

To convert a digit character into the value it represents: char.asDigit. If you have one or more digit characters in a string: digits.toInt

Your solution also fails for expressions like "2*2+3". It looks like the evaluateExpression() code doesn't anticipate that, in the recursive call evaluateExpression(pendingExpression), the value of pendingExpression might be a single digit.

But mostly, with the input under so many tight restrictions, you should consider what shortcuts might be available to you.

def evaluateExpression(s :String) :Int =
 s.split("\\+")
 .map(_.split("\\*")
 .map(_.toInt)
 .product)
 .sum
answered Dec 6, 2018 at 7:59
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for pointing out the bug & alternative, I will update the code. As this exercise is more for interview preparation (as tagged), I didnt went for solution with split because i thought it will be more expensive (due to multiple iterations). But it seems I am wrong. For a string like this "3*3+3+3*3*3+2+2*3*0*0*1*0+0*1+0*0*1+2+2*3*2+2+2*3+2+2", Your solution is faster. Is it because of recursion in my solution? \$\endgroup\$ Commented Dec 6, 2018 at 17:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.