Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue