Форматуйте список слів


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.
  • Через певний час декремент r (який містить результат до цього часу) до −1 (тому що нам потрібні саме r ітерації, але оскільки декремент відбувається до того, як він перевіряється як стан циклу while, декрементування до 0 дало б менше ітерацій) і для кожної ітерації додайте 10 до t . Тепер t містить 10 разів більше попереднього результату мінус 15.
  • Знову цикл, декремент * p до 0 і для кожної ітерації додайте від 1 до t . Після цього т містить правильний проміжний результат до сих пір: символи , '0'щоб '9'мати ASCII коди 48-57, так що після того, як раніше відніманням 32 вони 16-25, так що ми на самому ділі додати 15-24 до т , який анулює з -15 ми встановлюємо це раніше. Також важливо, щоб це нулювало осередки, які містили символи цифр, щоб наступний код міг розпізнати кінець списку слів.
  • Встановіть r на новий проміжний результат, щоб наступна ітерація знайшла його в r . (Зверніть увагу, що нам не потрібно читати з t ще раз, ми можемо просто використовувати останнє значення з попереднього циклу while, оскільки ми знаємо, що * p не може бути нульовим, тому воно запустилось хоча б один раз.)

Нарешті, ми використовуємо ще один простий цикл while (зменшення t як лічильник) для перетворення числа, яке ми тільки що обчислили, в одинакове. Ми зберігаємо рядок розмірами 1, що йде вліво від клітини № 0. Це спирається на те, що клітинка №1, наш запущений покажчик на це ( q ), починається з 0. Ми отримуємо на одну меншу кількість 1s, тому що цикли в Unreadable є такими:

Після цього нам більше не потрібно значення в r , тому ми повторно використовуємо цю клітинку для чогось іншого. Ми скидаємо покажчики p і q і ініціалізуємо деякі комірки з кодами ASCII, які нам знадобляться пізніше. Я також позначив c і s, які ми будемо використовувати згодом, і будемо покладатися на те, що s починається з нуля:

Гей, почекай хвилинку. Чому клітинка №0 пофарбована в червоний колір? ... Ну, це виділити підлий трюк. Пам'ятайте, що ми виводимо один 1 занадто мало? Хитрість полягає в тому, що ми використовуємо комірку № 0 як "розширення", щоб виправити це. Це працює, тому що ми знаємо, що p ніколи не буде 0. Таким чином, червоний блок зараз шириною 10 комірок, саме те, що ми хочемо. Це також зберігає 9 символів, щоб можна було ініціалізувати q до 1 замість 0.

Тепер ми входимо до циклу while, який проходить через слова і виводить їх усі.

Крок 1. Дізнайтеся, чи впишеться наступне слово у поточний рядок. Ми робимо це, просто перемістивши p вправо і q вліво з циклом час, поки 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 матиме перебіг у кінці блоку 1s:

Тепер q вказує на нульову клітинку, що означає, що "хрін" не впишеться в поточний рядок. Те, що ми робимо зараз, залежить від того, чи s дорівнює нулю. У нашому випадку це так, а значить, нам потрібно перейти до наступного рядка. Все, що ми повинні зробити для цього, це:

  • Друк нового рядка (використовуючи комірку №3)
  • Встановіть q назад на 1
  • Встановіть s на 0

Поки що результат: thyme,\n

Для наступної ітерації p знаходиться в тому самому місці, що і раніше, тому ми ще раз переглянемо те саме слово. Як і раніше, ми підраховуємо символи в «хріні», встановлюємо c знову 80, коли помічаємо, що після цього є ще одне слово, декремент q для коми і перемотаємо p назад на початок слова:

Як і в попередній ітерації, ми виявляємо, що «хрін» все ще не підходить, оскільки q закінчується на клітині, яка дорівнює нулю. Однак цей час s дорівнює нулю, це означає, що ми робимо щось інше, ніж минулий раз. Нам потрібно вивести трохи слова, три крапки і кома. Наша ширина - 10, тому нам потрібно вивести 6 символів слова. Подивимось, де ми опинимось, якщо:

  • Знайдіть початок червоного блоку 1s. Ми можемо це зробити, рухаючись праворуч, тому що знаємо, що 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 код точки.
  • Перемістіть р до кінця слова. Оскільки ми знаємо, що ми вже не могли дійти до кінця слова (оскільки це слово було занадто довгим, і нам довелося видалити з нього щонайменше 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

Як анонімна функція, що повертає вихід у вигляді масиву

(оскільки це, як правило, дозволено, якщо прямо не заборонено: meta meta )

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.