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

У вас есть доска 8X8 с номерами от 1 до 64.
Она выглядит так:

Вам нужно написать код, который вращает доску по часовой стрелке, чтобы число «1» было в положении «8», число «2» было в положении «16» и так далее…

вот как это должно выглядеть после поворота:

Итак, приступим к работе!

сначала давайте нарисуем доску с числами внутри.
я установлю размер матрицы равным 8 и создам простой двойной цикл for, чтобы создать каждую ячейку и поместить в нее правильное число.
каждая ссылка на ячейку имеет координаты {x, y}, поэтому координаты числа «1» будут равны {0,0}, а числа «2» будут иметь координаты {1,0} и так далее.

Я создал файл «index.html», который содержит элемент div с идентификатором «matrix», кнопку с идентификатором «rotate», которую я буду использовать для запуска функции поворота, ссылку на файл «styles.css». и в файл «index.js», который будет содержать наш код.

давайте продолжим, создав файлы styles.css и index.js.

файл styles.css очень прост. мы определяем матричный div и блоки внутри.
Я установил ширину матрицы в 200 пикселей с помощью «display: flex» и «flex: wrap», чтобы каждый коробка будет сидеть рядом с ее соседом. Каждое поле имеет ширину и высоту 25 пикселей, поэтому в каждой строке я увижу 8 полей.
Я также немного изменил стиль корпуса и кнопки, чтобы они выглядели лучше.

теперь к файлу index.js.
сначала мы создаем ссылку на матричный элемент DOM.
затем мы создаем счетчик для «цикла for», который я буду увеличивать на 1 на каждой итерации, и GRID_SIZE const со значением 8.

затем мы создаем двойной цикл for и внутри него создаем элемент DOM box, добавляем к нему класс «box», добавляем текущее значение счетчика в box innerHTML и присоединяем box внутри матричного элемента.

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

теперь самое сложное — как повернуть матрицу?
давайте задумаемся. при вращении матрицы числа «заменяют» места. Я объясню:

цифра «1» заменяет цифру «8».
цифра «8» заменяет цифру «64».
цифра «64» заменяет цифру «57»
а цифра «57» заменяет цифру «1».

то же самое касается числа «2»:
2 => 16 => 63 => 49 => 2 :-)

давайте углубимся и посмотрим, как меняются координаты {x,y} каждого числа:
1 {0,0} ‹= 57 {0,7} ‹= 64 {7,7} ‹= 8 {7,0} ‹= 1 {0,0}
2 {1,0} ‹= 49{0,6} ‹= 63 {6,7} ‹= 16 {7,1} ‹= 2 {1,0}
можете ли вы определить закономерность??? Посмотрим:

  1. позиция номера «1» принимает значение из позиции «57»
  2. позиция числа «57» берет значение из позиции «64»
  3. позиция числа «64» принимает значение из позиции «8»
  4. позиция номера «8» принимает значение из исходной позиции «1»

то же самое касается следующей серии чисел:

  1. позиция числа «2» принимает значение из позиции «49»
  2. номер позиции «49» берет значение из позиции «63»
  3. позиция числа «63» принимает значение из позиции «16»
  4. позиция номера «16» берет значение из исходной позиции «2»

original означает, что нам нужно запомнить исходное значение от первого числа до того, как мы его изменили. cleaver!
Итак, теперь все, что нам нужно сделать, это написать функцию «вращателя», которую мы будем запускать каждый раз и заменять значения 4 чисел друг на друга. легкий!

так что подытожим:

  1. создайте многомерный массив, содержащий элемент DOM box, чтобы мы могли получить доступ к DOM и получить значение этого блока.
  2. создайте функцию «rotateMatrix», которая получает координаты x, y первого поля, которое нам нужно заменить.
  3. создайте функцию «вращателя», которая выполняет переключение и заменяет значение во всех 4 полях, начиная с первого поля, которое мы получили из координат x, y.

Теперь давайте напишем немного кода, начнем с самого простого — создадим многомерный массив, содержащий DOM-элемент box:

в строке 2 я добавил ссылку «повернуть» на кнопку. мы будем использовать его, чтобы вращать матрицу, щелкая по ней.
в строке 5 я добавил массив «матрицы», который будет удерживать блоки.
в строке 9 я создал массив строк.
в строке 16 я добавил элемент DOM box в строку.
в строке 18 я добавил строку в матрицу.

теперь создайте функцию «rotateMatrix»:

перебираем x и y и отправляем в функцию «вращатель», которую мы скоро напишем. обратите внимание на значение y, которое я инициирую каждый цикл со значением x, поэтому первая пара аргументов, отправляемых «вращателю», равна {0,0}, а следующая — {0,1}, и вы поняли…

теперь самое интересное — «ротатор»

я объясню, используя значения x=0, y=0:
матрица доступа к строке 2[0][0].
матрица доступа к строке 3[8–0–1][0] ( matrix[7][0]).
строка 4 доступа к матрице[8–0–1][8–0–1] (matrix[7][7]).
строка 5 доступа к матрице[ 0][8–0–1] (matrix[0][7]).
получены все 4 поля!!!
строка 6 сохраняет значение первого поля прежде чем я изменю его.
строка 7 изменяет значение первого поля (topLeft) на предыдущее поле (bottomLeft).
строка 8 изменяет значение предыдущего поля (bottomLeft) со значением поля, которое стоит перед этим (bottomRight).
строка 9 изменяет значение предыдущего поля (bottomRight) на поле, которое стоит перед ним (topRight).
строка 10 заменяет последнее поле (topRight) на >исходное значение первого поля

давайте попробуем (нажмите кнопку поворота)!!

номер «1» не на том месте, где он должен быть, и все числа перепутаны.
что-то пошло не так…
если вы посмотрите на функцию «rotateMatrix», вы увидите, что она работает на все ящики — так делать нельзя!!!
почему? потому что функция «вращатель» изменяет значение 4 полей в каждом прогоне, поэтому в первой строке все в порядке, но во второй строке мы не должны передавать последнее поле, потому что оно уже было изменено, когда мы запускали первую строку!

поэтому мы быстро исправим функцию «rotateMatrix» следующим образом:

обратите внимание на изменение в строке 3 при условии, которое имеет значение:

y < GRID_SIZE — x — 1

теперь давайте попробуем еще раз и нажмем кнопку поворота:

наконец-то я заработал. yheee!!!
полный рабочий файл index.js — здесь
полный рабочий демо

это все люди.