Форматировать список слов


16

Ваша задача состоит в том, чтобы отформатировать список слов в нескольких строках, длина которых не превышает заданного количества символов, чтобы каждая строка содержала как можно больше слов, и слова не были бы излишне обрезаны.

вход

На входе будет список слов, разделенных пробелами, а затем число, равное как минимум 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...


Ответы:


10

Не читается , 2559 байт

Эта задача очень подходит для нечитаемых.

Первая версия этого была 3379 байтов, просто чтобы дать вам представление о том, сколько я играл в гольф.

Программа принимает ввод в точности так, как описано в задании: разделенный пробелами список слов (который также может содержать цифры и знаки пунктуации), за которым следуют пробел и целое число, равное не менее 4 (нижние числа генерируют бесконечные циклы) ,

«" „“ „“»«»«»«»«»«„“ „„„“““ „„„“““ „„„“““ "» „“ «" „“ „“»" " «„„“ „“ „““» «" „“ „„„“ „“ „“ „“ „“““ „“ „“ „„„“ „“ „“““ „“ „“ „“»" «» «„„““» «» «» «» «„“„“„“„“» «» «„„“ „“ „“ „““» «» «» «» «"»«» «» «» «„„“ „“ „“ „““» «» «» «» «„„“ „“ „“ „““» «» «» «» "" „“ „“ „“ «» «„“„“„“„“» «» «» «» «» «„“„“„“„“» «» «» «» «» «„“„“„“„“» «» «» «» «» «„“„“„“„“» «» «» «» «» «„“„“„“„“» «» «» «» «» "„“»«» «» «„„“ „“ „“ „““» «» «» «» «„„“ „“ „“ „““» «» «» «» "" „“ „“ „“ „“ «" „“ „“ „“»«»«»«»«»«„“ „“ „“ „“»«»«»«»«»«„“ „“ „“ „“»«»«» «» «» «„“„“„“„“» «» «» «» «» «„“„“„“„„„“““„“» «» «» "" „“«» «» «„„“ „“ „““» «» «» «» «„„“ „„„“ „“ „“ „“““ „“ „“ „““» «» «» «» «" „“»«„“ "» „“ „“ «" „“ „“ „“ „„„“ „“ „“““ „“ „“ „“»" „“ „„„“““ „“ «» «» «„“„“„“„“» «» «„„“ „““» «» «„„“ „“ „““» «" „“»" „“ „“ "«» «„„“ „“ „“ „““» «» «» «» «„„“ „“ „“ „““» «» «» «» «„„“ „“ „“ „““» «» «» «» «„„“ „“ „“ „““» «» «» «» «„„“ „“ „“ „““» «» «» «» "" „“ „“ „“ «» «„“„“„“„“» «» «» «» «» «„“„“„“„“» «» «» «» «» «„“"»„“"«» «„“» «» «» «» «„“» «» «„“„„„“„“„“„“““„“„“„“» «» «„“» «» "» «» «» «» «„“» «» «„„““» «„„““» «„„““» «„„““» «„„““» "" „“ „“ „“ «„„““» «» «„“„“„“» «» «„“» «» «„„“ „“ „„„“ „“ „“““ „“ „“ „““»»«» «» «» «„“„„„“„“„“„“““„“„“„“» «» «» «» «„„“ „“ „“ „““» «» "» «» «» «„„““» «» «„“» «» «» «» «„„““» «» «„“„“„„„“„“„“““"»„“" «" „“ „“ „“»«»«»«»«„„““»«»«„“ „“ „“»«»«»«»«„“ "» „“ „“«» «» «„“„“„“"»„“„„„“„„„“„“„“““„„„“““„„„“““„“““" „„““ «» «„“» «» «„“» «» «„“» «» «„“» «» «„“» «» «» «» «„“» «» «„“» «» "» «" „“ „„„“““ „„„“““ „„„“““ „„„“““ „„„“““ „„„“““ „„„“““»" „“«"»«»«„“»«»«„“»«»«„“»«»«»«»«„“»«»" „“ „„„“““ „„„“““» «» «» «„“„“„“„“» «» «„„““» «„„““» «„„““» «„„“ „“ „““» «» "„“» «" „“ „„„“ „“ „“ „„„“““ „“ „“ „“““ „“ „“ „“ "» „“ „„„“ „“““ „“ ""«» «» «„“„“"»„“„“„“„„„“„“„“““„“„“„“" „„“„„„“““„“„“„““ «» «» «» «» «„“„„„“„“„“““„“» «» «» «» «» «„“„“„“"»„“«"„“„“» «» «» «„“„“„“» «» «„“„„„“„“„“„„„“““„“„“„“““„“„“„“"»«» «„„“ „“ „““» «» «„“„“„“„“» «» «» «» «" „“»«„“ "» „“ „“ "" „“ „“ «» «„„“ „“ „““» «» «» «» «„„“ „„„“ „“ „“ „“““ „“ „“ „““» «» «» «» "» «» «" „“ „„„“ „“ „“““ „„„“““»«„“ "» „“ „“ „“ „“ «" „“ „“ „“»" "«» «» «» «» «„“„“„“„„„“““„„„“““„“» «» «» «» "„“" „„“„“„“„““ «» «» «» «" „“»«„“ „“ „“ "» „“ „„„“ „“““ „“ «" „“ „“ „“ „“»" „“ „“ „“ «„„““» «„„““» «» «„„„“„“„“„„„“““„„„“““„„„“““„“““„“»«» «» "" „“ „“ „“ „„„“ „“ „“““ „“ „“ „“ „„„“ „„„“““ „“ „“ „“““ „“ „“ «» «" „“»" „„„“““ „„„“““ „„„“““ „„„“““ „„„“““ „„„“““ „„„“““ «„„““» «„„““» «„„““» «„„““» «„„““» «„„““» «„„““» «„„““» "»«» «„“» «» «» «» «„„“ „“ „“ „„„“ „“ „“ „“““ „““» «» «» «» «» "„“„“» «» «„“» «» «"»«„“ „“ „“ „„„“““ „„„“““ "» „“ «" „“ „„„“ „“““ „“»" «» «» «» «» «„„“ „“ „“ „„„“““ „„„“““ „““» «» «„“„“» «» «» "„“»«„„“ „““» «» «» «„“„“„“„“» «» «» «» «„„“ „“ „““» «» «„“» «» «» «» «" „“»«„“ "» „“ „“ „“ „“ „„„“ „“ „“ „„„“““ „“““ „“ „“ "" „“ „„„“““ «» «» «» «„“"»„“" "„“„“„„„“““„“„“„„„“„„„“““„“„“„“““«» "„„„“““„„„“““„„„“““„„„“““„„„“““„„„“““„„„“““" „„““ «» «„“» «» «„“» «» «„“» «» «„“» «» «„“» «» «„“» «» «„“» «» «„“» «» «" „“ „“ „„„“ „“ „“““ „“ „“ „“ „„„“ „„„“““ „“ „“ „“““ „“ „“ „“ "» "«» «"»«"» «„“„“"»„“„“„“„„„“„“„“““„“„“„“«"„“„„„“““„“» «» «„„“ „“ „“ „““» «» «„“» «» «„“„“„“„„„“““„„„“““"»„“«"„“» «» «» «» «„“„“„“„„„“““„“» «" „“ „“ „“ „„„“““ „„„“““»«„“ "»«» «"»«„“ „“ „“ „„„“““ "» „“ „„„“ „“ „“ „“““ „“ „“ «" „“»" „“ "

объяснение

Я собираюсь показать вам, как программа обрабатывает ввод thyme horseradish peppermint 10. Ожидаемый результат thyme,\nhorser...,\npeppermint.

Сначала мы начинаем с ячейки № 7 и читаем весь ввод, но вычитаем 32 из каждого символа, чтобы пробелы стали нулями.

По понятным причинам это оставляет текущий указатель (с именем p здесь, хранится в ячейке # 0) в конце. Мы используем один цикл while, чтобы найти последний пробел, который является началом числа, определяющего ширину вывода (ячейка # 36 в этом примере).

Теперь мы хотим декодировать число (то есть преобразовать из десятичного числа). Окончательный результат будет в обеих ячейках t и r . Мы полагаемся на то, что они начинаются с нуля.

Для каждой цифры в номере сделайте следующее:

  • Установите t до -15.
  • В цикле while декремент r (который пока содержит результат) до −1 (потому что нам нужно ровно r итераций, но поскольку декремент происходит до того, как он будет проверен как условие цикла while, уменьшение до 0 даст на одну итерацию меньше) и для каждой итерации добавьте 10 к т . Теперь t содержит в 10 раз предыдущий результат минус 15.
  • Снова в цикле while уменьшите значение * p до 0 и для каждой итерации добавьте 1 к t . После того, как этот t пока содержит правильный промежуточный результат: символы '0'должны '9'иметь коды ASCII 48–57, поэтому после более раннего вычитания 32 они равны 16–25, поэтому мы фактически добавляем 15–24 к t , что отменяет с −15 мы установили это раньше. Также важно, чтобы это обнуляло ячейки, которые раньше содержали цифры, чтобы последующий код мог распознать конец списка слов.
  • Установите r в новый промежуточный результат, чтобы следующая итерация нашла его в r . (Обратите внимание, что нам не нужно снова читать из t , мы можем просто использовать последнее значение из предыдущего цикла while, потому что мы знаем, что * p не может быть нулем, поэтому он выполнялся хотя бы один раз.)

Наконец, мы используем другой простой цикл 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 указывает на ненулевое значение, поэтому все, что нам нужно сделать, это:

  • Снова переместите p вперед по слову, печатая каждый символ (плюс 32, потому что все коды ASCII выключены на 32).
  • Если c не ноль, выведите запятую (используя значение в ячейке # 5).
  • Установите для s ненулевое значение, чтобы указать на следующей итерации, что мы больше не находимся в начале строки и поэтому должны выводить пробел перед следующим словом. (Для этого мы повторно используем возвращаемое значение вышеприведенного оператора печати, равное 44 для запятой.)

Вывод на данный момент: thyme,

Затем начинается следующая итерация большого цикла. Как и прежде, мы проверяем, подходит ли следующее слово к остальной части строки, уменьшая q при прохождении слова слева направо. Обратите внимание, что q все еще равно -5 от предыдущей итерации, отслеживая, сколько символов мы уже напечатали в текущей строке. После подсчета символов в «хрене», плюс один для запятой, плюс один, потому что s отличен от нуля, что указывает на то, что нам также необходимо вывести пробел, q будет перерезать конец блока из 1 с:

Теперь q указывает на нулевую ячейку, что означает, что «хрен» не поместится в текущей строке. Что мы делаем сейчас, зависит от того, является ли s ненулевым. В нашем случае это так, что означает, что нам нужно перейти к следующей строке. Все, что мы должны сделать для этого:

  • Распечатать новую строку (используя ячейку № 3)
  • Установите q обратно в 1
  • Установите s в 0

Вывод на данный момент: thyme,\n

Для следующей итерации p находится в том же месте, что и раньше, поэтому мы будем снова смотреть на то же слово. Как и раньше, мы подсчитываем символы в «хрене», снова устанавливаем c на 80, когда замечаем, что после этого слова есть еще одно, уменьшаем запятую q и перематываем p обратно в начало слова:

Как и в предыдущей итерации, мы обнаруживаем, что «хрен» по-прежнему не подходит, потому что q попадает в нулевую ячейку. Однако, это время s равно нулю, что означает, что мы делаем что-то другое, чем в прошлый раз. Нам нужно вывести некоторые слова, три точки и запятую. Наша ширина равна 10, поэтому нам нужно вывести 6 символов слова. Давайте посмотрим, где мы окажемся, если мы:

  • Найдите начало красного блока 1с. Мы можем сделать это, идя прямо, потому что мы знаем, что q должно быть оставлено от этого.
  • Увеличьте q еще раз, если нам также нужно вывести запятую ( c ≠ 0).

Теперь лента выглядит так:

Я отметил диапазон 6 клеток здесь. Как видите, нам нужно выводить символы, пока q = −1. Это очень эффективно для проверки кода (в основном, while ((++q)+1) { ... }). Так:

  • Выведите эти символы (плюс 32, потому что все коды ASCII отключены на 32), пока q не достигнет -1. Затем p будет в ячейке 19, в середине слова «хрен».
  • Распечатать три точки. Поскольку команда print возвращает свой собственный аргумент, мы можем эффективно вложить его в код (по сути, print(print(print('.')))). Мы берем значение ASCII из ячейки # 5 и добавляем к нему 2, чтобы получить ASCII-код точки.
  • Переместите p в конец слова. Так как мы знаем, что мы еще не достигли конца слова (потому что слово было слишком длинным, и нам пришлось удалить из него как минимум 3 символа, чтобы соответствовать точкам), этот цикл определенно имеет по крайней мере одну итерацию, поэтому в коде короче, чтобы тело цикла while вычисляло значение ASCII для точки, а затем передавало возвращаемое значение цикла while в функции печати.
  • Выведите запятую, если c не равен нулю.

После всего этого, мы также печатаем новую строку (используя ячейку # 3) и устанавливаем q обратно в 1. Мы также можем установить s в 0, даже если это уже 0, что делает то же самое, что мы делали ранее, когда мы переносили в следующая строка (когда s был ненулевым), поэтому, чтобы избежать повторения кода, мы делаем это после условного, который проверяет s .

Вывод на данный момент: thyme,\nhorser...,\n

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

На этот раз после p ничего нет , поэтому мы устанавливаем c в 0, чтобы указать «без запятой», и, соответственно, мы не уменьшаем q в следующий раз. Поскольку q теперь указывает на ненулевую ячейку, мы знаем, что слово будет соответствовать, поэтому выполняется тот же код, что и в первой итерации, за исключением того, что на этот раз c равно нулю, поэтому он просто не будет печатать запятую.

Выход: thyme,\nhorser...,\npeppermint

В этом пошаговом руководстве я не включил случай, когда код фактически напечатал бы пробел, но я думаю, что теперь это должно быть достаточно ясно. Если код обнаружит, что слово подходит ( * q ≠ 0) и s не равно нулю, он просто выведет пробел перед словом.


3

JavaScript (ES6), 171

Как анонимная функция, возвращающая вывод в виде массива

(как это обычно разрешено, если явно не запрещено: мета- мета )

s=>(s=s.split` `,n=s.pop()-1,t='',o=[],s.map((w,i)=>(w=w[n+=!s[i+1]]?w.slice(0,n-3)+'...':w,(t+w)[n-2]&&(t&&o.push(t.slice(1)),t=''),t+=` ${w},`)),o.push(t.slice(1,-1)),o)

f=s=>(s=s.split` `,n=s.pop()-1,t='',o=[],s.map((w,i)=>(w=w[n+=!s[i+1]]?w.slice(0,n-3)+'...':w,(t+w)[n-2]&&(t&&o.push(t.slice(1)),t=''),t+=` ${w},`)),o.push(t.slice(1,-1)),o)

// Less golfed
U=s=>(
  s=s.split` `,
  n=s.pop()-1,
  t='', // current line
  o=[], // output
  s.map( (w,i)=>(
    w=w[
      n+=!s[i+1] // space for 1 more char on the last line
    ]?w.slice(0,n-3)+'...':w, // change w if it is too long
    (t+w)[n-2]&& ( // if current line + w is too long, ouput t and reset current line
      t&&o.push(t.slice(1)),t=''
    ),
    t+=` ${w},`
  )),
  o.push(t.slice(1,-1)), // remove tailing comma on last line
  o
)

console.log=x=>O.textContent+=x+'\n\n';
  
console.log(f("foo bar baz qux 12").join`\n`)
console.log(f("foo bar baz qux 5").join`\n`)
console.log(f("strength dexterity constitution intelligence wisdom charisma 10").join`\n`)
console.log(f("quas wex exort 4").join`\n`)
<pre id=O></pre>


1

Python 2, 206 байт

i=input().split()
l=int(i.pop())
i=[[w[:l-4]+'...',w][len(w)<l]+','for w in i][:-1]+[[w,w[:l-3]+'...'][len(w)>l]]
r=[i.pop(0)]
for w in i:
 if len(r[-1])+len(w)<l:r[-1]+=' '+w
 else:r+=[w]
print'\n'.join(r)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.