Last active
October 9, 2018 04:42
-
-
Save fushime2/fb6f81eff6ed4b0102cf4e6bdcb28934 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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