1
1
use std:: { collections:: HashMap , io:: stdin} ;
2
2
3
- use itertools:: Itertools ;
4
-
5
3
fn eval ( line : & str , plus_precedence : i32 ) -> i64 {
6
4
let mut nums = Vec :: new ( ) ;
7
5
let mut operators = Vec :: new ( ) ;
8
- let precedence = HashMap :: from ( [ ( '(' , 10 ) , ( '+' , plus_precedence) , ( '*' , 1 ) ] ) ;
9
- // eprintln!("line = {:?}", line);
6
+ let precedence = HashMap :: from ( [ ( '(' , 0 ) , ( ')' , 0 ) , ( '+' , plus_precedence) , ( '*' , 1 ) ] ) ;
7
+
10
8
for c in line. chars ( ) . chain ( ")" . chars ( ) ) {
11
- // eprintln!("c = {:?}, nums = {:?}, ops = {:?}", c, nums, operators);
12
9
match c {
13
10
'0' ..='9' => nums. push ( c. to_digit ( 10 ) . unwrap ( ) as i64 ) ,
14
- '(' => operators. push ( c) ,
15
- ')' => {
16
- while !operators. is_empty ( ) {
11
+ '(' | '+' | '*' | ')' => {
12
+ while !operators. is_empty ( ) && c != '(' {
17
13
let op = operators. pop ( ) . unwrap ( ) ;
18
- if op == '(' {
14
+ if op == '(' && c == ')' { break }
15
+ if precedence. get ( & op) . unwrap ( ) < precedence. get ( & c) . unwrap ( ) {
16
+ operators. push ( op) ;
19
17
break ;
20
18
}
21
19
let func = if op == '*' { |( a, b) | a * b } else { |( a, b) | a + b } ;
22
20
let value = nums. pop ( ) . zip ( nums. pop ( ) ) . map ( func) . unwrap ( ) ;
23
21
nums. push ( value) ;
24
22
}
25
- }
26
- '+' | '*' => {
27
- while !operators. is_empty ( ) {
28
- // eprintln!("\tc = {:?}, nums = {:?}, ops = {:?}", c, nums, operators);
29
- let op = operators. last ( ) . unwrap ( ) ;
30
- if * op == '(' || precedence. get ( op) . unwrap ( ) < precedence. get ( & c) . unwrap ( ) {
31
- break ;
32
- }
33
- let func = if * op == '*' { |( a, b) | a * b } else { |( a, b) | a + b } ;
34
- let value = nums. pop ( ) . zip ( nums. pop ( ) ) . map ( func) . unwrap ( ) ;
35
- nums. push ( value) ;
36
- operators. pop ( ) ;
37
- }
38
- operators. push ( c) ;
23
+ if c != ')' { operators. push ( c) ; }
39
24
} ,
40
- _ => ( ) ,
25
+ _ => continue ,
41
26
}
42
27
}
43
28
* nums. get ( 0 ) . unwrap ( )
44
29
}
45
30
46
31
fn main ( ) {
47
- let lines = stdin ( ) . lines ( ) . filter_map ( Result :: ok) . collect_vec ( ) ;
32
+ let lines: Vec < String > = stdin ( ) . lines ( ) . filter_map ( Result :: ok) . collect ( ) ;
48
33
println ! ( "{:?}" , lines. iter( ) . map( |l| eval( & l, 1 ) ) . sum:: <i64 >( ) ) ;
49
34
println ! ( "{:?}" , lines. iter( ) . map( |l| eval( & l, 2 ) ) . sum:: <i64 >( ) ) ;
50
- }
35
+ }
0 commit comments