2011-09-16 12:39:57 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
2011-09-22 11:31:00 +00:00
|
|
|
class InfiniteArray:
|
|
|
|
def __init__(self, values=None):
|
|
|
|
self.chunks = {}
|
|
|
|
if values is not None:
|
|
|
|
for key, value in enumerate(values):
|
|
|
|
self[key] = value
|
|
|
|
|
|
|
|
def get_chunk(self, index):
|
|
|
|
if index not in self.chunks:
|
|
|
|
self.chunks[index] = [0 for i in xrange(4096)]
|
|
|
|
return self.chunks[index]
|
|
|
|
|
|
|
|
def __getitem__(self, index):
|
|
|
|
return self.get_chunk(index / 4096)[index % 4096]
|
|
|
|
|
|
|
|
def __setitem__(self, index, value):
|
|
|
|
self.get_chunk(index / 4096)[index % 4096] = value
|
|
|
|
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
class Machine:
|
2011-09-22 11:31:00 +00:00
|
|
|
def __init__(self, code, read, write, user_data=None, max_cycles=None):
|
|
|
|
self.user_data = user_data
|
|
|
|
self.read = read
|
|
|
|
self.write = write
|
|
|
|
self.mem = InfiniteArray([ord(char) for char in code])
|
2011-09-16 12:39:57 +00:00
|
|
|
self.exc_ptr = 0
|
|
|
|
self.mem_ptr = 0
|
2011-09-22 11:31:00 +00:00
|
|
|
self.max_cycles = max_cycles
|
|
|
|
self.cycles = 0
|
|
|
|
|
|
|
|
def cycle(self):
|
|
|
|
self.cycles += 1
|
|
|
|
if self.max_cycles is not None:
|
|
|
|
if self.cycles >= self.max_cycles:
|
|
|
|
return False
|
|
|
|
return True
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
def get_integer(self):
|
|
|
|
parameter = 0
|
|
|
|
while chr(self.mem[self.exc_ptr + 1]) >= '0' \
|
|
|
|
and chr(self.mem[self.exc_ptr + 1]) <= '9':
|
|
|
|
self.exc_ptr += 1
|
2011-09-22 11:31:00 +00:00
|
|
|
if not self.cycle():
|
|
|
|
return parameter
|
2011-09-16 12:39:57 +00:00
|
|
|
parameter = parameter * 10 + (self.mem[self.exc_ptr] \
|
|
|
|
- ord('0'))
|
|
|
|
if parameter == 0:
|
|
|
|
parameter = 1
|
|
|
|
return parameter
|
|
|
|
|
|
|
|
def L(self):
|
|
|
|
self.mem_ptr -= self.get_integer()
|
2011-09-22 11:31:00 +00:00
|
|
|
if self.mem_ptr < 0:
|
|
|
|
self.mem_ptr = 0
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
def R(self):
|
|
|
|
self.mem_ptr += self.get_integer()
|
|
|
|
|
|
|
|
def O(self):
|
2011-09-22 11:31:00 +00:00
|
|
|
self.write(chr(self.mem[self.mem_ptr]))
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
def I(self):
|
2011-09-22 11:31:00 +00:00
|
|
|
self.mem[self.mem_ptr] = ord(self.read(1))
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
def N(self):
|
|
|
|
self.exc_ptr += 1
|
|
|
|
search = self.mem[self.exc_ptr]
|
|
|
|
while self.mem[self.exc_ptr] != search:
|
|
|
|
self.exc_ptr += 1
|
2011-09-22 11:31:00 +00:00
|
|
|
if not self.cycle():
|
|
|
|
return
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
def P(self):
|
|
|
|
search = self.mem[self.exc_ptr + 1]
|
|
|
|
self.exc_ptr -= 1
|
|
|
|
while self.mem[self.exc_ptr] != search:
|
|
|
|
self.exc_ptr -= 1
|
2011-09-22 11:31:00 +00:00
|
|
|
if not self.cycle():
|
|
|
|
return
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
def J(self):
|
|
|
|
if self.mem[self.mem_ptr] != ord('0'):
|
|
|
|
search = self.mem[self.exc_ptr + 1]
|
|
|
|
self.exc_ptr -= 1
|
|
|
|
while self.mem[self.exc_ptr] != search:
|
|
|
|
self.exc_ptr -= 1
|
2011-09-22 11:31:00 +00:00
|
|
|
if not self.cycle():
|
|
|
|
return
|
2011-09-16 12:39:57 +00:00
|
|
|
|
|
|
|
def H(self):
|
|
|
|
self.mem[self.mem_ptr] = self.mem[self.mem_ptr] + 1
|
|
|
|
|
|
|
|
def K(self):
|
|
|
|
self.mem[self.mem_ptr] = self.mem[self.mem_ptr] - 1
|
|
|
|
|
2011-09-22 11:31:00 +00:00
|
|
|
def run(self, debug=False):
|
2011-09-16 12:39:57 +00:00
|
|
|
while True:
|
2011-09-22 11:31:00 +00:00
|
|
|
if self.mem[self.exc_ptr] == 0:
|
|
|
|
return
|
2011-09-16 12:39:57 +00:00
|
|
|
control = chr(self.mem[self.exc_ptr])
|
2011-09-22 11:31:00 +00:00
|
|
|
if debug:
|
|
|
|
print control
|
2011-09-16 12:39:57 +00:00
|
|
|
if hasattr(self, control):
|
|
|
|
getattr(self, control)()
|
|
|
|
self.exc_ptr += 1
|
2011-09-22 11:31:00 +00:00
|
|
|
if not self.cycle():
|
|
|
|
return
|
2011-09-16 12:39:57 +00:00
|
|
|
|
2011-09-22 11:31:00 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
Machine(sys.argv[1], sys.stdin.read, sys.stdout.write, None).run()
|