Family Day update

This commit is contained in:
Ingy döt Net 2020-02-17 23:21:07 -08:00
parent aac6731f2c
commit 9ad63ea473
2442 changed files with 39761 additions and 8255 deletions

View file

@ -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();
}
}
}

View file

@ -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

View file

@ -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()
}
}

View file

@ -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 "$@"