update many
This commit is contained in:
285
storage/zeta/rs/23629.rs
Normal file
285
storage/zeta/rs/23629.rs
Normal file
@@ -0,0 +1,285 @@
|
||||
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<Vec<Token>> {
|
||||
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<i64>) -> 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<Token>) -> Option<i64> {
|
||||
let mut op_stack: Vec<Token> = vec![];
|
||||
let mut num_stack: Vec<i64> = 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()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user