[ create a new paste ] login | about

Link: http://codepad.org/9PO8hpI7    [ raw code | fork ]

D, pasted on Feb 16:
import std.stdio, std.algorithm, std.conv, std.range, std.typecons,
       std.string, std.array;

struct UTM {
    enum : char {right, left, stay}

    private TapeHead head;
    private const TuringMachine tm;

    static struct TuringMachine {
        char[] symbols;
        char blank;
        char initialState;
        char[] haltStates, runningStates;
        char[][string] rules;
        char[] input;
    }

    static struct TapeHead {
        const char[] symbols;
        const char blank;
        char[] tape;
        size_t index;

        this(in ref TuringMachine t) {
            this.symbols = t.symbols;
            this.blank = t.blank;
            this.tape = t.input.dup;
            if (tape.empty)
                tape = [blank];
            this.index = 0;
        }

        auto read() const pure nothrow {
            return this.tape[this.index];
        }

        void write(in char symbol) {
            .write(this);
            this.tape[this.index] = symbol;
        }

        void right() pure nothrow {
            this.index++;
            if (index == tape.length)
                tape ~= blank;
        }

        void left() pure nothrow {
            if (this.index == 0)
                this.tape = this.blank ~ this.tape;
            else
                this.index--;
        }

        void stay() const pure nothrow {
            // Do nothing.
        }

        void move(in char dir) {
            switch (dir) {
                case UTM.left:  left();  break;
                case UTM.right: right(); break;
                case UTM.stay:  stay();  break;
                default: assert(0);
            }
        }

        string toString() const {
            return text(tape) ~ '\n'
                   ~ format("%" ~ text(index + 1) ~ "s", "^")
                   ~ '\n';
        }
    }

    this(const ref TuringMachine tm_) {
        this.tm = tm_;
        this.head = TapeHead(this.tm);

        char state = this.tm.initialState;
        while (true) {
            if (tm.haltStates.canFind(state))
                break;
            if (!tm.runningStates.canFind(state))
                throw new Exception("Unknown state.");
            auto symbol = this.head.read();
            auto rule = this.tm.rules["" ~ state ~ symbol];
            this.head.write(rule[0]);
            this.head.move(rule[1]);
            state = rule[2];
        }
    }
}

void main() {
    writeln("Incrementer:");
    immutable UTM.TuringMachine tm1 = {
        symbols: ['0', '1'],
        blank: '0',
        initialState: 'A',
        haltStates: ['H'],
        runningStates: ['A'],
        rules: ["A1": ['1', UTM.right, 'A'],
                "A0": ['1', UTM.left,  'H']],
        input: ['1', '1', '1']
    };
    UTM(tm1);

    writeln("\nBusy beaver machine:");
    immutable UTM.TuringMachine tm2 = {
        symbols: ['0', '1'],
        blank: '0',
        initialState: 'A',
        haltStates: ['H'],
        runningStates: ['A', 'B', 'C'],
        rules: ["A0": ['1', UTM.right, 'B'],
                "A1": ['1', UTM.left,  'C'],
                "B0": ['1', UTM.left,  'A'],
                "B1": ['1', UTM.right, 'B'],
                "C0": ['1', UTM.left,  'B'],
                "C1": ['1', UTM.stay,  'H']]
    };
    UTM(tm2);
}


Create a new paste based on this one


Comments: