Фон
В типографии реки являются визуальными пробелами в блоке текста, которые возникают из-за совпадения пробелов. Это особенно раздражает, так как ваш мозг, кажется, легче воспринимает их при периферийном зрении, которое постоянно отвлекает ваши глаза.
В качестве примера возьмем следующий блок текста, строки которого разбиты так, что ширина строки не превышает 82 символов :
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor
incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eismod tempor incididunt ut labore et dolore
maga aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
est laborum.
В нижней правой части есть река, охватывающая шесть линий, которые я выделил в следующем блоке:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor
incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
officia deserunt mollit anim id est laborum. Lorem█ipsum dolor sit amet,
consectetur adipisicing elit, sed do eismod tempor█incididunt ut labore et dolore
maga aliqua. Ut enim ad minim veniam, quis nostrud█exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute█irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla█pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui█officia deserunt mollit anim id
est laborum.
Мы можем смягчить это, выбрав немного другую ширину столбца. Например, если мы размещаем один и тот же текст, используя строки длиной не более 78 символов , река не длиннее двух строк:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eismod tempor
incididunt ut labore et dolore maga aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt
in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor
sit amet, consectetur adipisicing elit, sed do eismod tempor incididunt ut
labore et dolore maga aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
Обратите внимание, что для целей этого вопроса мы рассматриваем только моноширинные шрифты, так что реки - это просто вертикальные столбцы пространств. Длина реки - это количество линий, которые она охватывает.
Если вы интересуетесь обнаружением реки пропорциональными шрифтами, в сети есть несколько интересных постов .
Соревнование
Вам дана строка печатных символов ASCII (кодовая точка от 0x20 до 0x7E) - то есть одна строка. Напечатайте этот текст с шириной строки от 70 до 90 символов (включительно), чтобы максимальная длина любой реки в тексте была минимальной. Если имеется несколько значений ширины текста с одинаковой (минимальной) максимальной длиной реки, выберите более узкую ширину. Приведенный выше пример с 78 символами является правильным выводом для этого текста.
Чтобы разбить строки, необходимо заменить пробелы (0x20) на разрывы строк, чтобы в результирующих строках было как можно больше символов, но не больше выбранной ширины текста. Обратите внимание, что результирующий разрыв строки сам по себе не является частью этого количества. Например, в последнем блоке выше Lorem[...]tempor
содержится 78 символов, что также является шириной текста.
Вы можете предположить, что входные данные не будут содержать последовательные пробелы и не будут иметь начальных или конечных пробелов. Вы также можете предположить, что ни одно слово (последовательная подстрока без пробелов) не будет содержать более 70 символов.
Вы можете написать программу или функцию, принимая ввод через STDIN, аргумент командной строки или аргумент функции и печатая результат в STDOUT.
Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.
источник
Ответы:
CJam,
116 106 99 84 7772 байтаПринимает однострочный ввод и печатает правильный вывод в STDOUT.
ОБНОВЛЕНИЕ : Улучшено много и удалены лишние циклы, выполнив все вычисления в самом цикле сортировки. Также исправлена ошибка в расчете длины реки.
Объяснение скоро (после того, как я играю в гольф это еще дальше)
Попробуй здесь
источник
ea~
вместоX
каждого раза. Сохраняет два байта.Рубин
162 160 158 152 160157 ( демо )Версия без гольфа:
источник
%r{...}
позволяет мне использовать интерполяцию строк. Я только что попробовал21.times
, но у этого есть еще некоторые последствия в будущем, и мне не удалось найти более короткое решение.APL (105)
Объяснение:
(K⊂⍨' '=K←' ',⍵)
: Добавить пробел перед⍵
, а затем разделить⍵
на пробелы. Каждое слово сохраняет место, с которого оно начинается.∘{
...}¨70+⍳21
: с этим значением для каждого числа в диапазоне[71, 91]
: (Из-за того, как слова разделяются, каждая «строка» заканчивается дополнительным пробелом в начале, который будет удален позже. Диапазон сдвигается на один, чтобы компенсировать дополнительное пространство.)×⍴⍺:
: если еще остались слова,z←⍵>+\≢¨⍺
: получить длину для каждого слова и вычислить итоговую сумму длины для каждого слова. Отметьте1
все слова, которые можно взять, чтобы заполнить следующую строку, и сохраните это вz
.(⊂z/⍺),⍵∇⍨⍺⍨~z
: возьми эти слова, а затем обработай то, что осталось от списка.⋄⍺
: если нет, вернуть⍺
(который теперь пуст).G←
: сохранить список списков строкG
(по одному на каждую возможную длину строки).V←{
...}¨G
: для каждой возможности рассчитайте длину самой длинной реки и сохраните ее вV
:+\↑≢¨¨⍵
: получить длину каждого слова (снова) и составить матрицу из длин. Вычислите промежуточные суммы для каждой строки в строках матрицы. (Таким образом, лишний пробел в начале каждой строки игнорируется.)2≠⌿
: для каждого столбца матрицы посмотрите, не соответствует ли текущая длина линии в этой точке линии после нее. Если так, то там нет реки.⊂⍨¨↓⍉
: разделить каждый столбец матрицы по отдельности (по1
s). Это дает список списков, где для каждой реки будет список[1, 0, 0, ...]
, в зависимости от длины реки. Если реки нет, список будет[1]
.⌈/≢¨
: получить длину каждой реки и получить максимальное значение этого.⊃G/⍨V=⌊/V
: fromG
выберите первый элемент, для которого длина самой длинной реки равна минимальной для всех элементов.{1↓∊⍵,3⊃⎕TC}¨
: для каждой строки соедините все слова вместе, удалите первый элемент (лишний пробел в начале) и добавьте новую строку в конец.∊
: соединить все линии вместе.источник
Bash + coreutils,
236157 байтОтредактировано с другим подходом - немного короче, чем раньше:
Читает входную строку из командной строки.
С 3-мя вложенными сортировками я не могу понять, какова сложность времени с большим количеством O для этого, но он завершает пример менее чем за 10 секунд на моей машине.
источник
Python, 314 байт
Большое спасибо SP3000, grc и FryAmTheEggman:
источник
JavaScript (ES6) 194
202Итеративное решение, может быть короче, если сделать рекурсивным
Разъяснения
Тест в консоли FireFox / FireBug.
Выход
источник
Python 3, 329 байт
Безголовая версия:
источник