Поради щодо гольфу в Underload


11

Underload - це напівфункціональний tarpit на основі стека, створений ais523 . Я нещодавно намагався займатися гольфом, оскільки це напрочуд елегантна мова.

Які поради для гольфу в Underload? (Одна порада на відповідь)


Мені подобається, що єдиною формою потоку управління є evalкоманда, я ніколи не бачив такої мови.
ETHproductions

Відповіді:


3

Використовувати *для виведення

Оскільки ви можете виводити, залишаючи рядок у стеці , може бути корисним накопичити рядок, використовуючи, *а не виводячи за допомогою S. Скажіть, що ваше завдання було "взяти рядок і додати пробіл", спосіб зробити це з результатом:

S( )S

З *іншого боку, спосіб зробити це на один байт коротше:

( )*

Проблема полягає в тому, що якщо ваш вихід має багато накопичення, це може коштувати байтів для обробки вихідного елемента на стеку.


2

Використовуйте словник багаторазово використаних функцій

Якщо вам потрібно багато використовувати фрагмент коду, є сенс зберігати цей код у стеку та повторювати його та раз у раз. Поки що це просто звичайне програмування Underload. На жаль, тривалий час зберігати значення у стеку є складним і, як правило, призводить до того, що ваш код стане багатослівним, і це справедливо, навіть якщо значення є функцією, а не даними. Це стає набагато гіршим, якщо у вас є кілька функцій, які потрібно повторно використовувати.

У ролі більшої програми, яка може отримати користь від декількох повторно використаних функцій, рішення, яке ви можете використовувати, - це замість того, щоб зробити одну велику функцію, яка може виконувати будь-які їх цілі залежно від способу її виклику (або на основі того, що знаходиться під ним у стеці, або через використання більш довгих послідовностей виклику , ніж просто ^, ретельно написана функція може відрізнити ^^від ^:^від ^*^від ^~^, даючи вам чотири різних, досить короткі послідовності). Ви також можете зберігати в цьому "словнику" інші корисні речі, такі як рядки, які ви використовуєте кілька разів. Зауважте, що якщо ви користуєтесь словником сильно, можливо, це має сенс зробити його якоюсь королевою, відсуваючи свою копію назад на стек, так що вам не потрібно копіювати її вручну: вміти ним користуватися, не втрачаючи можливості використовувати його в майбутньому.


Я зійшов би з розуму задовго до того, як отримав будь-яку програму, достатньо велику в Underload, що це стало проблемою: P
Esolanging Fruit

Одного разу я написав кілька прикладів на сторінці esolangs про те, як робити словники з моїм вподобаним ^!!!!^пошуком стилів (який я також використовував у кількох інших прикладах на сторінці, особливо в розділі мінімізації). Хоча це може не дати найкоротшого пошуку.
Ørjan Johansen

2

Виберіть формати даних, спеціалізовані для операцій, які потребують проблеми

Як простий приклад, найбільш часто зустрічається реалізація булевих !()помилок - це false (тобто ціле число 0), а нульовий рядок - true (тобто ціле число 1), але якщо у вас є проблема, яка сильно базується на логічному XOR, це може зробити більше сенс використовувати нульову рядок як для false, так і ~для true (цей формат даних може бути перетворений у будь-який інший булівський формат, використовуючи (false)~(true)~^!, і дозволяє дуже коротко реалізувати *для XOR.

Можна ще більше продовжити цей загальний принцип і використовувати функції, які пізніше будуть потрібні вашій програмі, як частину ваших значень даних; що дозволяє зберігати функції та дані окремо у стеку. Це може зробити контрольний потік досить заплутаним, але при проведенні гольфу для ремонту часто потрібно зайняти заднє місце, і це не так, як "Underload" все-таки корисний.


Раніше я використовував (!)і (~!)для булів, але ваш шлях здається кращим.
Esolanging Fruit

2

"Брудна" декрет

Функціонально-чистий спосіб декрементації церковного числа - це використання функції попередника обчислення лямбда:

\n.n(\p.\z.z($(pT))(pT))(\z.z0[whatever you define the predecessor of 0 to be])

Де 0 = \ x. \ Yy, T = \ x. \ Yx, і $ - наступник.

Перезаписано в Underload, це 28 байт:

(!())~(!())~(!:(:)~*(*)*~)~^!

Це добре, але ми можемо використовувати деякі з корисних властивостей недовантаженням, а саме , що :!і ()*не робити не є-OPS. Це означає , що, для ряду n, :ⁿ!!()()*ⁿ(де cⁿв cповторному nраз) дає N-1. Наприклад, якщо це зробити для Церкви цифра 3, це означає:

:::!!()()***

Видаляючи неопарні пари, ми отримуємо:

:*

Що 2.

Отже, це нова і коротша попередня операція:

:(:)~^(!!()())*~(*)~^*

Це на 7 байт коротше.


Однак ця функція перервана на n = 0. Якщо вам це потрібно для роботи, (()~(:))~:(^!!())*~(*)~^** все одно на 3 байти коротше.
Ørjan Johansen

@ ØrjanJohansen Як правило, у вас буде особливий випадок для n = 0, тому що при зменшенні числа Underload число 0 все одно не має сенсу.
Esolanging Fruit

1

Помістіть непотрібні значення стека в програмний простір

Навантаженість насправді має два стеки - стек рядків і стек команд, що складають вихідний код. ^Інструкція Underload дозволяє нам переміщувати рядки з першої стеки до другої. Цим ми можемо заощадити багато непотрібних маніпуляцій стеком.

Наприклад, скажімо, що у нас є (a)(b)(c)основний стек, і ми хотіли би об'єднати два нижні елементи, ігноруючи (c), отримати (ab)(c). Наївний спосіб зробити це - повернути стек, щоб отримати, (c)(a)(b)а потім конкантенувати і поміняти назад:

a~a~*~a*^*~

Це погано. Використовувати a~a~*~a*^для обертання стека так, як це надзвичайно дорого, і слід уникати, коли це можливо. Замістивши (c)натомість програмний простір, це можна зробити на чотири байти коротше:

a(*)~*^

Ідея полягає в тому, щоб скористатися інструкціями, які ви хочете виконати, а потім додати інструкцію для відштовхування (c)в кінці, а потім оцінити результат. Це означає, що нам не потрібно хвилюватися, (c)поки це не буде відсунуто назад, коли ми закінчимо.


1
Ви також можете записати це як (*)~a*^, що, на мою думку, є трохи більш складною. По суті ~a*^це dipкоманда від Радості.
Ørjan Johansen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.