Стиснення рядкових масивів
ОНОВЛЕННЯ: Інструменти, представлені в цій підказці, з тих пір будуть переписані, вдосконалені та інтегровані в мій перекладач Japt . Для найкращих результатів рекомендується використовувати цей компресор над будь-яким із зв'язаних нижче. Я перегляну цю пораду, коли у мене з’явиться ще час, і перепишу її новим компресором на увазі.
Вступ
Якщо у вашому коді є масив рядків, найбільш очевидним способом його стиснення було б запуск кожної рядкиOc
окремо. Для цілей цієї поради ми будемо працювати з масивом ["lollipop","marshmallow","nougat","oreo"]
, який спочатку важить 42 байти. Запуск кожного рядка через Oc
нас дає:
[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]
Це зараз 33 байти, гідна економія.
Крок 1
Але ми можемо зробити краще. Якщо ми приєднаємо масив до рядка, розділеного новою лінією, ми можемо позбутися дужок, коми та сторонніх задників і розділитись на новий рядок, щоб отримати наш масив. Застосовуючи це до нашого прикладу масиву, ми отримуємо наступне:
`lo¥ipop
Ú\hÚaow
Í
eo`·
Зараз до 26 байт.
Крок 2
Але ми можемо зробити все-таки краще! Ми можемо використовувати малі літери для розмежування рядків замість нового рядка, який може бути включений до стиснення. z
не використовується в жодному з наших рядків, тому давайте кинемо це, і подивимось, як ми дістаємось.
`lo¥ipopzÚ\hÚaowzÍzeo`qz
Ах, горіхи - поліпшення там немає; наш байт збільшився на один! Там може бути ще один лист , ви могли б використовувати , але, в залежності від ваших рядків, не може бути достатньо мало , щоб спробувати - в нашому прикладі є 11: b,c,d,f,j,k,q,v,x,y,z
. Спроба кожного з них була б досить стомлюючою, і саме тут є цей зручний інструмент ; подайте його своїми рядками, розділеними новим рядком, і він спробує розмежувати рядки кожною літерою, яка не міститься в жодній з них, і вивести:
- найкоротший стислий рядок,
- роздільник, який він використовує, і
- його довжина.
Запуск наших зразків рядків через нього показує, що b
дає найкращі результати:
`lo¥ipáæqrÚaowbÍÞo`qb
І там у вас це є, ми знизилися до всього 24 байт.
Крок 3
Але , ми можемо зробити ще краще! Якщо порядок рядків у вашому масиві не має значення, можливо, є інша перестановка в поєднанні з іншим роздільником, який може вийти ще коротше. Спроба кожної можливості стане набагато більш втомливою. З нашими 4-ма рядками, можна спробувати 24 різні перестановки. З кожною з 11 можливих літер, яка стає 264! Ось де цей інструмент вступає в гру. Знову ж таки, подайте йому свої рядки, що розділяються з нового рядка, і він буде випробовувати кожну комбінацію кожної перестановки та кожного відмітного листа, виводячи:
- порядок рядків у найкоротшому стисненому рядку,
- стислий рядок,
- роздільник, який він використовує, і,
- його довжина.
Запуск наших зразків рядків через це показує , що "nougat","oreo","lollipop","marshmallow"
з , b
як роздільник дає кращі результати, з остаточним підрахунком байт з усього 23:
`ÍÞo½o¥ipáæqrÚaow`qb
Порада про бонус: Стиснення масиву цілих чисел
Ви можете застосувати той же принцип до масивів цілих чисел, попередньо перетворивши кожне у вищу базу. Використовуючи цей зразок, 36-байтний масив:
[588181,156859,595676,475330,680474]
Ми можемо зменшити це до 29 байт, спершу перетворивши його в масив базових 32 рядків, а потім запустивши його через першу програму стиснення:
`huclt4p5r5ÛÊg62tkogq`qt mnH
Або ж 27 байт за допомогою другої програми:
`4p5Ïcl5ÛÊg62tkogq`qt mnH
Можливо, ви зможете зберегти ще один байт або 2, перемістивши цілочисельну конверсію в метод, який ви вже працюєте в масиві.
Примітки
- Не забувайте враховувати
q<letter>(<space>)
витрати на 1 або 2 зайвих байта ·
. Хоча, можливо, ви зможете скористатися одним із ярликів Unicode, щоб повернути байт назад, залежно від вашого роздільника ( qÊ
такий же, як ql<space>
, наприклад,).
- Слово обережності при використанні останнього інструменту: чим більше рядків у вас буде, тим більше буде перестановок і повільніше буде працювати програма, доки вона врешті не вискочить. Як детально описано вище, з 4-х зразкових рядків та 11 можливих букв, які можна спробувати, є 264 можливі комбінації, збільшити кількість рядків лише на 1 з тими ж 11 літерами, і ми вже маємо 1320 комбінацій для спробу. (Ви можете використовувати цей інструмент для підрахунку кількості комбінацій, якщо хочете).
Кредити
- Олівер за натхнення створити інструменти, знайдені в цій підказці.
- ETHпродукції для коректури.