use std::collections::VecDeque; use std::fmt::{Display, Formatter, Result}; fn main() { println!("Simple incrementer"); let rules_si = vec!( Rule::new("q0", '1', '1', Direction::Right, "q0"), Rule::new("q0", 'B', '1', Direction::Stay, "qf") ); let states_si = vec!("q0", "qf"); let terminating_states_si = vec!("qf"); let permissible_symbols_si = vec!('B', '1'); let mut tm_si = TM::new(states_si, "q0", terminating_states_si, permissible_symbols_si, 'B', rules_si, "111"); while !tm_si.is_done() { println!("{}", tm_si); tm_si.step(); } println!("___________________"); println!("Three-state busy beaver"); let rules_bb3 = vec!( Rule::new("a", '0', '1', Direction::Right, "b"), Rule::new("a", '1', '1', Direction::Left, "c"), Rule::new("b", '0', '1', Direction::Left, "a"), Rule::new("b", '1', '1', Direction::Right, "b"), Rule::new("c", '0', '1', Direction::Left, "b"), Rule::new("c", '1', '1', Direction::Stay, "halt"), ); let states_bb3 = vec!("a", "b", "c", "halt"); let terminating_states_bb3 = vec!("halt"); let permissible_symbols_bb3 = vec!('0', '1'); let mut tm_bb3 = TM::new(states_bb3 ,"a", terminating_states_bb3, permissible_symbols_bb3, '0', rules_bb3, "0"); while !tm_bb3.is_done() { println!("{}", tm_bb3); tm_bb3.step(); } println!("{}", tm_bb3); println!("___________________"); println!("Five-state busy beaver"); let rules_bb5 = vec!( Rule::new("A", '0', '1', Direction::Right, "B"), Rule::new("A", '1', '1', Direction::Left, "C"), Rule::new("B", '0', '1', Direction::Right, "C"), Rule::new("B", '1', '1', Direction::Right, "B"), Rule::new("C", '0', '1', Direction::Right, "D"), Rule::new("C", '1', '0', Direction::Left, "E"), Rule::new("D", '0', '1', Direction::Left, "A"), Rule::new("D", '1', '1', Direction::Left, "D"), Rule::new("E", '0', '1', Direction::Stay, "H"), Rule::new("E", '1', '0', Direction::Left, "A"), ); let states_bb5 = vec!("A", "B", "C", "D", "E", "H"); let terminating_states_bb5 = vec!("H"); let permissible_symbols_bb5 = vec!('0', '1'); let mut tm_bb5 = TM::new(states_bb5 ,"A", terminating_states_bb5, permissible_symbols_bb5, '0', rules_bb5, "0"); let mut steps = 0; while !tm_bb5.is_done() { tm_bb5.step(); steps += 1; } println!("Steps: {}", steps); println!("Band lenght: {}", tm_bb5.band.len()); } struct TM<'a> { state: &'a str, terminating_states: Vec<&'a str>, rules: Vec>, band: VecDeque, head: usize, blank: char, } struct Rule<'a> { state: &'a str, read: char, write: char, dir: Direction, new_state: &'a str, } enum Direction{ Left, Right, Stay, } impl<'a> TM<'a> { fn new(_states: Vec<&'a str>, initial_state: &'a str, terminating_states: Vec<&'a str>, _permissible_symbols: Vec, blank: char, rules: Vec>, input: &str) -> Self { Self { state: initial_state, terminating_states, rules, band: input.chars().collect::>(), head: 0, blank } } fn is_done(&self) -> bool { self.terminating_states.contains(&self.state) } fn step(&mut self) { let field = self.band.get(self.head).unwrap(); let rule = self.rules.iter().find(|rule| rule.state == self.state && &rule.read == field).unwrap(); let field = self.band.get_mut(self.head).unwrap(); *field = rule.write; self.state = rule.new_state; match rule.dir { Direction::Left => { if self.head == 0 { self.band.push_front(self.blank) } else { self.head -= 1; } }, Direction::Right => { if self.head == self.band.len() - 1 { self.band.push_back(self.blank) } self.head += 1; }, Direction::Stay => {}, } } } impl<'a> Display for TM<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> Result { let band = self.band.iter().enumerate().map(|(i, c)| { if i == self.head { format!("[{}]", c) } else { format!(" {} ", c) } }).fold(String::new(), |acc, val| acc + &val); write!(f, "{}\t{}", self.state, band) } } impl<'a> Rule<'a> { fn new(state: &'a str, read: char, write: char, dir: Direction, new_state: &'a str) -> Self { Self { state, read, write, dir, new_state } } }