Calculate simple arithmetic string in Scala











up vote
1
down vote

favorite












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









share|improve this question




















  • 1




    "only operators passed in string will be +,." Here's a typo, no?
    – Calak
    yesterday










  • fixed it, thanks for pointing it out.
    – vikrant
    yesterday










  • 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
    – Sᴀᴍ Onᴇᴌᴀ
    12 hours ago















up vote
1
down vote

favorite












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









share|improve this question




















  • 1




    "only operators passed in string will be +,." Here's a typo, no?
    – Calak
    yesterday










  • fixed it, thanks for pointing it out.
    – vikrant
    yesterday










  • 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
    – Sᴀᴍ Onᴇᴌᴀ
    12 hours ago













up vote
1
down vote

favorite









up vote
1
down vote

favorite











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









share|improve this question















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






interview-questions functional-programming scala math-expression-eval






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 12 hours ago









Sᴀᴍ Onᴇᴌᴀ

8,05061751




8,05061751










asked yesterday









vikrant

335




335








  • 1




    "only operators passed in string will be +,." Here's a typo, no?
    – Calak
    yesterday










  • fixed it, thanks for pointing it out.
    – vikrant
    yesterday










  • 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
    – Sᴀᴍ Onᴇᴌᴀ
    12 hours ago














  • 1




    "only operators passed in string will be +,." Here's a typo, no?
    – Calak
    yesterday










  • fixed it, thanks for pointing it out.
    – vikrant
    yesterday










  • 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
    – Sᴀᴍ Onᴇᴌᴀ
    12 hours ago








1




1




"only operators passed in string will be +,." Here's a typo, no?
– Calak
yesterday




"only operators passed in string will be +,." Here's a typo, no?
– Calak
yesterday












fixed it, thanks for pointing it out.
– vikrant
yesterday




fixed it, thanks for pointing it out.
– vikrant
yesterday












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
– Sᴀᴍ Onᴇᴌᴀ
12 hours ago




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
– Sᴀᴍ Onᴇᴌᴀ
12 hours ago










1 Answer
1






active

oldest

votes

















up vote
1
down vote













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





share|improve this answer





















  • 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?
    – vikrant
    13 hours ago











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209097%2fcalculate-simple-arithmetic-string-in-scala%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













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





share|improve this answer





















  • 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?
    – vikrant
    13 hours ago















up vote
1
down vote













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





share|improve this answer





















  • 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?
    – vikrant
    13 hours ago













up vote
1
down vote










up vote
1
down vote









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





share|improve this answer












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






share|improve this answer












share|improve this answer



share|improve this answer










answered 23 hours ago









jwvh

52627




52627












  • 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?
    – vikrant
    13 hours ago


















  • 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?
    – vikrant
    13 hours ago
















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?
– vikrant
13 hours ago




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?
– vikrant
13 hours ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209097%2fcalculate-simple-arithmetic-string-in-scala%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Morgemoulin

Scott Moir

Souastre