Как заполнить массив по спирали
Перейти к содержимому

Как заполнить массив по спирали

Тема: Вывод массива по спирали (Паскаль)

Вывод массива по спирали (Паскаль)

Есть простая задача. Вывести числа в массиве по спирали, например:
01 02 03 04
12 13 14 05
11 16 15 06
10 09 08 07

Для такого варианта задача решена.

var
s:array[1..n,1..m] of integer;
i,j,k,p:integer;

while i<n*m do
begin
k:=k+1;

for j:=m-k downto k do
begin
i:=i+1;
s[n-k+1,j]:=p;
p:=p+1;
end;

for j:=n-k downto k+1 do
begin
i:=i+1;
s[j,k]:=p;
p:=p+1;
end
end;

for i:=1 to n do
begin
for j:=1 to m do
write(s[i,j]:4,’ ‘);
writeln
end
end.

Но дальше — больше =)
Спираль может начинаться с любого внешнего элемента. Как это сделать?? Никто не подскажет??

  • Просмотр профиля
  • Сообщения форума
  • Записи в блоге
    За вклад в развитие форума 2006, Лучший знаток физики 2007, Самый активный автор месяца. Август 2007, Лучший консультант 2007, Лучший супермодератор 2007, Народный модератор раздела "Наука и Образование" 2008, Лучший супермодератор 2008, Лучший консультант 2008

В данном виде задача выглядит "заполнить квадратную матрицу (двумерный массив) числами от 1 до 16 в виде спирали"

Но я никак не могу сообразить, как спираль должна выглядеть, если она будет начинаться с произвольного места внешней оболочки.

  • Просмотр профиля
  • Сообщения форума
  • Записи в блоге
  • Домашняя страница

Так:
14 15 16 01 02
13 24 17 18 03
12 23 25 19 04
11 22 21 20 05
10 09 08 07 06

Либо так:
14 15 16 01 02
13 23 24 17 03
12 22 25 18 04
11 21 20 19 05
10 09 08 07 06

  • Просмотр профиля
  • Сообщения форума
  • Записи в блоге
    За вклад в развитие форума 2006, Лучший знаток физики 2007, Самый активный автор месяца. Август 2007, Лучший консультант 2007, Лучший супермодератор 2007, Народный модератор раздела "Наука и Образование" 2008, Лучший супермодератор 2008, Лучший консультант 2008

Второй вариант для заполнения проще. Будем ориентироваться на него.

Так. Вопрос подумать: пусть задана матрица NxN. Сколько элементов будет на внешнем квадрате?

Так вот — назовем это число — r.

Таким образом стартовое место можно задать либо числом q<=r, либо номером ячейки. Это — по вкусу.

Теперь возьмем прогонку по четырем сторонам.

В нашем случае для N=5 она распечатает

Или если это вытянуть в строку — будет последовательно печатать 01 02 03 . 15 16.

В Паскале есть операция остаток от деления: A mod B
Если мы возьмем этот массив по модулю 16, то получим 01 02 03 . 15 00.
Если нужно сдвинуть этот ряд на q ячеек, тогда нужно брать (A+q) mod 16
Сдвиг на три ячейки выглядит так: 14 15 00 01 . 12 13.
К каждой ячейке можно прибавить число. Так как у нас ряд начинается с единицы, то выражение будет вида ( (A+q) mod 16 ) + 1
Это даст 15 16 01 02 . 13 14.

Таким образом с помощью нехитрого выражения ( (A+q) mod 16 ) + 1
мы получаем сдвинутый внешний квадрат.

Теперь заполняем следующий квадрат той же идеей, только q будет другим, и начинать нужно не с единицы, а с 17. Все эти новые параметры вычисляются до возврата в начало основного цикла.

Как стать программистом

Это моя личная ссылка-приглашение на Stepik для вас. Регистрируясь по этой ссылке, записываясь на курсы и решая задачи, Вы помогаете автору данного сайта принять участие в конкурсе платформы Stepik! Подробности конкурса здесь: https://vk.cc/75rKuS

воскресенье, 27 октября 2013 г.

Занятие 19. Двумерные массивы.

Прочитайте улучшенную версию этого урока «Двумерные массивы».

  • Ещё более доступное объяснение
  • Дополнительные материалы
  • 10 задач на программирование с автоматической проверкой решения
