rpn_reckoner/
lib.rs

1//! # RPN-Reckoner
2//! Reverse Polish Notation (: RPN) - Reckoner
3//! # Example1
4//! ```
5//! let expression = String::from("1 2 +");
6//! let solution = rpn_reckoner::eval(expression).unwrap();
7//! println!("{}", solution); // -> 3
8//! ```
9//! # Example2
10//! ```
11//! let expression = String::from("5 2 - 3 +");
12//! let solution = rpn_reckoner::eval(expression).unwrap();
13//! println!("{}", solution); // -> 6
14//! ```
15//! # Example3
16//! ```
17//! let expression = String::from("5 2 3 ^ +");
18//! let solution = rpn_reckoner::eval(expression).unwrap();
19//! println!("{}", solution); // -> 13
20//! ```
21//! # Example4
22//! ```
23//! let expression = String::from("4 ! 2 +");
24//! let solution = rpn_reckoner::eval(expression).unwrap();
25//! println!("{}", solution); // -> 26
26//! ```
27
28mod operation;
29
30
31/// The function computes RPN expressions
32pub fn eval(expression: String) -> Result<f64, String> {
33    // Separate tokens with white space
34    let tokens = expression.split_whitespace();
35
36    let mut stack: Vec<f64> = Vec::new();
37    for token in tokens {
38        let t = token.trim();
39        if t == "" { continue; }
40
41        // Push values onto the stack
42        match t.parse::<f64>() {
43            Ok(value) => { stack.push(value); continue; },
44            Err(_) => 0.0,
45        };
46
47        // Push calculation results onto the stack
48        let right = stack.pop().unwrap_or(0.0);
49        let left = stack.pop().unwrap_or(0.0);
50        match t {
51            // Operator
52            "+" => stack.push(left + right),
53            "-" => stack.push(left - right),
54            "*" => stack.push(left * right),
55            "/" => stack.push(left / right),
56            "%" => stack.push(left % right),
57
58            // Power
59            "^" => stack.push(left.powf(right)),
60            "**" => stack.push(left.powf(right)),
61
62            // Factorial
63            "!" => {
64                if left != 0.0 { stack.push(left); }
65                stack.push(operation::factorial(right)); },
66
67            // Error
68            _ => return Err(format!("[Error] Invalid operator: {}", t)),
69        }
70    }
71
72    if stack.len() == 0 { return Err(format!("[Error] No result.")); }
73    if stack.len() > 1 { return Err(format!("[Error] Too many values in the stack.")); }
74
75    Ok(stack.pop().unwrap_or(0.0))
76}
77
78
79mod test;