Family Day update
This commit is contained in:
parent
aac6731f2c
commit
9ad63ea473
2442 changed files with 39761 additions and 8255 deletions
|
|
@ -0,0 +1,200 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class TuringMachine
|
||||
{
|
||||
public static async Task Main() {
|
||||
var fiveStateBusyBeaver = new TuringMachine("A", '0', "H").WithTransitions(
|
||||
("A", '0', '1', Right, "B"),
|
||||
("A", '1', '1', Left, "C"),
|
||||
("B", '0', '1', Right, "C"),
|
||||
("B", '1', '1', Right, "B"),
|
||||
("C", '0', '1', Right, "D"),
|
||||
("C", '1', '0', Left, "E"),
|
||||
("D", '0', '1', Left, "A"),
|
||||
("D", '1', '1', Left, "D"),
|
||||
("E", '0', '1', Stay, "H"),
|
||||
("E", '1', '0', Left, "A")
|
||||
);
|
||||
var busyBeaverTask = fiveStateBusyBeaver.TimeAsync();
|
||||
|
||||
var incrementer = new TuringMachine("q0", 'B', "qf").WithTransitions(
|
||||
("q0", '1', '1', Right, "q0"),
|
||||
("q0", 'B', '1', Stay, "qf")
|
||||
)
|
||||
.WithInput("111");
|
||||
foreach (var _ in incrementer.Run()) PrintLine(incrementer);
|
||||
PrintResults(incrementer);
|
||||
|
||||
var threeStateBusyBeaver = new TuringMachine("a", '0', "halt").WithTransitions(
|
||||
("a", '0', '1', Right, "b"),
|
||||
("a", '1', '1', Left, "c"),
|
||||
("b", '0', '1', Left, "a"),
|
||||
("b", '1', '1', Right, "b"),
|
||||
("c", '0', '1', Left, "b"),
|
||||
("c", '1', '1', Stay, "halt")
|
||||
);
|
||||
foreach (var _ in threeStateBusyBeaver.Run()) PrintLine(threeStateBusyBeaver);
|
||||
PrintResults(threeStateBusyBeaver);
|
||||
|
||||
var sorter = new TuringMachine("A", '*', "X").WithTransitions(
|
||||
("A", 'a', 'a', Right, "A"),
|
||||
("A", 'b', 'B', Right, "B"),
|
||||
("A", '*', '*', Left, "E"),
|
||||
("B", 'a', 'a', Right, "B"),
|
||||
("B", 'b', 'b', Right, "B"),
|
||||
("B", '*', '*', Left, "C"),
|
||||
("C", 'a', 'b', Left, "D"),
|
||||
("C", 'b', 'b', Left, "C"),
|
||||
("C", 'B', 'b', Left, "E"),
|
||||
("D", 'a', 'a', Left, "D"),
|
||||
("D", 'b', 'b', Left, "D"),
|
||||
("D", 'B', 'a', Right, "A"),
|
||||
("E", 'a', 'a', Left, "E"),
|
||||
("E", '*', '*', Right, "X")
|
||||
)
|
||||
.WithInput("babbababaa");
|
||||
sorter.Run().Last();
|
||||
Console.WriteLine("Sorted: " + sorter.TapeString);
|
||||
PrintResults(sorter);
|
||||
|
||||
sorter.Reset().WithInput("bbbababaaabba");
|
||||
sorter.Run().Last();
|
||||
Console.WriteLine("Sorted: " + sorter.TapeString);
|
||||
PrintResults(sorter);
|
||||
|
||||
Console.WriteLine(await busyBeaverTask);
|
||||
PrintResults(fiveStateBusyBeaver);
|
||||
|
||||
void PrintLine(TuringMachine tm) => Console.WriteLine(tm.TapeString + "\tState " + tm.State);
|
||||
|
||||
void PrintResults(TuringMachine tm) {
|
||||
Console.WriteLine($"End state: {tm.State} = {(tm.Success ? "Success" : "Failure")}");
|
||||
Console.WriteLine(tm.Steps + " steps");
|
||||
Console.WriteLine("tape length: " + tm.TapeLength);
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
public const int Left = -1, Stay = 0, Right = 1;
|
||||
private readonly Tape tape;
|
||||
private readonly string initialState;
|
||||
private readonly HashSet<string> terminatingStates;
|
||||
private Dictionary<(string state, char read), (char write, int move, string toState)> transitions;
|
||||
|
||||
public TuringMachine(string initialState, char blankSymbol, params string[] terminatingStates) {
|
||||
State = this.initialState = initialState;
|
||||
tape = new Tape(blankSymbol);
|
||||
this.terminatingStates = terminatingStates.ToHashSet();
|
||||
}
|
||||
|
||||
public TuringMachine WithTransitions(
|
||||
params (string state, char read, char write, int move, string toState)[] transitions)
|
||||
{
|
||||
this.transitions = transitions.ToDictionary(k => (k.state, k.read), k => (k.write, k.move, k.toState));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TuringMachine Reset() {
|
||||
State = initialState;
|
||||
Steps = 0;
|
||||
tape.Reset();
|
||||
return this;
|
||||
}
|
||||
|
||||
public TuringMachine WithInput(string input) {
|
||||
tape.Input(input);
|
||||
return this;
|
||||
}
|
||||
|
||||
public int Steps { get; private set; }
|
||||
public string State { get; private set; }
|
||||
public bool Success => terminatingStates.Contains(State);
|
||||
public int TapeLength => tape.Length;
|
||||
public string TapeString => tape.ToString();
|
||||
|
||||
public IEnumerable<string> Run() {
|
||||
yield return State;
|
||||
while (Step()) yield return State;
|
||||
}
|
||||
|
||||
public async Task<TimeSpan> TimeAsync(CancellationToken cancel = default) {
|
||||
var chrono = Stopwatch.StartNew();
|
||||
await RunAsync(cancel);
|
||||
chrono.Stop();
|
||||
return chrono.Elapsed;
|
||||
}
|
||||
|
||||
public Task RunAsync(CancellationToken cancel = default)
|
||||
=> Task.Run(() => {
|
||||
while (Step()) cancel.ThrowIfCancellationRequested();
|
||||
});
|
||||
|
||||
private bool Step() {
|
||||
if (!transitions.TryGetValue((State, tape.Current), out var action)) return false;
|
||||
tape.Current = action.write;
|
||||
tape.Move(action.move);
|
||||
State = action.toState;
|
||||
Steps++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private class Tape
|
||||
{
|
||||
private List<char> forwardTape = new List<char>(), backwardTape = new List<char>();
|
||||
private int head = 0;
|
||||
private char blank;
|
||||
|
||||
public Tape(char blankSymbol) => forwardTape.Add(blank = blankSymbol);
|
||||
|
||||
public void Reset() {
|
||||
backwardTape.Clear();
|
||||
forwardTape.Clear();
|
||||
head = 0;
|
||||
forwardTape.Add(blank);
|
||||
}
|
||||
|
||||
public void Input(string input) {
|
||||
Reset();
|
||||
forwardTape.Clear();
|
||||
forwardTape.AddRange(input);
|
||||
}
|
||||
|
||||
public void Move(int direction) {
|
||||
head += direction;
|
||||
if (head >= 0 && forwardTape.Count <= head) forwardTape.Add(blank);
|
||||
if (head < 0 && backwardTape.Count <= ~head) backwardTape.Add(blank);
|
||||
}
|
||||
|
||||
public char Current {
|
||||
get => head < 0 ? backwardTape[~head] : forwardTape[head];
|
||||
set {
|
||||
if (head < 0) backwardTape[~head] = value;
|
||||
else forwardTape[head] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Length => backwardTape.Count + forwardTape.Count;
|
||||
|
||||
public override string ToString() {
|
||||
int h = (head < 0 ? ~head : backwardTape.Count + head) * 2 + 1;
|
||||
var builder = new StringBuilder(" ", Length * 2 + 1);
|
||||
if (backwardTape.Count > 0) {
|
||||
builder.Append(string.Join(" ", backwardTape)).Append(" ");
|
||||
if (head < 0) (builder[h + 1], builder[h - 1]) = ('(', ')');
|
||||
for (int l = 0, r = builder.Length - 1; l < r; l++, r--) (builder[l], builder[r]) = (builder[r], builder[l]);
|
||||
}
|
||||
builder.Append(string.Join(" ", forwardTape)).Append(" ");
|
||||
if (head >= 0) (builder[h - 1], builder[h + 1]) = ('(', ')');
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
function tape=turing(rules,tape,initial,terminal)
|
||||
%"rules" is cell array of cell arrays of the following form:
|
||||
%First element is number representing initial state
|
||||
%Second element is number representing input from the tape
|
||||
%Third element is number representing output printed onto the tape
|
||||
%Fourth element is 'l', 'r', or 's' representing whether to go right,
|
||||
%left, or stay. Treats any input other than 'l' or 'r' as 's'.
|
||||
%Final value is state we go to
|
||||
%0 is always blank symbol
|
||||
term=0;
|
||||
ind=1;
|
||||
while term==0
|
||||
a=[];
|
||||
for i=1:numel(rules)
|
||||
if rules{i}{1}==initial
|
||||
a=[a i];
|
||||
end
|
||||
end
|
||||
|
||||
possible=rules(a);
|
||||
n=numel(possible);
|
||||
|
||||
while numel(tape)<ind
|
||||
tape=[tape, 0]; %#ok<AGROW>
|
||||
end
|
||||
|
||||
for i=1:n
|
||||
if(tape(ind)==possible{i}{2})
|
||||
break;
|
||||
end
|
||||
end
|
||||
instruction=possible{i};
|
||||
tape(ind)=instruction{3};
|
||||
if instruction{4}=='r'
|
||||
ind=ind+1;
|
||||
elseif instruction{4}=='l'
|
||||
if ind==1
|
||||
tape=[0,tape]; %#ok<AGROW>
|
||||
else
|
||||
ind=ind-1;
|
||||
end
|
||||
end
|
||||
if terminal==instruction{5}
|
||||
term=1;
|
||||
else
|
||||
initial=instruction{5};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -7,239 +7,219 @@ import scala.language.implicitConversions
|
|||
* Implementation of Universal Turing Machine in Scala that can simulate an arbitrary
|
||||
* Turing machine on arbitrary input
|
||||
*
|
||||
* @author Abdulla Abdurakhmanov (https://github.com/abdmob/utms)
|
||||
* @author Abdulla Abdurakhmanov (https://github.com/abdolence/utms)
|
||||
*/
|
||||
class UniversalTuringMachine[S](val rules: List[UTMRule[S]],
|
||||
val initialState: S,
|
||||
val finalStates: Set[S],
|
||||
val blankSymbol: String,
|
||||
val inputTapeVals: Seq[String],
|
||||
printEveryIter: Int = 1) {
|
||||
class UniversalTuringMachine[S](
|
||||
val rules: List[UTMRule[S]],
|
||||
val initialState: S,
|
||||
val finalStates: Set[S],
|
||||
val blankSymbol: String,
|
||||
val inputTapeVals: Iterable[String],
|
||||
printEveryIter: Int = 1
|
||||
) {
|
||||
|
||||
private val initialTape = UTMTape(inputTapeVals, 0, blankSymbol)
|
||||
private val initialTape = UTMTape( inputTapeVals.toVector, 0, blankSymbol )
|
||||
|
||||
@tailrec
|
||||
private def iterate(state: S, curIteration: Int, tape: UTMTape): UTMTape = {
|
||||
val needToBePrinted = curIteration % printEveryIter == 0
|
||||
@tailrec
|
||||
private def iterate( state: S, curIteration: Int, tape: UTMTape ): UTMTape = {
|
||||
if (curIteration % printEveryIter == 0) {
|
||||
print( s"${curIteration}: ${state}: " )
|
||||
tape.printTape()
|
||||
}
|
||||
|
||||
if (needToBePrinted) {
|
||||
print(s"${curIteration}: ${state}: ")
|
||||
tape.printTape()
|
||||
}
|
||||
if (finalStates.contains( state )) {
|
||||
println( s"Finished in the final state: ${state}" )
|
||||
tape.printTape()
|
||||
tape
|
||||
} else {
|
||||
rules.find(rule => rule.state == state && rule.fromSymbol == tape.current() ) match {
|
||||
case Some( rule ) => {
|
||||
val updatedTape = tape.updated( rule.toSymbol, rule.action )
|
||||
|
||||
if (finalStates.contains(state)) {
|
||||
println(s"Finished in the final state: ${state}")
|
||||
tape.printTape()
|
||||
tape
|
||||
}
|
||||
else {
|
||||
rules.find(rule => rule.state == state && rule.fromSymbol == tape.current()) match {
|
||||
case Some(rule) => {
|
||||
val updatedTape = tape.updated(
|
||||
rule.toSymbol,
|
||||
rule.action
|
||||
)
|
||||
iterate( rule.toState, curIteration + 1, updatedTape )
|
||||
}
|
||||
case _ => {
|
||||
println(
|
||||
s"Finished: no suitable rules found for ${state}/${tape.current()}"
|
||||
)
|
||||
tape.printTape()
|
||||
tape
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iterate(
|
||||
rule.toState,
|
||||
curIteration + 1,
|
||||
updatedTape
|
||||
)
|
||||
}
|
||||
case _ => {
|
||||
println(s"Finished: no suitable rules found for ${state}/${tape.current()}")
|
||||
tape.printTape()
|
||||
tape
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def run(): UTMTape = iterate(state = initialState, curIteration = 0, tape = initialTape)
|
||||
def run(): UTMTape =
|
||||
iterate( state = initialState, curIteration = 0, tape = initialTape )
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Universal Turing Machine actions
|
||||
*/
|
||||
* Universal Turing Machine actions
|
||||
*/
|
||||
sealed trait UTMAction
|
||||
case class UTMLeft() extends UTMAction
|
||||
case class UTMRight() extends UTMAction
|
||||
case class UTMStay() extends UTMAction
|
||||
|
||||
object UTMAction {
|
||||
case object left extends UTMAction
|
||||
case object right extends UTMAction
|
||||
case object stay extends UTMAction
|
||||
}
|
||||
|
||||
/**
|
||||
* Universal Turing Machine rule definition
|
||||
*/
|
||||
case class UTMRule[S](state: S,
|
||||
fromSymbol: String,
|
||||
toSymbol: String,
|
||||
action: UTMAction,
|
||||
toState: S)
|
||||
* Universal Turing Machine rule definition
|
||||
*/
|
||||
case class UTMRule[S]( state: S, fromSymbol: String, toSymbol: String, action: UTMAction, toState: S )
|
||||
|
||||
object UTMRule {
|
||||
|
||||
implicit def tupleToUTMLRule[S](
|
||||
tuple: ( S, String, String, UTMAction, S )
|
||||
): UTMRule[S] =
|
||||
UTMRule[S]( tuple._1, tuple._2, tuple._3, tuple._4, tuple._5 )
|
||||
}
|
||||
|
||||
/**
|
||||
* Universal Turing Machine Tape
|
||||
*/
|
||||
case class UTMTape(content: Seq[String], position: Int, blankSymbol: String) {
|
||||
* Universal Turing Machine Tape
|
||||
*/
|
||||
case class UTMTape( content: Vector[String], position: Int, blankSymbol: String ) {
|
||||
|
||||
private def updateContentAtPos(symbol: String) = {
|
||||
if (position >= content.length) {
|
||||
content :+ symbol
|
||||
}
|
||||
else if (position < 0) {
|
||||
symbol +: content
|
||||
}
|
||||
else
|
||||
content.updated(position, symbol)
|
||||
}
|
||||
private def updateContentAtPos( symbol: String ) = {
|
||||
if (position >= content.length) {
|
||||
content :+ symbol
|
||||
} else if (position < 0) {
|
||||
symbol +: content
|
||||
} else if (content( position ) != symbol)
|
||||
content.updated( position, symbol )
|
||||
else
|
||||
content
|
||||
}
|
||||
|
||||
private[scala] def updated(symbol: String, action: UTMAction): UTMTape = {
|
||||
val updatedTape =
|
||||
this.copy(
|
||||
content = updateContentAtPos(symbol),
|
||||
position = action match {
|
||||
case UTMLeft() => position - 1
|
||||
case UTMRight() => position + 1
|
||||
case UTMStay() => position
|
||||
}
|
||||
)
|
||||
private[scala] def updated( symbol: String, action: UTMAction ): UTMTape = {
|
||||
val updatedTape =
|
||||
this.copy( content = updateContentAtPos( symbol ), position = action match {
|
||||
case UTMAction.left => position - 1
|
||||
case UTMAction.right => position + 1
|
||||
case UTMAction.stay => position
|
||||
} )
|
||||
|
||||
if (updatedTape.position < 0) {
|
||||
updatedTape.copy(
|
||||
content = blankSymbol +: updatedTape.content,
|
||||
position = 0
|
||||
)
|
||||
}
|
||||
else if (updatedTape.position >= updatedTape.content.length) {
|
||||
updatedTape.copy(
|
||||
content = updatedTape.content :+ blankSymbol
|
||||
)
|
||||
}
|
||||
else
|
||||
updatedTape
|
||||
}
|
||||
if (updatedTape.position < 0) {
|
||||
updatedTape.copy(
|
||||
content = blankSymbol +: updatedTape.content,
|
||||
position = 0
|
||||
)
|
||||
} else if (updatedTape.position >= updatedTape.content.length) {
|
||||
updatedTape.copy( content = updatedTape.content :+ blankSymbol )
|
||||
} else
|
||||
updatedTape
|
||||
}
|
||||
|
||||
private[scala] def current(): String = {
|
||||
if (content.isDefinedAt( position ))
|
||||
content( position )
|
||||
else
|
||||
blankSymbol
|
||||
}
|
||||
|
||||
private[scala] def current(): String = {
|
||||
if (content.isDefinedAt(position))
|
||||
content(position)
|
||||
else
|
||||
blankSymbol
|
||||
}
|
||||
|
||||
def printTape(): Unit = {
|
||||
print("[")
|
||||
if (position < 0)
|
||||
print("˅")
|
||||
content.zipWithIndex.foreach { case (symbol, index) =>
|
||||
if (position == index)
|
||||
print("˅")
|
||||
else
|
||||
print(" ")
|
||||
print(s"$symbol")
|
||||
}
|
||||
if (position >= content.length)
|
||||
print("˅")
|
||||
println("]")
|
||||
}
|
||||
def printTape(): Unit = {
|
||||
print( "[" )
|
||||
if (position < 0)
|
||||
print( "˅" )
|
||||
content.zipWithIndex.foreach {
|
||||
case ( symbol, index ) =>
|
||||
if (position == index)
|
||||
print( "˅" )
|
||||
else
|
||||
print( " " )
|
||||
print( s"$symbol" )
|
||||
}
|
||||
if (position >= content.length)
|
||||
print( "˅" )
|
||||
println( "]" )
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object UniversalTuringMachine extends App {
|
||||
|
||||
object dsl {
|
||||
main()
|
||||
|
||||
final val right = UTMRight()
|
||||
final val left = UTMLeft()
|
||||
final val stay = UTMStay()
|
||||
def main(): Unit = {
|
||||
import UTMAction._
|
||||
|
||||
implicit def tupleToUTMLRule[S](tuple: (S, String, String, UTMAction, S)): UTMRule[S] =
|
||||
UTMRule[S](tuple._1, tuple._2, tuple._3, tuple._4, tuple._5)
|
||||
}
|
||||
def createIncrementMachine() = {
|
||||
|
||||
main()
|
||||
sealed trait IncrementStates
|
||||
case object q0 extends IncrementStates
|
||||
case object qf extends IncrementStates
|
||||
|
||||
def main(): Unit = {
|
||||
import dsl._
|
||||
new UniversalTuringMachine[IncrementStates](
|
||||
rules = List( ( q0, "1", "1", right, q0 ), ( q0, "B", "1", stay, qf ) ),
|
||||
initialState = q0,
|
||||
finalStates = Set( qf ),
|
||||
blankSymbol = "B",
|
||||
inputTapeVals = Seq( "1", "1", "1" )
|
||||
).run()
|
||||
|
||||
def createIncrementMachine() = {
|
||||
}
|
||||
|
||||
sealed trait IncrementStates
|
||||
case class q0() extends IncrementStates
|
||||
case class qf() extends IncrementStates
|
||||
def createThreeStateBusyBeaver() = {
|
||||
|
||||
new UniversalTuringMachine[IncrementStates](
|
||||
rules = List(
|
||||
(q0(), "1", "1", right, q0()),
|
||||
(q0(), "B", "1", stay, qf())
|
||||
),
|
||||
initialState = q0(),
|
||||
finalStates = Set(qf()),
|
||||
blankSymbol = "B",
|
||||
inputTapeVals = Seq("1", "1", "1")
|
||||
).run()
|
||||
sealed trait ThreeStateBusyStates
|
||||
case object a extends ThreeStateBusyStates
|
||||
case object b extends ThreeStateBusyStates
|
||||
case object c extends ThreeStateBusyStates
|
||||
case object halt extends ThreeStateBusyStates
|
||||
|
||||
}
|
||||
new UniversalTuringMachine[ThreeStateBusyStates](
|
||||
rules = List(
|
||||
( a, "0", "1", right, b ),
|
||||
( a, "1", "1", left, c ),
|
||||
( b, "0", "1", left, a ),
|
||||
( b, "1", "1", right, b ),
|
||||
( c, "0", "1", left, b ),
|
||||
( c, "1", "1", stay, halt )
|
||||
),
|
||||
initialState = a,
|
||||
finalStates = Set( halt ),
|
||||
blankSymbol = "0",
|
||||
inputTapeVals = Seq()
|
||||
).run()
|
||||
|
||||
def createThreeStateBusyBeaver() = {
|
||||
}
|
||||
|
||||
sealed trait ThreeStateBusyStates
|
||||
case class a() extends ThreeStateBusyStates
|
||||
case class b() extends ThreeStateBusyStates
|
||||
case class c() extends ThreeStateBusyStates
|
||||
case class halt() extends ThreeStateBusyStates
|
||||
def createFiveState2SymBusyBeaverMachine() = {
|
||||
sealed trait FiveBeaverStates
|
||||
case object FA extends FiveBeaverStates
|
||||
case object FB extends FiveBeaverStates
|
||||
case object FC extends FiveBeaverStates
|
||||
case object FD extends FiveBeaverStates
|
||||
case object FE extends FiveBeaverStates
|
||||
case object FH extends FiveBeaverStates
|
||||
|
||||
new UniversalTuringMachine[ThreeStateBusyStates](
|
||||
rules = List(
|
||||
(a(), "0", "1", right, b()),
|
||||
(a(), "1", "1", left, c()),
|
||||
(b(), "0", "1", left, a()),
|
||||
(b(), "1", "1", right, b()),
|
||||
(c(), "0", "1", left, b()),
|
||||
(c(), "1", "1", stay, halt())
|
||||
),
|
||||
initialState = a(),
|
||||
finalStates = Set(halt()),
|
||||
blankSymbol = "0",
|
||||
inputTapeVals = Seq()
|
||||
).run()
|
||||
new UniversalTuringMachine[FiveBeaverStates](
|
||||
rules = List(
|
||||
( FA, "0", "1", right, FB ),
|
||||
( FA, "1", "1", left, FC ),
|
||||
( FB, "0", "1", right, FC ),
|
||||
( FB, "1", "1", right, FB ),
|
||||
( FC, "0", "1", right, FD ),
|
||||
( FC, "1", "0", left, FE ),
|
||||
( FD, "0", "1", left, FA ),
|
||||
( FD, "1", "1", left, FD ),
|
||||
( FE, "0", "1", stay, FH ),
|
||||
( FE, "1", "0", left, FA )
|
||||
),
|
||||
initialState = FA,
|
||||
finalStates = Set( FH ),
|
||||
blankSymbol = "0",
|
||||
inputTapeVals = Seq(),
|
||||
printEveryIter = 100000
|
||||
).run()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def createFiveState2SymBusyBeaverMachine() = {
|
||||
sealed trait FiveBeaverStates
|
||||
case class FA() extends FiveBeaverStates
|
||||
case class FB() extends FiveBeaverStates
|
||||
case class FC() extends FiveBeaverStates
|
||||
case class FD() extends FiveBeaverStates
|
||||
case class FE() extends FiveBeaverStates
|
||||
case class FH() extends FiveBeaverStates
|
||||
|
||||
new UniversalTuringMachine[FiveBeaverStates](
|
||||
rules = List(
|
||||
(FA(), "0", "1", right, FB()),
|
||||
(FA(), "1", "1", left, FC()),
|
||||
(FB(), "0", "1", right, FC()),
|
||||
(FB(), "1", "1", right, FB()),
|
||||
(FC(), "0", "1", right, FD()),
|
||||
(FC(), "1", "0", left, FE()),
|
||||
(FD(), "0", "1", left, FA()),
|
||||
(FD(), "1", "1", left, FD()),
|
||||
(FE(), "0", "1", stay, FH()),
|
||||
(FE(), "1", "0", left, FA())
|
||||
),
|
||||
initialState = FA(),
|
||||
finalStates = Set(FH()),
|
||||
blankSymbol = "0",
|
||||
inputTapeVals = Seq(),
|
||||
printEveryIter = 100000
|
||||
).run()
|
||||
}
|
||||
|
||||
createIncrementMachine()
|
||||
createThreeStateBusyBeaver()
|
||||
|
||||
// careful here, 47 mln iterations,
|
||||
// so this is commented to save our nature (I checked it for you anyway):
|
||||
// createFiveState2SymBusyBeaverMachine()
|
||||
}
|
||||
createIncrementMachine()
|
||||
createThreeStateBusyBeaver()
|
||||
// careful here, 47 mln iterations
|
||||
createFiveState2SymBusyBeaverMachine()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env bash
|
||||
main() {
|
||||
printf 'Simple Incrementer\n'
|
||||
printf '1 1 1' | run_utm q0 qf B q0,1,1,R,q0 q0,B,1,S,qf
|
||||
|
||||
printf '\nThree-state busy beaver\n'
|
||||
run_utm a halt 0 \
|
||||
a,0,1,R,b a,1,1,L,c b,0,1,L,a b,1,1,R,b c,0,1,L,b c,1,1,S,halt \
|
||||
</dev/null
|
||||
}
|
||||
|
||||
run_utm() {
|
||||
local initial=$1 final=$2 blank=$3
|
||||
shift 3
|
||||
local rules=("$@") tape
|
||||
mapfile -t -d' ' tape
|
||||
if (( ! ${#tape[@]} )); then
|
||||
tape=( "$blank" )
|
||||
fi
|
||||
local state=$initial
|
||||
local head=0
|
||||
while [[ $state != $final ]]; do
|
||||
print_state "$state" "$head" "${tape[@]}"
|
||||
local symbol=${tape[head]}
|
||||
local found=0 rule from input output move to
|
||||
for rule in "${rules[@]}"; do
|
||||
IFS=, read from input output move to <<<"$rule"
|
||||
if [[ $state == $from && $symbol == $input ]]; then
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if (( ! found )); then
|
||||
printf >&2 "Configuration error: no match for state=$state input=$sym\n"
|
||||
return 1
|
||||
fi
|
||||
tape[head]=$output
|
||||
state=$to
|
||||
case "$move" in
|
||||
L) if (( ! head-- )); then
|
||||
head=0
|
||||
tape=("$blank" "${tape[@]}")
|
||||
fi
|
||||
;;
|
||||
R) if (( ++head >= ${#tape[@]} )); then
|
||||
tape+=("$blank")
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
print_state "$state" "$head" "${tape[@]}"
|
||||
}
|
||||
|
||||
print_state() {
|
||||
local state=$1 head=$2
|
||||
shift 2
|
||||
local tape=("$@")
|
||||
printf '%s' "$state"
|
||||
printf ' %s' "${tape[@]}"
|
||||
printf '\r'
|
||||
(( t = ${#state} + 1 + 3 * head ))
|
||||
printf '\e['"$t"'C<\e[C>\n'
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Loading…
Add table
Add a link
Reference in a new issue