Что такое двумерный массив?
Рис.1. Двумерный массив. Общий вид.
Рис.2 Двумерный массив, объявление.
Как работать с двумерным массивом?
Рис.3. Двумерный массив инициализированный при объявлении
Рис.4. Двумерный массив, инициализированный не полностью.
Как работать с отдельным элементом массива.
Рис.5. Обращение к элементу двумерного массива.
Рис.6. Двумерный массив. Поэлементный вывод на экран.
Зачем нужны двумерные массивы?

Напишите в комментариях пожалуйста, понятен ли вам этот пример, или лучше его подробно расписать?

Если этот материал кажется вам полезным, расскажите о нем друзьям используя кнопки основных социальных сетей, расположенные ниже.

Напишите программу, работающую следующим образом. Создайте массив 10 на 10. Заполните его нулями. Считайте два произвольных целых числа с клавиатуры, меньших либо равных 10. Первое число количество строк, второе — количество столбцов. Напишите функцию, которая заполняет массив по спирали и выводит его на экран. Т.е. если бы мы ввели 6 и 7, то получили бы следующий массив.

При этом табличка приблизительно должна быть выровнена по центру окна вывода.

Готовое решение пользователя с ником «Дмитрий». За проявленное упорство и трудолюбие, и как первый выполнивший правильно практическое задание, Дмитрий награждается печенькой:

57 комментариев :

Заебись. Красавчик. Так и к успеху скоро придешь. Пиши ещё.

Здравствуйте, подскажите пожалуйста, когда я выполняю построение проекта на visual c++, то консольное окно после выполнения программы сразу закрывается. Это началось пару дней назад. Не знаю почему. Что делать? Спасибо.

Добрый день. Ответ на ваш вопрос есть в F.A.Q.
http://youngcoder.blogspot.ru/p/blog-page_10.html

заинклудь и допиши в конце мэйна _getch();

Я пользуюсь командой system("pause"); в конце программы перед return 0;

народ, сделал ли кто это практическое задание(массив по спирали). хотелось бы глянуть, так как у самого ни чего не получилось=(

До какого момента вы уже дошли самостоятельно? ))
Какие есть идеи?

Дали в колледже почти аналогичное задание, только там нужно, чтобы элементы появлялись с задержкой (sleep). Я пытался делать спираль, но ее выводит построчно, а не по спирали.
Можете дать подсказку, как это можно сделать?

Подсказать что?!Показал бы код)
Мои предположения,что забыл printf("\n") добавить. Посмотри пример ниже. Я его вставил в цикл по for по i

Прогу разбил на 2 части,так как при переносе полного кода исчезают часть строк))
Я первый. мне печеньку)

Этот комментарий был удален автором.

Вы облегчили себе задачу. Ваша программа работает только с квадратными матрицами. =)) А в задаче, речь шла о произвольных. =))

Так что без печеньки. =)

//объявление двухмерного массива
// заполнение спиралью
#include ((stdio.h))
#include((iostream))
int main()
<
setlocale(LC_ALL,".1251");//
int mass[10][10]=<<0>>;//объявляем двумерный массив 10*10 и заполняем 0
int i=0,j=-1;//счётчики
int n,k,c=0,a=0,b=1;//номера строки и столбца
printf("Введите через пробел номер строки и столбца меньше 10\n");
scanf("%d %d",&n,&k);
while((j<(k-1))||(i<(n-1))) while(ja) <
if (mass[i][j-1]==0) mass[i][j-1]=++c;
j—;
>
a++;
while(i>b) <
if (mass[i-1][j]==0) mass[i-1][j]=++c;
i—;
>
b++;
>
for (i=0;i<10;i++) <
printf("\n");
for(j=0;j<10;j++) <
printf ("%4d",mass[i][j]);
>
printf("\n");
>
return(0);
>
Всё достаточно просто и понятно.Огромное спасибо.Жаль последний урок.

Кажется коряво копировалось, не работает.

Не последний, будут и другие. =)

KaDeaT, большое спасибо за уроки. было очень интересно. всего наилучшего)

Пожалуйста. надеюсь они вам помогли.
И это еще не конец. Заходите время от времени, быть может появится что-то новое. =))

Тогда мне печеньку.
#include

void fun_spiral (int [10][10], int, int);

int main ()
<
int str, stb;
int mass_a[10][10] = <>;

fun_spiral (mass_a, str, stb);

for (int i = 0; i < 10; i++)
<
for (int j = 0; j < 10; j++)
<
printf ("%i\t", mass_a[i][j]);
>//for
printf ("\n");
>//for str

void fun_spiral (int a[10][10], int str, int stb)
<
int z, b, x = 0, y = 1, chislo = 1;

