using System; using System.IO; using System.Collections; using System.Text; public class Init { public static void Main (string[] args) { if (args.Length < 1) { Console.WriteLine ("BAD USAGE\nUSAGE: MaquinaTuring.exe ProgramRules.txt [ribbon]"); return; } TuringMachine Machine = new TuringMachine (); FileStream file = null; StreamReader reader = null; bool Error = false; try { file = File.OpenRead (args[0]); reader = new StreamReader (file); while (true) { string LineAct = reader.ReadLine (); if (LineAct[0] == '-') { Machine.SetInitialState (LineAct.Substring (1)); break; } if (LineAct.StartsWith ("//")) continue; string[] tokens = LineAct.Split (':'); MoveType Move; if (tokens[4] == "NULL") Move = MoveType.NullMove; else if (tokens[4] == "LEFT") Move = MoveType.LeftMove; else if (tokens[4] == "RIGHT") Move = MoveType.RightMove; else throw new Exception ("BAD FORMAT, MOVE TYPE MUST BE NULL, LEFT OR RIGHT"); Machine.AddRule (tokens[0], tokens[1], tokens[2][0], tokens[3][0], Move); } } catch (IOException) { Console.WriteLine ("File not found or unexpected EOF"); Error = true; } catch (Exception ex) { Console.WriteLine (ex.Message); Error = true; } finally { reader.Close (); file.Close (); } if (Error) return; string ribbon = ""; if (args.Length > 1) { StringBuilder builder = new StringBuilder (); int i = 1; while (true) { builder.Append (args[i]); i++; if (i == args.Length) break; builder.Append (" "); } ribbon = builder.ToString (); } else { Console.Write ("Ribbon: "); ribbon = Console.ReadLine (); } Machine.SetRibbon (ribbon.ToCharArray ()); try { Machine.Run (); } catch (Exception er) { Console.WriteLine (er.Message); } Console.WriteLine ("Final Ribbon: {0}", Machine.PrintRibbon ()); } } public class TuringMachine { Hashtable states = new Hashtable (); TuringState ActualState; TuringRibbon Ribbon; public void SetRibbon (char[] Ribbon) { this.Ribbon = new TuringRibbon (Ribbon); } public void SetInitialState (string State) { ActualState = GetState (State); if (ActualState == null) throw new Exception ("There is no connection from the initial state to the other ones "); } public void AddRule (string State, string NextState, char Read, char Write, MoveType Move) { if (!states.ContainsKey (State)) states[State] = new TuringState (State); if (!states.ContainsKey (NextState)) states[NextState] = new TuringState (NextState); GetState (State).AddRule (NextState, Read, Write, Move); } private TuringState GetState (string State) { return states[State] as TuringState; } public void Run () { while (true) { TuringRule Rule = ActualState.GetRule (Ribbon.Read ()); if (Rule == null) throw new Exception ("The Ribbon Got Stuck!"); Ribbon.Write (Rule.Write); Ribbon.MoveCurrentPosition (Rule.Move); ActualState = GetState (Rule.NextState); if (Ribbon.IsPositionOutOfRibbon ()) break; } } public string PrintRibbon () { return Ribbon.Print (); } } public class TuringState { string name; Hashtable rules = new Hashtable (); public TuringState (string Name) { name = Name; } public string Name { get { return name; } } public void AddRule (string NextState, char CharToRead, char CharToWrite, MoveType Move) { rules[CharToRead] = new TuringRule (NextState, CharToRead, CharToWrite, Move); } public TuringRule GetRule (char Read) { return rules[Read] as TuringRule; } } public class TuringRule { string nextState; char charToRead; char charToWrite; MoveType move; public TuringRule (string NextState, char CharToRead, char CharToWrite, MoveType Move) { nextState = NextState; charToRead = CharToRead; charToWrite = CharToWrite; move = Move; } public string NextState { get { return nextState; } } public char Read { get { return charToRead; } } public char Write { get { return charToWrite; } } public MoveType Move { get { return move; } } } public class TuringRibbon { char[] ribbon; int currentPosition = 0; public TuringRibbon (char[] Ribbon) { ribbon = (char[]) Ribbon.Clone (); } public char Read () { return ribbon[currentPosition]; } public void Write (char Value) { ribbon[currentPosition] = Value; } public void MoveCurrentPosition (MoveType type) { if (type == MoveType.LeftMove) currentPosition--; else if (type == MoveType.RightMove) currentPosition++; } public bool IsPositionOutOfRibbon () { return currentPosition < 0 || currentPosition == ribbon.Length; } public string Print () { return new string (ribbon); } } public enum MoveType { LeftMove, RightMove, NullMove }