Мне нравится, что единственная форма потока управления - это evalкоманда, я никогда раньше не видел такого языка.
ETHproductions
Ответы:
3
Использовать *для вывода
Поскольку вы можете выводить, оставляя строку в стеке , может быть полезно накопить строку, используя *вместо вывода с помощью S. Скажем, ваша задача заключалась в том, чтобы «взять строку и добавить пробел», способ сделать это с помощью вывода:
S( )S
С *другой стороны, способ сделать это на один байт короче:
( )*
Проблема в том, что если ваш вывод имеет много накоплений, он может стоить байтов для обработки выходного элемента в стеке.
Используйте словарь многократно используемых функций
Если вам нужно много использовать фрагмент кода, имеет смысл сохранить этот код в стеке и время от времени дублировать и оценивать его. Пока что это просто нормальное программирование под нагрузкой. К сожалению, долгое время хранить значение в стеке сложно, и это приводит к тому, что ваш код становится многословным, и это верно, даже если значение является функцией, а не данными. Это становится намного хуже, если у вас есть несколько функций, которые необходимо использовать повторно.
В более крупной программе, которая может извлечь выгоду из нескольких повторно используемых функций, решение, которое вы можете использовать, состоит в том, чтобы вместо этого создать одну большую функцию, которая может выполнять любые свои задачи в зависимости от того, как она вызывается (либо на основе того, что находится под ней в стеке, или через использование более длинных последовательностей вызова , чем просто ^, тщательно написанная функция может отличить ^^от ^:^от ^*^от ^~^, давая вам четыре различных, довольно короткие последовательности). Вы также можете хранить другие полезные вещи, такие как строки, которые вы используете несколько раз, в этом «словаре». Обратите внимание, что если вы интенсивно используете словарь, возможно, имеет смысл сделать его своего рода квинэном, перенеся его копию обратно в стек, чтобы вам не приходилось копировать его вручную с помощью: быть в состоянии использовать это, не теряя способность использовать это в будущем.
Я бы сошел с ума задолго до того, как получил достаточно большую программу в Underload, чтобы это стало проблемой: P
Esolanging Fruit
Однажды я написал несколько примеров на странице esolangs о том, как создавать словари с моим предпочтительным ^!!!!^стилем поиска (который я также использовал в нескольких других примерах на странице, особенно в разделе минимизации.) Хотя это может не дать кратчайшего поиска.
Эрджан Йохансен,
2
Выберите форматы данных, специализированные для операций, в которых нуждается проблема
В качестве простого примера, наиболее часто встречающаяся реализация логических значений относится !()к ложному (т. Е. Целому 0) и к нулевой строке для истинного (т. Е. Целому 1), но если у вас есть проблема, которая в значительной степени основана на логическом XOR, она может сделать больше смысл использовать пустую строку для false и ~для true (этот формат данных может быть преобразован в любой другой логический формат с использованием (false)~(true)~^!и позволяет очень краткую реализацию *для XOR.
Можно пойти дальше этого общего принципа и использовать функции, которые понадобятся вашей программе позже, как часть ваших значений данных; это избавляет от необходимости хранить функции и данные отдельно в стеке. Это может сделать процесс управления более запутанным, но при игре в гольф ремонтопригодность часто приходится занимать заднее сиденье, и в любом случае недогрузка не так уж и полезна.
Раньше я использовал (!)и (~!)для логических, но ваш путь кажется лучше.
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 байтов:
(!())~(!())~(!:(:)~*(*)*~)~^!
Это нормально, но мы можем использовать некоторые из полезных свойств Underload, а именно, что они :!и ()*являются no-ops. Это означает , что, для ряда n, :ⁿ!!()()*ⁿ(где cⁿв cповторном nраз) дает N-1. Например, делая это для церковной цифры 3, получим следующее:
:::!!()()***
Сняв безоперационные пары, мы получим:
:*
Который 2.
Итак, это новая и более короткая предшествующая операция:
Это нарушает n = 0. Если вам это нужно, (()~(:))~:(^!!())*~(*)~^** все равно на 3 байта короче.
Орджан Йохансен,
@ Ø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)пока он не отодвинется после того, как мы закончим.
eval
команда, я никогда раньше не видел такого языка.Ответы:
Использовать
*
для выводаПоскольку вы можете выводить, оставляя строку в стеке , может быть полезно накопить строку, используя
*
вместо вывода с помощьюS
. Скажем, ваша задача заключалась в том, чтобы «взять строку и добавить пробел», способ сделать это с помощью вывода:С
*
другой стороны, способ сделать это на один байт короче:Проблема в том, что если ваш вывод имеет много накоплений, он может стоить байтов для обработки выходного элемента в стеке.
источник
Используйте словарь многократно используемых функций
Если вам нужно много использовать фрагмент кода, имеет смысл сохранить этот код в стеке и время от времени дублировать и оценивать его. Пока что это просто нормальное программирование под нагрузкой. К сожалению, долгое время хранить значение в стеке сложно, и это приводит к тому, что ваш код становится многословным, и это верно, даже если значение является функцией, а не данными. Это становится намного хуже, если у вас есть несколько функций, которые необходимо использовать повторно.
В более крупной программе, которая может извлечь выгоду из нескольких повторно используемых функций, решение, которое вы можете использовать, состоит в том, чтобы вместо этого создать одну большую функцию, которая может выполнять любые свои задачи в зависимости от того, как она вызывается (либо на основе того, что находится под ней в стеке, или через использование более длинных последовательностей вызова , чем просто
^
, тщательно написанная функция может отличить^^
от^:^
от^*^
от^~^
, давая вам четыре различных, довольно короткие последовательности). Вы также можете хранить другие полезные вещи, такие как строки, которые вы используете несколько раз, в этом «словаре». Обратите внимание, что если вы интенсивно используете словарь, возможно, имеет смысл сделать его своего рода квинэном, перенеся его копию обратно в стек, чтобы вам не приходилось копировать его вручную с помощью:
быть в состоянии использовать это, не теряя способность использовать это в будущем.источник
^!!!!^
стилем поиска (который я также использовал в нескольких других примерах на странице, особенно в разделе минимизации.) Хотя это может не дать кратчайшего поиска.Выберите форматы данных, специализированные для операций, в которых нуждается проблема
В качестве простого примера, наиболее часто встречающаяся реализация логических значений относится
!()
к ложному (т. Е. Целому 0) и к нулевой строке для истинного (т. Е. Целому 1), но если у вас есть проблема, которая в значительной степени основана на логическом XOR, она может сделать больше смысл использовать пустую строку для false и~
для true (этот формат данных может быть преобразован в любой другой логический формат с использованием(false)~(true)~^!
и позволяет очень краткую реализацию*
для XOR.Можно пойти дальше этого общего принципа и использовать функции, которые понадобятся вашей программе позже, как часть ваших значений данных; это избавляет от необходимости хранить функции и данные отдельно в стеке. Это может сделать процесс управления более запутанным, но при игре в гольф ремонтопригодность часто приходится занимать заднее сиденье, и в любом случае недогрузка не так уж и полезна.
источник
(!)
и(~!)
для логических, но ваш путь кажется лучше."Грязный" Декремент
Функционально-чистый способ уменьшить церковную цифру - использовать функцию-предшественник лямбда-исчисления:
Где 0 = \ x. \ Yy, T = \ x. \ Yx и $ - преемник.
Переписано в Underload, это 28 байтов:
Это нормально, но мы можем использовать некоторые из полезных свойств Underload, а именно, что они
:!
и()*
являются no-ops. Это означает , что, для рядаn
,:ⁿ!!()()*ⁿ
(гдеcⁿ
вc
повторномn
раз) дает N-1. Например, делая это для церковной цифры 3, получим следующее:Сняв безоперационные пары, мы получим:
Который 2.
Итак, это новая и более короткая предшествующая операция:
Это на 7 байт короче.
источник
(()~(:))~:(^!!())*~(*)~^**
все равно на 3 байта короче.Поместите ненужные значения стека в пространство программы
Недостаточная нагрузка на самом деле имеет два стека - стек строк и стек команд, составляющих исходный код. Инструкция Underload
^
позволяет нам перемещать строки из первого стека во второй. Делая это, мы можем сохранить много ненужных манипуляций со стеком.Например, скажем, у нас есть
(a)(b)(c)
основной стек, и мы хотим объединить два нижних элемента, игнорируя(c)
, чтобы получить(ab)(c)
. Наивный способ сделать это состоит в том, чтобы повернуть стек, чтобы получить,(c)(a)(b)
а затем собрать и вернуть обратно:Это плохо. Использование
a~a~*~a*^
для вращения стека таким образом чрезвычайно дорого, и по возможности его следует избегать.(c)
Вместо этого, поместив в пространство программы, это можно сделать на четыре байта короче:Идея состоит в том, чтобы взять инструкции, которые вы хотели бы выполнить, а затем добавить инструкцию, чтобы отодвинуть ее
(c)
в конце, и затем оценить результат. Это означает, что нам не нужно беспокоиться,(c)
пока он не отодвинется после того, как мы закончим.источник
(*)~a*^
, что я думаю, что это немного более сложным. По сути~a*^
этоdip
команда от Радости.