use std::io::stdin; #[derive(Debug, Clone, Copy)] enum Token { NUM(usize), PLUS, TIMES, MINUS, DIV, EQUAL, Err, } impl ToString for Token { fn to_string(&self) -> String { match self { Token::NUM(x) => x.to_string(), Token::PLUS => "+".to_string(), Token::MINUS => "-".to_string(), Token::TIMES => "x".to_string(), Token::DIV => "/".to_string(), Token::EQUAL => "=".to_string(), Token::Err => "Err".to_string(), } } } fn convert(num: i64) -> String { let mut s = String::new(); for ch in num.to_string().chars() { match ch { '0' => s.push_str("ZERO"), '1' => s.push_str("ONE"), '2' => s.push_str("TWO"), '3' => s.push_str("THREE"), '4' => s.push_str("FOUR"), '5' => s.push_str("FIVE"), '6' => s.push_str("SIX"), '7' => s.push_str("SEVEN"), '8' => s.push_str("EIGHT"), '9' => s.push_str("NINE"), '-' => s.push('-'), _ => panic!("Invalid Number"), } } s } fn priority(tok: Token) -> usize { match tok { Token::NUM(_) => 0, Token::PLUS | Token::MINUS => 1, Token::TIMES | Token::DIV => 2, Token::EQUAL => 3, Token::Err => 100, } } #[allow(unused_assignments)] fn lex(s: String) -> Option> { let mut lexed = vec![]; let mut iter = s.chars(); let mut curr: char = '\n'; let mut next: char = '\n'; curr = iter.next().unwrap(); next = iter.next().unwrap(); let mut skip = 0; loop { if skip <= 0 { let mut tok = Token::Err; match (curr, next) { ('\n', _) => { break; } ('O', 'N') => { skip = 3; tok = Token::NUM(1); } ('T', 'W') => { skip = 3; tok = Token::NUM(2); } ('T', 'H') => { skip = 5; tok = Token::NUM(3); } ('F', 'O') => { skip = 4; tok = Token::NUM(4); } ('F', 'I') => { skip = 4; tok = Token::NUM(5); } ('S', 'I') => { skip = 3; tok = Token::NUM(6); } ('S', 'E') => { skip = 5; tok = Token::NUM(7); } ('E', 'I') => { skip = 5; tok = Token::NUM(8); } ('N', 'I') => { skip = 4; tok = Token::NUM(9); } ('Z', 'E') => { skip = 4; tok = Token::NUM(0); } ('+', _) => { tok = Token::PLUS; } ('-', _) => { tok = Token::MINUS; } ('x', _) => { tok = Token::TIMES; } ('/', _) => { tok = Token::DIV; } ('=', _) => { tok = Token::EQUAL; } _ => { return None; } } match tok { Token::NUM(x) => { let last = lexed.last(); match last { Some(&Token::NUM(y)) => { lexed.pop(); lexed.push(Token::NUM(y * 10 + x)); } _ => { lexed.push(tok); } } } _ => { lexed.push(tok); } } } // next if skip > 0 { skip -= 1; } match iter.next() { Some(ch) => { curr = next; next = ch; } None => { if next == '\n' || next == '\0' { next = '\0'; curr = '\n'; } else { curr = next; next = '\n'; } } } } // ON // TW // TH // FO // FI // SI // SE // EI // NI // ZE Some(lexed) } fn eval(op: Token, num_stack: &mut Vec) -> bool { let (a, b) = match (num_stack.pop(), num_stack.pop()) { (Some(x), Some(y)) => (y, x), _ => { return false; } }; match op { Token::PLUS => { num_stack.push(a + b); } Token::MINUS => { num_stack.push(a - b); } Token::TIMES => { num_stack.push(a * b); } Token::DIV => { num_stack.push(a / b); } _ => { return false; } } return true; } fn parse(lexed: &Vec) -> Option { let mut op_stack: Vec = vec![]; let mut num_stack: Vec = vec![]; for &token in lexed { match token { Token::NUM(x) => { num_stack.push(x as i64); } Token::PLUS | Token::MINUS | Token::TIMES | Token::DIV => { let p = priority(token); while let Some(&top) = op_stack.last() { if priority(top) > p { if !eval(op_stack.pop().unwrap(), &mut num_stack) { return None; } } else { break; } } op_stack.push(token); } Token::EQUAL => { while let Some(op) = op_stack.pop() { if !eval(op, &mut num_stack) { return None; } } } Token::Err => { panic!("Invalid Token"); } } } if (num_stack.len() == 1) { return num_stack.pop(); } else { return None; } } fn main() { let mut s = String::new(); stdin().read_line(&mut s).unwrap(); let s = s.trim_ascii_end().to_string(); let lexed = lex(s); if lexed.is_none() { println!("Madness!"); return; } let lexed = lexed.unwrap(); let parsed = parse(&lexed); if parsed.is_none() { println!("Madness!"); } else { for tok in lexed { print!("{}", tok.to_string()); } print!("\n"); println!("{}", convert(parsed.unwrap())); } }