You are on page 1of 3

class​ ​TuringVM​ {

​var​ ttuplesArray​:​ [​TTuple​]


​private​ ​var​ numberTuples​:​ ​Int
​init​(ttuplesArray​:​ [​TTuple​]) {
​self​.​ttuplesArray​ ​=​ ttuplesArray
​self​.​numberTuples​ ​=​ ttuplesArray.​count

​func​ tapeIntoArray(someTape​:​ ​String​) ​->​ [​Character​] {


​var​ tape ​=​ [​Character​]()
​for​ n ​in​ someTape {
tape.​append​(n)
}
​return​ tape
}

​func​ tupleReport() ​->​ ​String​ {


​return​ ttuplesArray.​reduce​(​""​,​ {$​0​ ​+​ $​1​.​description​ ​+​ ​"\n"​})
}

​func​ nakedTupleReport() ​->​ ​String​ {


​var​ tupleReport ​=​ ​"cs ic ns oc di\n"
​for​ n ​in​ ttuplesArray {
tupleReport ​+=​ ​"​\(​n.nakedTuple​())​\n"
}
​return​ tupleReport
}

​func​ tapeAsString(_ tape​:​ [​Character​]) ​->​ ​String​ {


​var​ outputString ​=​ ​""
​for​ n ​in​ tape {
outputString.​append​(n)
}
​return​ outputString
}
​func​ shiftDirection(_ direction​:​ ​Direction​) ​->​ ​Int​ {
​switch​ direction {
​case​ ​Direction​.​left​:​ ​return​ ​-​1
​case​ ​Direction​.​right​:​ ​return​ ​1
}
}

​func​ dict() ​->​ [​String​:​ ​TTuple​] {


​var​ data ​=​ [​String​:​ ​TTuple​]()
​for​ n ​in​ ttuplesArray {
data[n.​getKey​()] ​=​ n
}
​return​ data
}

​func​ printedTape(tape​:​ [​Character​]​,​ headPos​:​ ​Int​) ​->​ ​String​ {


​var​ current ​=​ tape
current.​insert​(​"["​,​ at​:​ headPos)
current.​insert​(​"]"​,​ at​:​ headPos ​+​ ​2​)
​return​ tapeAsString(current)
}

​func​ traceLine(data​:​ ​TTuple​,​ steps​:​ ​Int​,​ tape​:​ [​Character​]​,​ headPos​:​ ​Int​)


->​ ​String​ {
​return​ ​"​\(​steps​)​: {cs: ​\(​data.currentState​)​ ic: ​\(​data.inputChar​)​ ns:
\(​data.newState​)​ oc: ​\(​data.outputChar​)​ di: ​\(​data.direction​)​}
\(​printedTape​(​tape​:​ tape​,​ headPos​:​ headPos​))​"
}

​func​ runTuring(initialTape​:​ ​String​,​ initialState​:​ ​Int​,​ initialHead​:​ ​Int​)


->​ (numberSteps​:​ ​Int​,​ finalTape​:​ ​String​,​ trace​:​ [​String​]) {
​var​ tape ​=​ tapeIntoArray(someTape​:​ initialTape)
​var​ setNum ​=​ dict()
​var​ currentState ​=​ initialState
​var​ currentHead ​=​ initialHead
​var​ currentChar ​=​ tape[currentHead]
​var​ trace ​=​ [​String​]()
​var​ numSteps ​=​ ​0
​var​ key ​=​ ​TTuple​.​makeKey​(state​:​ currentState​,​inputChar​:​ currentChar)
​while​ setNum[key] ​!=​ ​nil​ {
numSteps ​+=​ ​1
​let​ newTup ​=​ setNum[key]​!
currentState ​=​ newTup.​newState
tape[currentHead] ​=​ newTup.​outputChar
currentHead ​+=​ shiftDirection(newTup.​direction​)
​if​ (currentHead ​>​ ​0​) ​&&​ (currentHead ​<​ tape.​count​) {
currentChar ​=​ tape[currentHead]
key ​=​ ​TTuple​.​makeKey​(state​:​ currentState​,​ inputChar​:​ currentChar)
} ​else​ {
setNum[key] ​=​ ​nil
}
trace.​append​(traceLine(data​:​ newTup​,​ steps​:​ numSteps​,​ tape​:​ tape​,
headPos​:​ currentHead))
}
​return​ (numSteps​,​ tapeAsString(tape)​,​ trace)
}
}

You might also like