while (chislo != z+1)//(a[str][x-1] != z)
<
for (b = x; b < stb; b++)
<
a[x][b] = chislo;
chislo++;
>//for

for (b = y; b < str; b++)
<
a[b][stb-1] = chislo;
chislo++;
>//for

for (b = stb-1; b > x; b—)
<
a[str-1][b] = chislo;
chislo++;
>//for

for (b = str-1; b > x; b—)
<
a[b][x] = chislo;
chislo++;
>//for

К сожалению, тоже без печеньки. =)
1. Код длинный, а Вы его в комментариях написали.
2. Эти нули излишний, лучше бы попробовали написать программу так, чтобы полученная табличка была выровнена по центру окошка. Это конечно дополнительное задание, но все же. Думаю стоит его добавить в условие задачи. )

Ссылка:
http://pastebin.ru/LAd8YZNS
Первое условие выполнено.
Второе условие, не честное, выполнено: нули убраны, табличка по центру.
Нули вывел потому, что в условии сказано заполнить массив нулями. я и подумал, что это не просто так, а чтобы их потом и вывести.

С первым согласен. Со втором нет. Табличка выровнена по центру лишь по горизонтали, а как же вертикальная составляющая? Ваш способ выравнивания немножечко извращен. Что если сдвинуть полученную матрицу на середину, а потом при выводе просто заменять нули пробелами?
И еще, сто штук одинаковых if — не порядок. Нужно подумать. =)))

Ссылка:
http://pastebin.ru/hNlxNutg
От if избавился причём понял как, но не сразу.
И всё по центру.

Вот это уже намного лучше. Хотя и тут есть один странный if, повторяющий условие цикла. Можно ли без него? Хотя печеньку вы уже заслужили. Посмотрите конец этого урока. ))

Спасибо, очень вкусно.
Без этого if даже если изменить условие
while (!(chislo >= z))
если ввести, к примеру, 7стр и 3стб
будет ошибка в таблице.
Так, что я пока не знаю как по другому.

Здравствуйте, в первую очередь хочу сказать вам огромное спасибо за ваш труд. Не мог долгое время начать заниматься, но благодаря вашим урокам стал обучаться программированию. Вы объясняете все просто и доступно. Самое главное все понятно и написано живым языком. Благодарен от души:)
Решил задание:
http://pastebin.ru/A6H3wYsJ

Решили, но не полностью и есть недочеты.
1. Размерность массива должен вводить пользователь, а не задавать её в программе.
2. Забыли про выравнивание по центру окошка.
3. Крайне неоптимально, три вложенных цикла это очень много. )))
Стоит немножко подумать и переделать. )))

Здравствуйте, переделал)
http://pastebin.ru/9aXLrLIx
не понял по поводу 2-го пункта, этого добиться за счет пробелов и табуляций?

http://pastebin.ru/wB3Tbvzb
#include "stdio.h"
#include "stdlib.h"

void spiral(int [10][10], int, int);

while((0 > a || a > 10) || (0 > b || b > 10))
<
printf("razmer matrici zadan ne verno!\n razmer matrici?\n");
scanf("%d %d", &a, &b);
>
spiral(arr_1, a, b);
return 0;
>

void spiral(int arr[10][10], int a, int b)
<

int count = a * b;
int numb_count = 0;
int f;
int j, i;
int c, d, e, g;
c = 0; d = 0;
e = a; g = b;
i = c; j = d;
int vert_otstup = (10 — a) / 2;
int hori_otstup = (10 — b) / 2;

while (numb_count < count)
<
if (count == 1)
<
for ((i = c + vert_otstup) && (j = d + hori_otstup); j < g; j++)
<
numb_count++;
printf("vvedite %d 4islo\n", numb_count);
scanf("%d", &f);
arr[i][j] = f;
>
>
else
<
//строка
for ((i = c + vert_otstup) && (j = d + hori_otstup); j < g + hori_otstup; j++)
<
numb_count++;
printf("vvedite %d 4islo\n", numb_count);
scanf("%d", &f);
arr[i][j] = f;
>
c++;

//столбец
for((j = g — 1 + hori_otstup) && (i = c + vert_otstup); i < e + vert_otstup; i++)
<
numb_count++;
printf("vvedite %d 4islo\n", numb_count);
scanf("%d", &f);
arr[i][j] = f;
>
g—;

