use std::{ fs::File, io::{Read, Write}, }; #[derive(PartialEq, Eq, Clone, Copy, Debug)] enum Keyword { Start, End, Assign(isize, isize), Set0, MvRight, MvLeft, PrintNum, PrintChar, // unicode GetNum, GetChar, // Unicode StartLoop, EndLoop, CopyClip, PasteClip, Ignore, } pub fn run(path: &str) { let mut file = File::open(path).unwrap(); let mut buf = String::new(); file.read_to_string(&mut buf).unwrap(); let tokens = tokenize(buf); let mut list = [0_isize; 10000]; let mut pos = 0_usize; let mut clip = 0_isize; let mut token_pos = 0; let mut loop_stack: Vec = Vec::new(); println!("{:?}", tokens); while tokens[token_pos] != Keyword::End { let tk = tokens[token_pos]; match tk { Keyword::End => break, Keyword::Set0 => list[pos] = 0, Keyword::Start => (), Keyword::Assign(s, m) => list[pos] = list[pos] * m + s, Keyword::MvRight => pos += 1, Keyword::MvLeft => pos -= 1, Keyword::PrintNum => { print!("{}", list[pos]); std::io::stdout().flush().unwrap(); } Keyword::PrintChar => { if let Some(c) = char::from_u32(list[pos] as u32) { print!("{}", c); std::io::stdout().flush().unwrap(); } } Keyword::GetNum => { let mut input_text = String::new(); std::io::stdin().read_line(&mut input_text).unwrap(); if let Ok(num) = input_text.trim().parse::() { list[pos] = num; } } Keyword::GetChar => { let mut input_text = String::new(); std::io::stdin().read_line(&mut input_text).unwrap(); list[pos] = input_text.chars().next().unwrap() as isize; } Keyword::StartLoop => { if list[pos] == 0 { token_pos = goto_end_of_loop(tokens.clone(), token_pos).unwrap() + 1; } else { loop_stack.push(token_pos); } } Keyword::EndLoop => { token_pos = loop_stack.pop().expect("Found unmatched 'vuelve messi'") - 1; } Keyword::CopyClip => clip = list[pos], Keyword::PasteClip => list[pos] = clip, Keyword::Ignore => (), } token_pos += 1; } } fn goto_end_of_loop<'a>(tokens: Vec, pos: usize) -> Result { let mut loops = 0; for (i, kw) in tokens[(pos + 1)..].iter().enumerate() { match kw { Keyword::StartLoop => loops += 1, Keyword::EndLoop => { if loops > 0 { loops -= 1; } else { return Ok(i + pos + 1); } } _ => (), } } Err("Found unmatched 'sigue messi'") } fn tokenize(text: String) -> Vec { let clean_text = text // .replace('\n', "") // .replace(". ", ".") // .replace(',', "") // .replace('\t', "") .replace(['\n', ',', '\t'], "") .to_lowercase(); let commands = clean_text.split('.').filter(|x| !x.is_empty()); commands .map(|command| { let comm_trim = command.trim(); if comm_trim.len() > 7 && &comm_trim[0..8] == "va messi" { let mut sum = 0_isize; let mut mult = 1_isize; for word in comm_trim[8..].split(' ') { if is_noun(word) { sum += 1; } else if is_adjetive(word) { sum *= 2; mult *= 2; } else if word == "fútbol" { mult *= -1; } } Keyword::Assign(sum, mult) } else { match comm_trim { "la agarra messi" => Keyword::Start, "¡gol!" => Keyword::End, "encara messi" | "ankara messi" => Keyword::Set0, "la mueve messi por la derecha" => Keyword::MvRight, "la mueve messi por la izquierda" => Keyword::MvLeft, "juega messi" => Keyword::PrintNum, "la pisa messi" => Keyword::PrintChar, "siempre messi" => Keyword::GetNum, "gambetea messi" => Keyword::GetChar, "sigue messi" => Keyword::StartLoop, "vuelve messi" => Keyword::EndLoop, "corre messi" => Keyword::CopyClip, "amaga messi" => Keyword::PasteClip, word => { println!("Ignored, {:?}", word); Keyword::Ignore } } } }) .collect() } fn is_noun(word: &str) -> bool { let nouns = [ "actuación", "actuaciones", "astro", "astros", "banda", "bandas", "calidad", "calidades", "campo", "campos", "cancha", "canchas", "centro", "centros", "clase", "clases", "dios", "dioses", "estadio", "estadios", "estrella", "estrellas", "figura", "figuras", "galaxia", "galaxias", "gambeta", "gambetas", "habilidad", "habilidades", "ídola", "ídolo", "ídolos", "ídolos", "jugada", "jugadas", "jugador", "jugadora", "jugadores", "jugadoras", "lateral", "laterales", "leo", "lio", "leonel", "lionel", "muchacho", "muchachos", "muchacha", "muchachas", "mundo", "mundos", "país", "países", "partido", "partidos", "pelota", "pelotas", "pibe", "pibes", "piba", "pibas", "planeta", "planetas", "potencial", "potenciales", "pulga", "pulgas", "república", "repúblicas", "talento", "talentos", "titán", "titanes", "tribuna", "tribunas", "toda", "todo", "todas", "todos", ]; nouns.contains(&word) } fn is_adjetive(word: &str) -> bool { let adjetives = [ "argentina", "argentino", "argentinas", "argentinos", "favorita", "favorito", "favoritas", "favoritos", "fenomenal", "fenomenales", "futbolística", "futbolísticas", "futbolístico", "futbolísticos", "habilidosa", "habilidoso", "habilidosas", "habilidosos", "increible", "increibles", "irrepetible", "irrepetibles", "impecable", "impecables", "impresionante", "impresionantes", "magistral", "magistrales", "maravilloso", "maravillosa", "maravillosos", "maravillosas", "mundial", "mundiales", "nacional", "nacionales", "talentosa", "talentoso", "talentosas", "talentosos", "titánica", "titánico", "titánicas", "titánicos", "tremenda", "tremendo", "tremendas", "tremendos", "única", "único", "únicas", "únicos", ]; adjetives.contains(&word) }