Рассмотрим булевой массив a[n]
, где каждый элемент является ячейкой. Ячейка становится живой (установлена в true
) в следующем поколении, если одна и только одна соседняя ячейка жива, в противном случае она становится мертвой (установлена в false
). Первая и последняя ячейки считаются соседями.Неиреративный алгоритм для жизни 1D жизни
Учитывая a[n]
, размер массива n
, и положительное целое число t
, я хочу, чтобы вычислить a[n]
после t'th поколения эволюции, но без использования каких-либо итерационного алгоритма на t
, который может быть потенциально очень большой.
То, что я заметил: если мы определим S_k(a[n])
быть циклический сдвиг из a[n]
справа от k
элементов. То есть, a[0]
становится a[k]
после одной смены, если 0 <= k < n
. Определите a[n]^b[n]
как элементную операцию xor между двумя булевыми массивами. Если w[n]
является логическим массивом, следующее поколение может быть выражено
r(w[n]) = S_{-1}(w[n])^S_1(w[n])
Оператор исключающее ^
ассоциативно и коммутативно. Используя это свойство, в ближайшие несколько поколений w[n]
могут быть вычислены с помощью
r^2(w[n]) = (S_{-2}(w[n])^S_0(w[n]))^(S_0(w[n])^S_2(w[n]))
= S_{-2}(w[n])^S_2(w[n])
Если мы позволим s_j = S_{-j}(w[n])^S_j(w[n])
, есть образец
r(w[n]) = s_1
r^2(w[n]) = s_2
r^3(w[n]) = s_3^s_1
r^4(w[n]) = s_4
...
r(s_m) = s_{m-1}^s_{m+1}
Кроме того, s_n = 0
(массив нулей), так как полный круговой shift - это исходный массив. Как это использовать для получения нетеративного выражения r^t(w[n])
?
Edit: Узор
[1]
[2]
[1,3]
[4]
[3,5]
[2,6]
[1,3,5,7]
[8]
Почему вам не нужен итеративный алгоритм на 't'? Даже если 't' * очень * большой, итеративный алгоритм в' O (log (t)) 'будет действительно эффективным. – fjardon