//обратная строка
for((i = e — 1 + vert_otstup) && (j = g — 1 + hori_otstup); j >= d + hori_otstup; j—)
<
numb_count++;
printf("vvedite %d 4islo\n", numb_count);
scanf("%d", &f);
arr[i][j] = f;
>
e—;

Нет, так не пойдет. Программа должна сама заполнять массив, пользователь вводит только размерность. И код очень огромный, мне это не нравится. Можно сделать проще. )

//укоротил + самоприсваивание значение. Кажется этот варинат краше прежнего)
http://pastebin.ru/t7cT1Qjk
#include "stdio.h"

void spiral(int [10][10], int, int);

int main ()
<
int a;
int b;
int arr_1[10][10] = <<0>>;

spiral(arr_1, a, b);
return 0;
>

void spiral(int arr[10][10], int a, int b)
<

int count = a * b;
int numb_count = 0;
int j, i;
int c, d, e, g;
int a_ots = (10 — a) / 2;
int b_ots = (10 — b) / 2;
c = a_ots; d = a_ots;
e = a + b_ots; g = b + b_ots;
i = c; j = d;

while (numb_count = d; j—)//обратная строка
<
numb_count++;
arr[i][j] = numb_count;
>
e—;
for((i = e — 1) && (j = d); i > c — 1; i—)//обратный столбец
<
numb_count++;
arr[i][j] = numb_count;
>
d++;
>
//vivod massiva
for (int i = 0; i < 10; i++) < // 1 цикл
for (int j = 0; j < 10 ; j++) // 2 цикл
if(arr[i][j] == 0)
<
printf("\t");
>
else
<
printf("%d\t",arr[i][j]);
>
printf("\n");
>
>

Где-то ошибка. ввожу 5 8 ничего не выводит. )))

Добрый день!
У меня возник вопрос, вот я беру ваш код:
#include "stdio.h"
int main () <
int arr [2][4] = <<1,2,4>,<3,4>>;
for (int i=0; i<2; i++) < // 1 цикл
for (int j=0; j<4; j++) // 2 цикл
printf("%d\t",arr[i][j]);
printf("\n");
>
return 0;
>
он у меня не компилируется, и говорит что не объявлены i и j. Почему?

А в какой среде программирования вы работаете?

ни Visual c++ 2008, ни Dev c++

Хочу оценить лаконичность, но то, что вы залили свой код, как обычный текст мне очень мешает. Сделайте отправку использую опцию C++ или С

вроде нажимал как формать СИ. алгоритм работает на четырех частях цикла фор. после первого цикла еще добавил if (side_1==1) break; так как при вводе матрицы в одну строчку и два столбика,вместо "1,2" было "3,2" http://pastebin.ru/76UFuXmR

Плохо, т.к. не выполнено задание.
1. Заполнять массив должна отдельная функция, а у вас это делается внутри программы.
2. Программа зациклена, а должна отработать всего один раз.
3. Если код, который высвечивается в окне "Исходный текст", это то, как вы его написали, то вам стоит задумать над форматированием (отступы там и т.д.).
Поработайте над этим.)

еще было б неплохо указывать в заданиях приблизительный курс и семестр в универах где попадаются подобные задачи (задача. например курс первый семестр первый)чтоб хоть как то ориентироватся и понимать какого уровня пишут проги например на лаблаторных или дипломных

http://pastebin.ru/mNpcUlg9 прочитал вверху у кого то там что у него в матрице 7х3 например ошибка была, проверил и у меня тоже. уже исправил, лаконично не вышло, надо было вставить по if в каждый фор)))) остальное не вышло))))сделать отдельную функцию пока)). но у меня возник вопрос, почему в языке Си нельзя делать большие матрицы. например 800х800. ошибка вылетает. если например 700х700 оно считает конечно , но недоходит до конца и тоже вылетает. максимум что посчитало в спиральку это 500х500. в чем дело. например я несмогу в загрузить в массив изображение в 1000х1000 пикселов.

Все задачи в курсе не превосходят уровня 1 семестра 1 курса.
Я забыл еще упомянуть, что у вас очень много составных операторов <>. Не понимаю зачем их столько много.

Дело в том, что память под массив выделяется на стеке, поэтому когда вы задаете очень большой размер, для него не хватает памяти и всё слетает. Выход: динамические массивы, глобальные массивы.

Сможете, только для этого не используют массивы обычно.Есть специальные библиотеки для работы с изображениями. Вам не придется заботиться о массиве 1000х1000. Хранить 1 пиксель в 4 байтах это расточительство.

