0

Has anyone in this forum attempted to solve the ACM programming problem http://acm.mipt.ru/judge/problems.pl?browse=yes&problem=024? It is one of the simpler problems in ACM MIPT and the goal is to evaluate an expression consisting of +, -, * and parentheses. Despite the apparent simplicity, I haven't been able to get my solution accepted, apparently because one of the test case expressions has an operator not stated in the problem. I even added support for division ('/') but that too didn't help. Any idea on what other operator needs to be supported? FYI, my program removes all whitespaces from the input before processing so that spaces shouldn't be a problem. Anything not stated in the problem but needs to be taken care of?

so1
  • 58
  • 1
  • 10
  • "apparently"? How did you come to that conclusion? Do you support the unary minus? – phant0m Sep 25 '12 at 10:19
  • How did you approach it? I suspect it is not as simple as it seems - the order of evaluation of operators along with maintaining the stack is not trivial (though not extremely hard as well) – amit Sep 25 '12 at 10:21
  • @phant0m - Yes, I support unary minus - I verified it using y own sample expressions and also using samples given in problem statement. I added a line of validation to check for operators that I didn't expect - with that line in place, I got Runtime Error for the solution. With that line removed, I got wrong answer (guess because my code defaulted to '/' operator if the operator was not one of +, - or *) – so1 Sep 25 '12 at 10:45
  • @amit - Yes, I used a stack approach - 1 stack each for operators and 1 for operands. I would initially identify unary minuses and transform them to a custom operator '~' before evaluating the expression. – so1 Sep 25 '12 at 10:53
  • @so1: Please provide a short explanation of your solution (optionally with the code itself) in your answer (use the edit option), there most likely be some edge case you didn't think of - and we'll be able to help you find it. – amit Sep 25 '12 at 10:57
  • Link to my code: http://ideone.com/RO4Hf. – so1 Sep 25 '12 at 11:01
  • Approach: Step1: Translate unary -s to ~. Enclose given expr within (). Step2: Parse the expression from left to right: - if number, parse rest of the number and push to operand stack - if (, push it to stack - if ), pop operators till ( is reached - for each operator, apply it on popped operand(s) and push result to operand stack - if +, -, *, / or ~, evaluation is starighforward and result is pushed to operand stack Step3: When operator stack becomes empty, return the only element in operand stack as result of expression – so1 Sep 25 '12 at 11:09
  • I can't run ruby code, but try checking that: 1. you are following this: `Operators have equal priority and should be calculated from left to right. It means that 1+1*2=4.` and 2. you are correctly handling stuff like 2*-3 (the problem is not clear if this is allowed or not) and unary minus in front of brackets, like -(2+1)*3. – IVlad Sep 25 '12 at 13:44

1 Answers1

0

You're being bitten by ruby's handling of strings and characters.

curr_ch = @input[i]

gives you an integer, for the input you get, the ASCII code of the character at index i of the input.

curr_ch == '('

for example compares that integer to the string "(", of course that fails. Also the regex matches fail because you pass them an integer where a string is expected.

Replacing all occurrences of some_var = @input[some_index] with some_var = @input[some_index...some_index+1] gives me a programme that seems to work (it works on a few test inputs I gave it). Probably someone who actually knows the quirks of ruby can give you a better fix.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • Thanks a lot - the observation turned out to be spot on!! I had completely missed the fact that older versions of Ruby, such as the one that the contest site uses, return ASCII code rather than the actual character for string[index]. I was testing locally using newer version of Ruby and hence couldn't catch the problem. Thanks again! – so1 Sep 25 '12 at 16:28
  • Ah, good news that it became sane. Terrible for backwards compatibility, though, I think. – Daniel Fischer Sep 25 '12 at 16:32