-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy path18.rs
35 lines (32 loc) · 1.28 KB
/
18.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
use std::io::stdin;
fn eval(line: &str, plus_precedence: i32) -> i64 {
let mut nums = Vec::new();
let mut operators = Vec::new();
let precedence = |c| match c { '+' => plus_precedence, '*' => 1, _ => 0 };
for c in line.chars().chain(")".chars()) {
match c {
'0'..='9' => nums.push(c.to_digit(10).unwrap() as i64),
'(' | '+' | '*' | ')' => {
while !operators.is_empty() && c != '(' {
let op = operators.pop().unwrap();
if op == '(' && c == ')' { break }
if precedence(op) < precedence(c) {
operators.push(op);
break;
}
let func = match op { '*' => |(a, b)| a * b, _ => |(a, b)| a + b };
let value = nums.pop().zip(nums.pop()).map(func).unwrap();
nums.push(value);
}
if c != ')' { operators.push(c); }
},
_ => continue,
}
}
*nums.get(0).unwrap()
}
fn main() {
let lines: Vec<String> = stdin() .lines().filter_map(Result::ok).collect();
println!("{}", lines.iter().map(|l| eval(&l, 1)).sum::<i64>());
println!("{}", lines.iter().map(|l| eval(&l, 2)).sum::<i64>());
}