Задать вопрос
@PRodion

Как сделать распределение слов по ячейкам таблицы?

Есть многомерный массив.

var array = [
    [
        'один',
        'два',
        'три',
        'четыре'

        // всего 16 букв
    ]
];

Список слов из array[0] должен быть размещен в таблицу, каждая буква - это отдельная ячейка таблицы. Расположение слов в таблице - не имеет значения. Главная задача - оставить их читаемыми по одной из сторон.

|о|д|и|н|     |ч|е|т|ы|
|ч|е|р|т|     |т|д|о|р|
|е|т|ы|р|     |р|в|д|е|
|д|в|а|и| или |и|а|и|н|

Мне кажется что вставить их без разбора на буквы - нереально. Вся проблема в том, что некоторые слова могут быть "закручены" (не знаю как правильно сказать). Пример:

| | | | |     |ч|е|т|ы|
|ч|е|р| |     | | | |р|
|е|т|ы| |     | | | |е|
| | | | | или | | | | |

Разбор слов на буквы:

for(var value = 0; value < array[0].length; value++) { 
    for (var index = 0; index < array[0][value].length; index++) { 
        // console.log(array[0][value][index]);
    } 
}

Важные нюансы:
  1. Общее количество букв может быть больше чем 16.
  2. Ячеек по горизонтали может быть больше чем 4. По задумки их количество указывается опционально var cells = 4;.
  3. Ячеек по вертикали может быть ровно столько - сколько требуется для размещения всех слов.
  4. Пустых ячеек быть не должно.

Пример:
cells = 4     cells = 4
| | | | |     | | | | |
| | | | |     | | | | |
| | | | |     | | | | |
| | | | | или | | | | |
16 букв       | | | | |
              20 букв

Над этой задачей я сижу 3й день, с 10:00 до 23:00. Очень сложный для меня алгоритм. Буду рад любой помощи, любым советам относительно реализации.
  • Вопрос задан
  • 705 просмотров
Подписаться 1 Оценить 9 комментариев
Решение пользователя 0xD34F К ответам на вопрос (4)
0xD34F
@0xD34F Куратор тега JavaScript
Закрутите слова спиралью от краёв к центру. Типа так:

|о|д|и|н|
|е|т|ы|д|
|ч|е|р|в|
|и|р|т|а|

Собираете слова в одну строку, режете на отдельные символы - получаете массив букв всех слов. Создаёте двухмерный массив, изначально заполняете его элементы значениями-заглушками - null, например. Затем начинаете по нему двигаться от левого верхнего угла, заполняя символами слов. На каждом шаге проверяете следующий элемент, если его значение не null - значит вы достигли края массива или уже заполненной его части - меняете направление обхода (поворачиваете направо).

Как это может выглядеть:

function makeTable(data) {
  data = data.join('').split('');

  let width = Math.sqrt(data.length) | 0;
  let height = (data.length / width) | 0;

  while (width * height !== data.length) {
    width--;
    height = (data.length / width) | 0;
  }

  const position = [ 0, 0 ];
  const directions = [
    [  1,  0 ],
    [  0,  1 ],
    [ -1,  0 ],
    [  0, -1 ],
  ];
  let direction = 0;

  const result = Array.from({ length: height }, n => Array(width).fill(null));

  for (const n of data) {
    result[position[1]][position[0]] = n;

    if (null !== (result[position[1] + directions[direction][1]] || {})[position[0] + directions[direction][0]]) {
      direction = (direction + 1) % directions.length;
    }

    position[0] += directions[direction][0];
    position[1] += directions[direction][1];
  }

  return result.map(n => n.join(' ')).join('\n');
}

Примеры использования:

console.log(makeTable([ 'раз', 'два', 'три' ])); /*
р а з
р и д
т а в
*/
console.log(makeTable([ 'один', 'два', 'три', 'четыре' ])); /*
о д и н
е т ы д
ч е р в
и р т а
*/
console.log(makeTable([ 'hello', ',', ' ', 'world', '!!' ])); /*
h e
! l
! l
d o
l ,
r  
o w
*/

Ответ написан
Комментировать