Цей виклик дуже підходить для Нечитабельних.
Перша версія цього документа складала 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 не дорівнює нулю, воно просто виведе пробіл перед словом.