996
|
1 #!/usr/bin/env python
|
|
2 from numarray import *
|
|
3 import sys
|
|
4
|
|
5 def dimensionSubstr(line):
|
|
6 a = enumerate(line)
|
|
7 try:
|
|
8 b = a.next()
|
|
9 except:
|
|
10 return ["", line]
|
|
11 try:
|
|
12 while 1:
|
|
13 if b[1] not in "0123456789": return [line[0:b[0]], line[b[0]:]]
|
|
14 b = a.next()
|
|
15 while b[1] != ".":
|
|
16 if b[1] not in "0123456789": return [line[0:b[0]], line[b[0]:]]
|
|
17 b = a.next()
|
|
18 b = a.next()
|
|
19 if b[1] == ".":
|
|
20 return None #syntax error
|
|
21 except:
|
|
22 return [line[0:b[0]], ""]
|
|
23
|
|
24 class Dimensifuck:
|
|
25 def __init__(self):
|
|
26 self.dimensions = 0
|
|
27 self.dimensionSizes = []
|
|
28 self.matrix = array(type=Int8)
|
|
29 self.tape = [0]
|
|
30 self.pointer = 0
|
|
31 def run(self, verbose=False):
|
|
32 location = [0] * self.dimensions
|
|
33 dimension = 0
|
|
34 nextDimension = 0
|
|
35 direction = 1
|
|
36 while 1:
|
|
37 op = self._getMatrixAt(location)
|
|
38 if verbose:
|
|
39 print "Location: ", location
|
|
40 print "Opcode:", "+-.,<>=_^vX "[op]
|
|
41 if op == 0:
|
|
42 self.tape[self.pointer] = (self.tape[self.pointer] + 1) & 255
|
|
43 elif op == 1:
|
|
44 self.tape[self.pointer] = (self.tape[self.pointer] - 1) & 255
|
|
45 elif op == 2:
|
|
46 print chr(self.tape[self.pointer]),
|
|
47 elif op == 3:
|
|
48 self.tape[self.pointer] = ord(sys.stdin.read(1))
|
|
49 elif op == 4:
|
|
50 self.pointer -= 1
|
|
51 if self.pointer < 0:
|
|
52 self.tape = [0] + self.tape
|
|
53 self.pointer = 0
|
|
54 elif op == 5:
|
|
55 self.pointer += 1
|
|
56 if self.pointer == len(self.tape):
|
|
57 self.tape.append(0)
|
|
58 elif op == 6:
|
|
59 nextDimension += 1
|
|
60 elif op == 7:
|
|
61 nextDimension -= 1
|
|
62 elif op == 8:
|
|
63 if self.tape[self.pointer]:
|
|
64 dimension = nextDimension
|
|
65 direction = 1
|
|
66 elif op == 9:
|
|
67 if self.tape[self.pointer]:
|
|
68 dimension = nextDimension
|
|
69 direction = -1
|
|
70 elif op == 10:
|
|
71 return self.tape[self.pointer]
|
|
72 location[dimension] += direction
|
|
73 def loadMatrix(self, code):
|
|
74 self.dimensions = 0
|
|
75 code = [dimensionSubstr(i) for i in code.split('\n')]
|
|
76 lines = []
|
|
77 for i, j in enumerate(code):
|
|
78 if j is None:
|
|
79 print "Syntax error on line ", i
|
|
80 return False
|
|
81 if j[0]:
|
|
82 lines.append(j)
|
|
83 self.dimensions = max(self.dimensions, j[0].count(".") + 2)
|
|
84 else:
|
|
85 lines[-1][1] += j[1]
|
|
86 self.dimensionSizes = [0] * self.dimensions
|
|
87 for i in xrange(len(lines)):
|
|
88 lines[i][0] = [len(lines[i][1])] + [int(j) for j in lines[i][0].split(".")]
|
|
89 lines[i][0] += [0] * (len(lines[i][0]) - self.dimensions)
|
|
90 for i in xrange(self.dimensions):
|
|
91 self.dimensionSizes[i] = max([a[0][i] + 1 for a in lines])
|
|
92 for i in xrange(self.dimensions):
|
|
93 self.matrix = array([-1], type=Int8)
|
|
94 self.matrix.resize(self.dimensionSizes)
|
|
95 for i in lines:
|
|
96 location = list(i[0])
|
|
97 location[0] = 0
|
|
98 for j in i[1]:
|
|
99 self._setMatrixAt(location, self._getValue(j))
|
|
100 location[0] += 1
|
|
101
|
|
102 def loadFile(self, filename):
|
|
103 self.loadMatrix(file(filename, "r").read())
|
|
104
|
|
105 def _getMatrixAt(self, location):
|
|
106 for i in location:
|
|
107 if i < 0:
|
|
108 return 10
|
|
109 try:
|
|
110 return reduce(lambda x, y: x[y], location, self.matrix)
|
|
111 except:
|
|
112 return 10
|
|
113 def _setMatrixAt(self, location, value):
|
|
114 array = self.matrix
|
|
115 while len(location) > 1:
|
|
116 array = array[location[0]]
|
|
117 location = location[1:]
|
|
118 array[location[0]] = value
|
|
119 def _getValue(self, char):
|
|
120 return "+-.,<>=_^vX".find(char)
|
|
121
|