Skip to content

Instantly share code, notes, and snippets.

@fushime2
Last active October 9, 2018 04:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fushime2/fb6f81eff6ed4b0102cf4e6bdcb28934 to your computer and use it in GitHub Desktop.
Save fushime2/fb6f81eff6ed4b0102cf4e6bdcb28934 to your computer and use it in GitHub Desktop.
class RPNCalculator {
import std.algorithm : all, canFind, map;
import std.ascii : isDigit, isWhite;
import std.conv : to;
import std.string : split;
import std.range;
alias Stack = int[];
bool isNum(const char[] cs) {
return cs.all!(c => isDigit(c));
}
int calc(const string exp) {
char[][] es = exp.split!isWhite
.map!(e => e.to!(char[]))
.array;
Stack stack;
foreach (char[] e ; es) {
if (canFind("+-*/", e)) {
if (stack.length < 2) {
throw new Exception("Invalid Expression");
}
int x = stack.back; stack.popBack();
int y = stack.back; stack.popBack();
int val = 0;
switch (e) {
case "+": val = y + x; break;
case "-": val = y - x; break;
case "*": val = y * x; break;
case "/": val = y / x; break;
default: throw new Exception("Invalid Expression");
}
stack ~= val;
}
else if (isNum(e)) {
stack ~= e.to!int;
}
else {
throw new Exception("Invalid Expression");
}
}
assert(stack.length == 1);
return stack.front;
}
}
unittest {
RPNCalculator rc = new RPNCalculator;
assert(rc.calc("1 1 +") == 2);
assert(rc.calc("10 20 +") == 30);
assert(rc.calc("5 1 -") == 4);
assert(rc.calc("3 4 *") == 12);
assert(rc.calc("4 4 /") == 1);
assert(rc.calc("1 2 + 3 *") == 9);
}
import Data.List
-- words :: String -> [String] // like split()
solveRPN :: (Num a, Read a) => String -> a
solveRPN = head . foldl foldingFunction [] . words
where foldingFunction (x:y:ys) "*" = (x * y):ys
foldingFunction (x:y:ys) "+" = (x + y):ys
foldingFunction (x:y:ys) "-" = (y - x):ys
foldingFunction xs numberString = read numberString:xs -- 1
{-
- For example, a = [3, 4, 9, 3]
- Then, x = 3, y = 4, ys = [9, 3]
- If the items are not operators, a string represents a number(1)
-}
main = do
print $ 2 == solveRPN "1 1 +"
print $ 0 == solveRPN "1 1 -"
print $ -4 == solveRPN "10 4 3 + 2 * -"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment