Ваша задача состоит в том, чтобы отформатировать список слов в нескольких строках, длина которых не превышает заданного количества символов, чтобы каждая строка содержала как можно больше слов, и слова не были бы излишне обрезаны.
вход
На входе будет список слов, разделенных пробелами, а затем число, равное как минимум 4.
Выход
Выходными данными должны быть входные слова, сгруппированные в строки, чтобы ни одна из строк не содержала больше символов, чем входной номер. Слова должны быть выведены в порядке их ввода. Слова должны быть разделены запятой, а затем пробелом, за исключением конца каждой строки, где пробел не нужен. Если слово слишком длинное, чтобы поместиться в строке, его следует обрезать как можно меньше, следуя другим правилам, и в конце следует добавить «...».
Контрольные примеры
Input:
foo bar baz qux 12
Output:
foo, bar,
baz, qux
Input:
foo bar baz qux 5
Output:
foo,
bar,
baz,
qux
Input:
strength dexterity constitution intelligence wisdom charisma 10
Output:
strength,
dexterity,
consti...,
intell...,
wisdom,
charisma
Input:
quas wex exort 4
Output:
...,
wex,
e...
Ответы:
Не читается , 2559 байт
Эта задача очень подходит для нечитаемых.
Первая версия этого была 3379 байтов, просто чтобы дать вам представление о том, сколько я играл в гольф.
Программа принимает ввод в точности так, как описано в задании: разделенный пробелами список слов (который также может содержать цифры и знаки пунктуации), за которым следуют пробел и целое число, равное не менее 4 (нижние числа генерируют бесконечные циклы) ,
объяснение
Я собираюсь показать вам, как программа обрабатывает ввод
thyme horseradish peppermint 10
. Ожидаемый результатthyme,\nhorser...,\npeppermint
.Сначала мы начинаем с ячейки № 7 и читаем весь ввод, но вычитаем 32 из каждого символа, чтобы пробелы стали нулями.
По понятным причинам это оставляет текущий указатель (с именем p здесь, хранится в ячейке # 0) в конце. Мы используем один цикл while, чтобы найти последний пробел, который является началом числа, определяющего ширину вывода (ячейка # 36 в этом примере).
Теперь мы хотим декодировать число (то есть преобразовать из десятичного числа). Окончательный результат будет в обеих ячейках t и r . Мы полагаемся на то, что они начинаются с нуля.
Для каждой цифры в номере сделайте следующее:
'0'
должны'9'
иметь коды ASCII 48–57, поэтому после более раннего вычитания 32 они равны 16–25, поэтому мы фактически добавляем 15–24 к t , что отменяет с −15 мы установили это раньше. Также важно, чтобы это обнуляло ячейки, которые раньше содержали цифры, чтобы последующий код мог распознать конец списка слов.Наконец, мы используем другой простой цикл while (уменьшая t как счетчик), чтобы преобразовать только что вычисленное число в унарное. Мы храним строку 1 с, идущую влево от ячейки # 0. Это зависит от того факта, что ячейка # 1, наш рабочий указатель для этого ( q ), начинается с 0. Мы получаем на единицу меньше 1, потому что циклы while в Unreadable выглядят так:
После этого нам больше не нужно значение в r , поэтому мы повторно используем эту ячейку для чего-то другого. Мы сбрасываем указатели p и q и инициализируем некоторые ячейки с ASCII-кодами символов, которые нам понадобятся позже. Я также обозначил c и s, которые мы будем использовать позже, и мы будем полагаться на тот факт, что s начинается с нуля:
Эй, подожди минутку. Почему ячейка № 0 окрашена в красный цвет? ... Ну, это для того, чтобы выделить хитрый трюк. Помните, мы выводим один 1 слишком мало? Хитрость в том, что мы используем ячейку № 0 как «расширение», чтобы исправить это. Это работает, потому что мы знаем, что p никогда не будет 0. Таким образом, красный блок теперь имеет ширину 10 ячеек, ровно столько, сколько мы хотим. Он также сохраняет 9 символов, чтобы иметь возможность инициализировать q в 1 вместо 0.
Теперь мы входим в цикл while, который просматривает слова и выводит их все.
Шаг 1: Узнайте, будет ли следующее слово вписываться в текущую строку. Мы делаем это, просто перемещая p вправо и q влево с помощью цикла while, пока p не достигнет следующего пробела:
Теперь, когда p находится справа от слова, мы можем проверить, является ли это последним словом в списке, проверив, равен ли * (p + 1) нулю. Мы также сохраняем это значение (которое в нашем примере равно 72, потому что это «h» из «хрена» минус 32) в c, потому что оно понадобится нам позже. В этом случае он не равен нулю, поэтому нам нужно вывести запятую вместе со словом, чтобы слово было на один символ длиннее. Примите это во внимание, уменьшив q еще раз. Наконец, используйте другой цикл while, чтобы переместить p назад в начало слова.
Теперь мы знаем, что слово будет вписываться в текущую строку, потому что q указывает на ненулевое значение, поэтому все, что нам нужно сделать, это:
Вывод на данный момент:
thyme,
Затем начинается следующая итерация большого цикла. Как и прежде, мы проверяем, подходит ли следующее слово к остальной части строки, уменьшая q при прохождении слова слева направо. Обратите внимание, что q все еще равно -5 от предыдущей итерации, отслеживая, сколько символов мы уже напечатали в текущей строке. После подсчета символов в «хрене», плюс один для запятой, плюс один, потому что s отличен от нуля, что указывает на то, что нам также необходимо вывести пробел, q будет перерезать конец блока из 1 с:
Теперь q указывает на нулевую ячейку, что означает, что «хрен» не поместится в текущей строке. Что мы делаем сейчас, зависит от того, является ли s ненулевым. В нашем случае это так, что означает, что нам нужно перейти к следующей строке. Все, что мы должны сделать для этого:
Вывод на данный момент:
thyme,\n
Для следующей итерации p находится в том же месте, что и раньше, поэтому мы будем снова смотреть на то же слово. Как и раньше, мы подсчитываем символы в «хрене», снова устанавливаем c на 80, когда замечаем, что после этого слова есть еще одно, уменьшаем запятую q и перематываем p обратно в начало слова:
Как и в предыдущей итерации, мы обнаруживаем, что «хрен» по-прежнему не подходит, потому что q попадает в нулевую ячейку. Однако, это время s равно нулю, что означает, что мы делаем что-то другое, чем в прошлый раз. Нам нужно вывести некоторые слова, три точки и запятую. Наша ширина равна 10, поэтому нам нужно вывести 6 символов слова. Давайте посмотрим, где мы окажемся, если мы:
Теперь лента выглядит так:
Я отметил диапазон 6 клеток здесь. Как видите, нам нужно выводить символы, пока q = −1. Это очень эффективно для проверки кода (в основном,
while ((++q)+1) { ... }
). Так:print(print(print('.')))
). Мы берем значение ASCII из ячейки # 5 и добавляем к нему 2, чтобы получить ASCII-код точки.После всего этого, мы также печатаем новую строку (используя ячейку # 3) и устанавливаем q обратно в 1. Мы также можем установить s в 0, даже если это уже 0, что делает то же самое, что мы делали ранее, когда мы переносили в следующая строка (когда s был ненулевым), поэтому, чтобы избежать повторения кода, мы делаем это после условного, который проверяет s .
Вывод на данный момент:
thyme,\nhorser...,\n
Осталась только одна итерация. На этот раз, посчитав буквы слова, получим следующее:
На этот раз после p ничего нет , поэтому мы устанавливаем c в 0, чтобы указать «без запятой», и, соответственно, мы не уменьшаем q в следующий раз. Поскольку q теперь указывает на ненулевую ячейку, мы знаем, что слово будет соответствовать, поэтому выполняется тот же код, что и в первой итерации, за исключением того, что на этот раз c равно нулю, поэтому он просто не будет печатать запятую.
Выход:
thyme,\nhorser...,\npeppermint
В этом пошаговом руководстве я не включил случай, когда код фактически напечатал бы пробел, но я думаю, что теперь это должно быть достаточно ясно. Если код обнаружит, что слово подходит ( * q ≠ 0) и s не равно нулю, он просто выведет пробел перед словом.
источник
JavaScript (ES6), 171
Как анонимная функция, возвращающая вывод в виде массива
(как это обычно разрешено, если явно не запрещено: мета- мета )
источник
Python 2, 206 байт
источник