Метод 1 - Numpy
Этого можно добиться, используя следующую небольшую модификацию вашего текущего кода - изменив возвращаемое значение от rule30
до return np.array(next_row)
. Тогда вы можете использовать следующую функцию:
def apply_rule(n):
rv = initial_state(n)
while rv[-1][0] == 0:
rv = np.append(rv, rule30(rv[-1].reshape(1,-1)), axis=0)
return rv
Использование:
>>> apply_rule(7)
array([[0, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 0, 0, 1, 0],
[1, 1, 0, 1, 1, 1, 1]])
Или построено:
>>> plt.imshow(apply_rule(7), cmap='hot')
Метод 2 - Списки
В качестве альтернативы, вы можете использовать следующее решение без использования numpy, в котором используется несколько функций для применения логики правила 30 c ко всем каждая тройка в каждом дополненном списке, пока не будет выполнено условие остановки.
Код:
def rule(t):
return t[0] ^ (t[1] or t[2])
def initial_state(width):
initial = [0]*width
if width%2:
initial[width // 2] = 1
else:
initial.insert(width//2, 1)
return initial
def get_triples(l):
return zip(l,l[1:],l[2:])
def rule30(l):
return [rule(t) for t in get_triples([0] + l + [0])]
def apply_rule(width):
rv = [initial_state(width)]
while not rv[-1][0]:
rv.append(rule30(rv[-1]))
return rv
Использование:
>>> apply_rule(7)
[[0, 0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 0, 1, 0],
[1, 1, 1, 0, 0, 1, 1]]
>>> [''.join(str(y) for y in x) for x in apply_rule(7)]
['0001000',
'0011100',
'0111010',
'1110011']
Визуализация Matplotlib (с использованием любого метода):
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
plt.imshow(apply_rule(250), cmap='hot')