Problem with exercism Forth Exercise: One of the tests timed out

When coding for Forth exercise, I got this error:

We received the following error when we ran your code:

One of the tests timed out

I searched forum and found the “alloc_attack test fail” post, which was not this case because I’d fixed the alloc_attack issue already.

Please see my code on playground which passes all test cases and provide your feedback about the root cause:

Thanks!

It would be helpful to post your code here (using a codeblock). That way people have everything they need without needing to click links and juggle multiple tabs to figure out what’s going on. Help people help you but providing all the information directly when asking a question!

the whole runnable code is pasted below as well:

'''
#![allow(unused_imports)]

use std::collections::hash_map::HashMap;
use std::collections::VecDeque;
use std::rc::Rc;

pub type Value = i32;
pub type Result = std::result::Result<(), Error>;

#[derive(Debug)]
pub struct MyNode {
    name: String,
    children: VecDeque<Rc<MyNode>>,
}

impl MyNode {
    fn new(s: String, children: VecDeque<Rc<MyNode>>) -> MyNode {
        MyNode {
            name: s,
            children
        }
    } 

    fn add_child(&mut self, child: Rc<MyNode>) {
        self.children.push_back(child);
    }

    fn get_children_text(&self) -> Vec<String> {
        let mut v = Vec::new();
        
        if self.children.len() == 0 {
            v.push(self.name.clone());
            return v;
        }
        
        for child in &self.children {
            let cv = child.get_children_text();
            v.extend_from_slice(&cv);
        }

        v
    }
}

pub struct Forth {
    stack: VecDeque<Value>,
    new_names: HashMap<String, Rc<MyNode>>,
}

#[derive(Debug, PartialEq, Eq)]
pub enum Error {
    DivisionByZero,
    StackUnderflow,
    UnknownWord,
    InvalidWord,
}

impl Forth {
    pub fn new() -> Forth {
        Forth {
            stack: VecDeque::new(),
            new_names: HashMap::new(),
        }
    }

    pub fn stack(&self) -> &[Value] {
        self.stack.as_slices().0
    }

    fn is_digit(&self, sym: &String) -> bool {
        for (idx,c) in sym.chars().enumerate() {
            if idx == 0 && c == '-' && sym.len() > 1 {
                continue
            }
            if c < '0' || c > '9' {
                return false;    
            } 
        }

        true
    }

    fn add_expression(&mut self) -> Result {
        let s1 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        let s2 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        self.stack.push_back(s1 + s2);
        Ok(())
    }
    fn subtract_expression(&mut self) -> Result {
        let s1 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        let s2 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        self.stack.push_back(s2 - s1);
        Ok(())
    }
    fn multiply_expression(&mut self) -> Result {
        let s1 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        let s2 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        self.stack.push_back(s1 * s2);
        Ok(())
    }
    fn division_expression(&mut self) -> Result {
        let s1 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        let s2 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        if s1 == 0 {
            return Err(Error::DivisionByZero);
        }
        self.stack.push_back(s2 / s1);
        Ok(())
    }
    fn swap_expression(&mut self) -> Result {
        let s1 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        let s2 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        self.stack.push_back(s1);
        self.stack.push_back(s2);
        Ok(())
    }
    fn drop_expression(&mut self) -> Result {
        self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        Ok(())
    }
    fn dup_expression(&mut self) -> Result {
        let s1 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        self.stack.push_back(s1);
        self.stack.push_back(s1);
        Ok(())
    }
    fn over_expression(&mut self) -> Result {
        let s1 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        let s2 = self.stack.pop_back().ok_or(Error::StackUnderflow)?;
        self.stack.push_back(s2);
        self.stack.push_back(s1);
        self.stack.push_back(s2);
        Ok(())
    }
    
    fn eval_expression(&mut self, input: &str) -> Result {
        let symbols: Vec<&str> = input.split(' ').collect();
        for symbol in symbols {
            if self.is_digit(&symbol.to_owned()) {
                self.stack.push_back(symbol.parse::<Value>().unwrap());
            } else {
                let reg_sym = symbol.to_lowercase(); 

                let resolved_vec = self.resolve_symbol(reg_sym);
                println!("{:?}", resolved_vec);
                for rs in resolved_vec {
                    if self.is_digit(&rs) {
                        self.stack.push_back(rs.parse::<Value>().unwrap());
                    } else {
                        match rs.as_str() {
                            "+" => self.add_expression()?,
                            "-" => self.subtract_expression()?,
                            "*" => self.multiply_expression()?,
                            "/" => self.division_expression()?,
                            "swap" => self.swap_expression()?,
                            "drop" => self.drop_expression()?,
                            "dup" => self.dup_expression()?,
                            "over" => self.over_expression()?,
                            _ => return Err(Error::UnknownWord)
                        }
                    }
                }
            }
        }

        Ok(())
    }

    fn resolve_symbol(&self, sym: String) -> Vec<String> {
        if let Some(node) = self.new_names.get(&sym) {
            return node.get_children_text();
        } else {
            return vec!(sym);
        }
    }
    
    fn resolve_name(&self, sym: String) -> Rc<MyNode> {
        if let Some(_b) = self.new_names.get(&sym) {
            _b.clone()
            // Rc::new(MyNode::new(sym, VecDeque::new()))
        } else {
            Rc::new(MyNode::new(sym, VecDeque::new()))
        }
    }
    
        
    fn add_new_names(&mut self, input: &str) -> Result {
        let symbols: Vec<&str> = input.split(' ').collect();
        let len = symbols.len();
        if symbols[0] != ":" || symbols[len-1] != ";" {
            return Err(Error::InvalidWord);
        }
        if len < 4 {
            return Err(Error::InvalidWord);            
        }
        
        let sym = symbols[1].to_lowercase();
        if self.is_digit(&sym) {
            return Err(Error::InvalidWord);                        
        }

        let mut node = MyNode::new(sym.clone(), VecDeque::new());
        for i in 2..len-1 {
            let n = self.resolve_name(symbols[i].to_lowercase());
            node.add_child(n);
        } 
        self.new_names.insert(sym, Rc::new(node));

        println!("{:?}", self.new_names);
        Ok(())
    }
    
    pub fn eval(&mut self, input: &str) -> Result {
        if input.starts_with(":") {
            return self.add_new_names(input);
        } else {
             return self.eval_expression(input);
        }            
    }
}

///////////// all test cases included below //////////////////
///////////// omitted for clarify //////////////////

#[allow(dead_code)]
fn main() {
}

'''