@PRodion

Как написать сложный алгоритм?

Есть массив:

var level = [
    [
        'один', // 4 буквы
        'два', // 3 буквы
        'три', // 3 буквы
        'четыре' // 6 букв

        // и того 16 букв
    ]
];


Стоит задача: разобрать слова из level[0] на отдельные буквы и вывести их в сетке, каждая буква - это отдельная ячейка сетки. Общее количество букв может меняться. Например: 16 (как в примере), 20 и т.д. Не могу понять как разобрать слова на буквы и как правильно формулировать сетку, точнее как сделать ее зависимой от количества букв. Например: 16 букв = 4*4, 20 букв = 4*5 и т.д. То есть, иметь возможность опционально указать пропорции сетки в зависимости от количества букв.

Возможно я изначально имею не правильное представление о реализации. Не разу такие сложные задачи не решал и сейчас очень тяжело понят с какой стороны браться. Очень надеюсь на какую любо помощь, возможно подскажете элегантный вариант реализация.
  • Вопрос задан
  • 565 просмотров
Пригласить эксперта
Ответы на вопрос 2
Labunsky
@Labunsky
Я есть на хабре
Не сложный алгоритм. Берешь таблицу, и начинаешь слева-направо:
1. Берешь слово;
2. Выбираешь первую попавшуюся свободную клетку (при обходе слева-направо, сверху-вниз, специально для longclaps. Сначала это угол, потом как пойдет);
3. Выбираешь случайное направление движения из доступных (должна быть хоть одна свободная клетка по этому направлению);
4. Начинаешь записывать слово по буквам, используя обход в глубину (ячейки клетки - вершины графа, ребра образуются между двумя свободными клетками, соединенными под прямым углом), с приоретитом на сохранение направления (никаких поворотов, кроме как при упоре в стенку);
5. Если есть еще слова - бери их и иди в п.1.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Например: 16 букв = 4*4, 20 букв = 4*5 и т.д. То есть, иметь возможность опционально указать пропорции сетки в зависимости от количества букв.
Квадратный корень из количества букв или ближайший извлекаемый квадратный корень из заданного числа (модульная разница которого меньше):
Условие: [общее кол-во букв = 20 ] <= x^2,
т.е. мы хотим поместить слова в максимально-квадратную область.

проверяем: x=2 => x^2=4 => мало.
проверяем: x=3 => x^2=9 => мало.
проверяем: x=4 => x^2=16 => мало.
проверяем: x=5 => x^2=25 => много. стоп.
Теперь, сравниваем:
abs(20-4^2)=4 < abs(20-5^2)=5
Т.е., мы выбираем максимальное приближение к искомому, а именно, число 4 и квадрат 4x4.
Затем, "довешиваем" (удлиняем) одну сторону квадрата до нужного числа (делаем прямоугольник), кратного перемножению короткой грани на только что созданную удлинённую на столько, чтобы могли поместиться все буквы.
Вот и будет как раз сетка: 4x5 (4x4+4=20)

Затем, заполняете всё нужными словами, а то, что останется - заполняете словом, с нужным (оставшимся) количеством букв.

Если возможно нужно как-то растянуто, но главное - чтобы всё влезло "впритык", то можно сразу искать через покрываемую площадь: S=X*Y и минимальную длину стороны, кратную числу всех букв и уже от этого отталкиваться...
Т.е., конечная задача найти НОД для пар значений: S и X, и для S и Y, где S нужное кол-во букв для всех слов.

Если число букв простое - то делается так же, как написано выше: ближайшим дополнением до произведения X*Y, превышающего общее кол-во букв на как можно меньшее количество добавочных клеток сетки (правда проще - найти нужное по размеру слово и заменить им короткое, или всегда следить за НУЖНОЙ кратностью суммарного числа всех букв в словах).

Укладывать слова в сетку можно по-спирали из любой точки внешнего периметра до полного кольца и затем, смещение к центру на 1 клетку и снова в том же направлении.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы