Skip to content

Instantly share code, notes, and snippets.

@RIscRIpt
Created April 7, 2016 20:28
Show Gist options
  • Save RIscRIpt/b7e6fb3080b43e80809680900746a058 to your computer and use it in GitHub Desktop.
Save RIscRIpt/b7e6fb3080b43e80809680900746a058 to your computer and use it in GitHub Desktop.
Turing machine written in PY3, which converts unary number to binary
import os
import numpy as np
from collections import deque
clear = lambda: os.system('cls' if os.name=='nt' else 'clear')
class TuringTape:
def __init__(self, initial_data, empty_symbol):
self.data = deque(initial_data)
self.base_offset = 0
self.empty_symbol = empty_symbol
def __str__(self):
return '[' + ']['.join(self.data) + ']'
def safe_index(self, index):
index += self.base_offset
if index >= len(self.data):
count = index - len(self.data) + 1
if count > 0:
self.expand_right(count)
elif index < 0:
positions = -index
self.shift_right(positions)
self.base_offset += positions
index = 0
return index
def expand_right(self, count):
while count > 0:
self.data.append(self.empty_symbol)
count -= 1
def shift_right(self, positions):
while positions > 0:
self.data.appendleft(self.empty_symbol)
positions -= 1
def shrink(self):
while self.data[+0] == self.empty_symbol:
self.data.popleft()
while self.data[-1] == self.empty_symbol:
self.data.pop()
def Get(self, index):
return self.data[self.safe_index(index)]
def Set(self, index, symbol):
index = self.safe_index(index)
self.data[index] = symbol
if symbol == self.empty_symbol:
self.shrink()
class TuringCommand:
def __init__(self, next_state, output, movement):
self.next_state = next_state
self.output = output
self.movement = movement
def __str__(self):
if self.movement == +1:
movement = '>'
elif self.movement == -1:
movement = '<'
else:
movement = '|'
return '{}:{{{}}}:{}'.format(self.next_state, self.output, movement)
class TuringMachine:
def __init__(self, tape, tape_head, init_state, end_state, command_table):
self.iteration = 0
self.tape = tape
self.tape_head = tape_head
self.state = init_state
self.end_state = end_state
self.command_table = command_table
self.completed_commands = []
@property
def Finished(self):
return self.state == self.end_state
def Tick(self):
if self.Finished:
return
self.iteration += 1
# Getting current command, according to
# current symbol and current state
symbol = self.tape.Get(self.tape_head)
try:
command = self.command_table[self.state][symbol]
except KeyError as e:
raise Exception("No command defined for the state `{}` and symbol `{}`".format(self.state, symbol))
# Perform the command
self.tape.Set(self.tape_head, command.output)
self.state = command.next_state
self.tape_head += command.movement
# Post-command actions
self.tape.Get(self.tape_head) # make sure the cell exists
self.completed_commands.append(command)
def Display(self):
print("Iteration:", self.iteration)
print(self.tape)
print(' ' * ((self.tape_head + self.tape.base_offset) * 3), '^')
#print(', '.join(map(str, self.completed_commands)))
def main():
MOVE_LEFT = -1
MOVE_RIGHT = +1
MOVE_NONE = 0
tape = TuringTape(list("=||||||||||||"), ' ')
cmd_table = {
0: { #Initial state
'=': TuringCommand(next_state=9, output=' ', movement=MOVE_LEFT),
'|': TuringCommand(next_state=1, output=' ', movement=MOVE_LEFT),
},
1: { #Moving left to the binary number, and increasing it
'|': TuringCommand(next_state=1, output='|', movement=MOVE_LEFT),
'=': TuringCommand(next_state=1, output='=', movement=MOVE_LEFT),
'1': TuringCommand(next_state=1, output='0', movement=MOVE_LEFT),
'0': TuringCommand(next_state=3, output='1', movement=MOVE_RIGHT),
' ': TuringCommand(next_state=3, output='1', movement=MOVE_RIGHT),
},
3: { #Moving back right to the beginning
'0': TuringCommand(next_state=3, output='0', movement=MOVE_RIGHT),
'1': TuringCommand(next_state=3, output='1', movement=MOVE_RIGHT),
'|': TuringCommand(next_state=3, output='|', movement=MOVE_RIGHT),
'=': TuringCommand(next_state=3, output='=', movement=MOVE_RIGHT),
' ': TuringCommand(next_state=0, output=' ', movement=MOVE_LEFT),
},
}
machine = TuringMachine(tape, tape_head=len(tape.data)-1, init_state=0, end_state=9, command_table=cmd_table)
while not machine.Finished:
machine.Tick()
machine.Display()
print("=" * 80)
input()
#clear()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment