Вы не указали входы или выходы, которые могут повлиять на используемые структуры данных. Например, вам может потребоваться сохранить только две строки или даже одну строку, если вы распечатываете их по мере их вычисления. Похоже, вы планируете сохранить все строки в массиве.
Похоже, у вас логическая ошибка в начальной строке:
if(firstTime == 1){
if(j == row-1) //print 1 in center of first row
arr[i][j] = 1;
else
arr[i][j] = 0;
}
должно быть
if(i == 0){
if(j == col / 2) //print 1 in center of first row
arr[i][j] = 1;
else
arr[i][j] = 0;
}
или что-то еще проще.
Алгоритм генерации других строк не так уж и сложен.
1) построить число от 0 до 7, используя элементы строки выше.
2) Побит & 1 << (число из 1) с правилом для получения результата </p>
parent = 0;
if(j>0 && arr[i-1][j-1]) parent = 4;
if(arr[i-1][j]) parent += 2;
if(j<col-1 && arr[i-1][j+1]) parent += 1;
position = 1 << parent;
arr[i][j] = (rule & position)?1:0;
Есть несколько очевидных способов сделать это быстрее. Например, создайте родительский элемент для этого столбца на основе родительского элемента предыдущего столбца и ячейки справа вверху: & с 3, сдвиг влево, | с содержимым клетки. Единственная неприятная часть - это обработка первого и последнего столбцов отдельно.
РЕДАКТИРОВАТЬ В ОТВЕТ НА КОММЕНТАРИЙ:
Алгоритм имеет несколько естественных реализаций в целых числах с битовыми операциями, отсюда и идея «правила XX».
В своей основе выбор текущего пространства определяется тремя пробелами над ним. Есть 8 возможностей для этого. Мы можем думать о них как о 8 битах байта.
Каждое правило - это соответствие из набора из 8 возможностей множеству {0,1}. Есть 2 ^ 8 = 256 возможных соответствий или правил, которые совпадают с количеством возможных значений для байта.
Наиболее удобный способ обозначить правила - это число, показывающее, как именно должна заполняться текущая ячейка, как это определено родительскими ячейками. Например,
правило 30:
30 = 16 + 8 + 4 + 2 = 2 ^ 4 + 2 ^ 3 + 2 ^ 2 + 2 ^ 1
Таким образом, правило заключается в том, чтобы заполнить ячейку, если родительские ячейки:
4 = 100
3 = 011
2 = 010
1 = 001
Для другого примера, каково правило, которое просто копирует предыдущую строку?
В этом случае мы заполняем ячейку, если указанная выше ячейка заполнена, но соседние ячейки могут быть любыми:
010 = 2
011 = 3
110 = 6
111 = 7
Итак, это правило 2 ^ 2 + 2 ^ 3 + 2 ^ 6 + 2 ^ 7 = правило 4 + 8 + 64 + 128 = правило 204.
Надеюсь, алгоритм определения ячейки теперь имеет больше смысла.
1) определить номер шаблона родителей.
2) определить, является ли шаблон 2 ^ частью правила. Если это так, заполните ячейку.
Другой комментарий, который у меня был, это то, сколько вам нужно хранить. Если вы выводите данные по ходу работы, вам нужна только одна строка массива (то есть только одно измерение). Когда вы пересекаете строку, вы можете заменить записи значениями для следующей строки. Единственная трудность заключается в том, что вам нужно каким-то образом сохранить текущее значение, которое вы заменяете, чтобы использовать его при определении следующей ячейки.
Но вы можете сохранить это значение и уменьшить количество вычислений тем же приемом: оставьте последний родительский номер; & это с 3, чтобы удалить левого родителя; сдвиньте его влево на 1; | это с родителем справа. Это дает вам текущий родительский номер. Будьте внимательны, чтобы правильно обработать конечные записи массива, и все готово.
ДРУГОЕ РЕДАКТИРОВАНИЕ:
Сначала реализуйте предыдущую версию, но если вы действительно хотите сходить с ума от экономии места и еще больше напрячь свой разум, попробуйте сохранить строку в виде битовых значений целого числа вместо массива 1 и 0. Если вы хотите, чтобы строка была даже длиннее, чем число битов в long, тогда вам нужен массив целых чисел, содержащих биты, и некоторая сумасшедшая битовая манипуляция для обработки ячеек на границе двух таких целых чисел. Веселись!