Требуется заполнить массив размера N × N единичками по спирали (начиная с верхнего левого угла по часовой стрелке, см. пример).

Входные данные
С клавиатуры вводится число N (нечетное, натуральное и не превышающее 50).

Выходные данные
Требуется вывести на экран построенную спираль.

Примеры
Входные данные
7
Выходные данные
1111111
0000001
1111101
1000101
1011101
1000001
1111111

Не могу понять как найти центральную точку чтобы от неё начать ставить

Как сделать 2-х мерный массив, но что бы количество столбцов и строк вводились самостоятельно.
Определить количество строк в которых есть "0". И сортировать строки от минимального до максимального.

создай переменные для считывания коль-ва строк и столбцов, после создай динамический массив с помощью указателей

int **mass = new int*[a];
for (int i=0;i<a;i++ )
____<
________mass[a]=new int[b];
____>
а после методом перебора(пузырька или как-то так админ его называл) более тяжелые елементы на дно

как передать в функцию двумерный и более массив. статичный и динамичный?

я так и не разобрался

в данном случае я не смог вывести всё одной формулой как в принципе и решить задание в целом
может позже

//Заполнение 2мерного массива по спирали
#include
#include

using namespace std;

void Funciklar( int **Mas, int sizeY, int sizeX )
<
____int Summ = sizeX * sizeY;
____int CorrectY = 0;
____int CorrectX = 0;
____int Count = 1;
____while( sizeY > 0 )
____<
________for ( int y = 0; y < 4; y++ )
________<
____________for ( int x = 0; x < ( ( sizeX < sizeY ) ? sizeY : sizeX ); x++ )
____________<
________________if ( y == 0 && x < sizeX — CorrectX && Count <= Summ )
________________Mas[y + CorrectY][x + CorrectX] = Count++;
________________if ( y == 1 && x < sizeY — CorrectY && x != 0 && Count <= Summ )
________________Mas[x + CorrectY][sizeX — 1] = Count++;
________________if ( y == 2 && x < sizeX — CorrectX && x != 0 && Count <= Summ )
________________Mas[sizeY — 1][sizeX — (x + 1)] = Count++;
________________if ( y == 3 && x < sizeY — ( CorrectY + 1 ) && x != 0 && Count <= Summ )
________________Mas[sizeY — (x + 1)][CorrectY] = Count++;
____________>
________>
________sizeY—;
________sizeX—;
________CorrectY += 1;
________CorrectX += 1;
____>
>

int main()
<
____setlocale(0,"");
____int x;
____int y;
____cout<<"Введите размерность матрицы X и Y\n";
____cin>>x>>y;
____cout<<"Матрица с размером "<<x<<"х"<<y<<endl;
____//создание
____int **matrix=new int*[x];
____for (int i=0;i<x;i++)
____<
________matrix[i]=new int[y];
____>
____//заполнение
____Funciklar(matrix, x, y);
____//вывод
____for(int a=0;a<x; a++)
____<
________for(int b=0;b<y;b++)
________<
____________cout<<matrix[a][b]<<"\t";
________>
________cout<<endl;
____>
____for (int i=0; i<x;i++)
____<
________delete[] matrix[i];
____>
____delete[] matrix;
____return 0;
>
Решил вернуться к заданию, тернарные функции упрощают жизнь.
Если серьезно то код практически копирован из интернета. щас уже лень завтра буду разбирать

я так похвастаться
друг на 2 курсе учится дал задание с матрицами на выполнение
это конечно не по спирали заполнить но
//Матрица и манипуляции
#include
#include
#include
#include
#include
#include

using namespace std;

void zapolnenie(int **matrix, int *sizeX, int *sizeY)
<
____cout<<"Хотите ввести данные вручную? y | n \nВ ином случае данные будут взяты из файла "<>yn;
____>while((strncmp(strlwr(yn),"y",1)!=0) && (strncmp(strlwr(yn),"n",1)!=0) );
____//выбор ввода

