# Rpn.eval "3 1 - 2.1 +" # => 4.1 defmodule Rpn do def eval(expression) do eval(tokenize(expression), []) end defp eval([], [result]), do: result defp eval(["+"|tokens], [rhs, lhs|stack]), do: eval(tokens, [lhs + rhs | stack]) defp eval(["-"|tokens], [rhs, lhs|stack]), do: eval(tokens, [lhs - rhs | stack]) defp eval(["*"|tokens], [rhs, lhs|stack]), do: eval(tokens, [lhs * rhs | stack]) defp eval(["/"|tokens], [rhs, lhs|stack]), do: eval(tokens, [lhs / rhs | stack]) defp eval([value|tokens], stack), do: eval(tokens, [value | stack]) defp tokenize(expression) do tokens = Regex.scan( ~r/(?<op>[\+\-\*\/])|(?<float>\d+\.\d+)|(?<int>\d+)/, expression, capture: ["op", "int", "float"]) Enum.map( tokens, fn ([op, "", ""]) -> op (["", int, ""]) -> String.to_integer(int) (["", "", float]) -> String.to_float(float) end ) end end
Regex.scan/3
がいささかトリッキー。使い方が合っているのか判断がつかない。