____if(strncmp(strlwr(yn),"y",1)==0)//если Y
____<
________for(int i=0; i<*sizeX; i++, cout<>*znach;
________________cout<<"matrix["<<i<<"]["<<ii<<"]="<<*znach;
________________matrix[i][ii]=*znach;
________________delete znach;
____________>
________>

>//Ввод данных в матрицу(либо вручную, либо из файла)
void copy_tran (int **matrix, int **matrixT, int *sizeX, int *sizeY)
<
____for (int i=0;i<*sizeX; i++)
____<
________for (int ii=0; ii<*sizeY; ii++)
________<
____________matrixT[ii][i]=matrix[i][ii];
________>
____>
____cout<<"Транспорированая матрица"<<endl;
____for (int i=0; i<*sizeY; i++, cout<<endl)
____<
________for (int ii=0; ii<*sizeX; ii++)
________<
____________cout<<"\t["<<i<<"]["<<ii<<"]="<<matrixT[i][ii];
________>
____>
>//передача значений в транспорированую копию
int **multipl (int **matrix, int **matrixT, int *sizeX, int *sizeY)
<
____int **matrixM;// создание перемноженого массива
____matrixM=new int*[*sizeY];
____for (int i=0; i<*sizeY; i++)
____<
________matrixM[i]=new int[*sizeY];
____>
____//заполнение и вывод
____cout<<"Произведение матрицы на транспорированую мартрицу"<<endl;
____int *summ=new int;
____for (int i=0;i<*sizeX; i++, cout<<endl)
____<
________for (int j=0; j<*sizeX; j++)
____________<
____________for (int p=0; p<*sizeY; p++)
____________<
________________*summ=(matrix[i][p]*matrixT[p][j]);
____________>
____________matrixM[i][j]=*summ;
____________cout<<"\t["<<i<<"]["<<j<<"]="<<matrixM[i][j];
____________*summ=0;
________>
____>
____return matrixM;
>
int main()
<
____srand(time(NULL));
____setlocale(LC_ALL, "rus");
____int *sizeX=new int, *sizeY=new int, **matrix, **matrixT;
____cout<<"Введите размеры матрицы = ";
____cin>>*sizeX>>*sizeY;
____cout<<endl;

____matrix=new int *[*sizeX];
____for (int i=0; i<*sizeX; i++)<
________matrix[i]=new int [*sizeY];
____>//оригинал

____matrixT=new int *[*sizeY];
____for (int i=0; i<*sizeY; i++)<
________matrixT[i]=new int [*sizeX];
____>//транспонир

____zapolnenie(matrix, sizeX, sizeY);//заполнение
____copy_tran(matrix, matrixT, sizeX, sizeY);//копирование данных
____multipl (matrix, matrixT, sizeX, sizeY);//умножение матриц
____return 0;
>

суть такова есть матрица которую нужно траспарировать и помножить на оригинал

размеры матрицы задаю я сам, при этом во всю юзаю указатели уже( блин удалить матрицы забыл.
я уже коснулся классов, круть я решаю практические задания 2 курса, и я сам до этого дошёл
в действительности чем больше начинаешь знать тем проще пытаешься выполнить задание

/dev/energy

Сайт о том, как стать программистом и как с этим жить потом

Обход массива по улитке.

Не так давно мне на глаза попалась задачка, которую кому-то из хабравчан предложили для решения на собеседовании. Суть ее состояла в том, чтобы заполнить квадратную матрицу с размерностью n*n числами от 1 до n^2 по спирали, закручивающейся от элемента [0, 0] к центру по часовой стрелке.

Поняв, что мысль о решении не дает мне покоя, я взялся вспоминать первый курс института ��

Минут 20 я рисовал квадратные матрицы разных размеров, пытаясь выявить закономерности, которые помогут упростить алгоритм обхода. Я выделил несколько интересных особенностей:

1. Каждый угловой элемент «улитки» (тот элемент, на котором происходит очередной поворот) можно легко рассчитать по формуле, зная размерность матрицы и номер шага:

Смещение — это сдвиг от «края» матрицы. Ведь на каждой итерации угловые элементы приближаются к центру. Соответственно, он меняется с каждым шагом. Изначально он равен 0. Для следующего шага (s+1) он рассчитывается так:

2. Зная угловой элемент и направление движения на следующем шаге, можно легко заполнить недостающие элементы.

Что ж, думаю, что этих вещей вполне достаточно для реализации задачи. На мой взгляд, главной изюминкой решения является идея с угловыми элементами. Мы сокращаем вычисления, сводя заполнение «неугловых» ячеек простым инкрементированием.

Я думаю, что в самой статье приводить листинг кода не нужно, а любой заинтересовавшийся может легко скачать код из репозитория.

Использование класса Snail очень простое. Мы создаем новый объект и вызываем у него метод cookSnail(int $length), где $length — это размерность квадратной матрицы.

Текущая версия легко «готовит» и выводит «улитку» со стороной до 550 ячеек. А попробовать программу в действии можно тут:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *