Советы по игре в гольф в Бефунге

12

Какие общие советы у вас есть для игры в гольф в Бефунге? Я ищу идеи, которые могут быть применены к кодовым проблемам гольфа в целом, которые, по крайней мере, несколько специфичны для Befunge (например, «удалить комментарии» - это не ответ). Пожалуйста, оставьте один совет за ответ.

Джастин
источник
Я не уверен, стоит ли менять это на Befunge в целом, но Befunge 93 гораздо менее идеален для игры в гольф, чем 98.
Джастин
6
У нас недавно была тема Befunge 93 , но я думаю, что было бы лучше обобщить эту тему. Это было бы хорошо? (и, возможно, отметьте, какие советы подходят для какой версии / версий, точно так же, как советы Python говорят, являются ли они специфичными для Python 2 / Python 3)
Sp3000

Ответы:

9

При использовании многострочного цикла старайтесь использовать как можно больше:

>1234....v
^        <

против

>1234v
^....<
Джастин
источник
7

Нужно удалить значение после условного (например, потому что другой путь зависит от значения, но этот не делает)? Вместо того, чтобы использовать >$или $<, примите во внимание тот факт, что вы знаете истинное значение переменной и используйте _вместо этого как для изменения направления, так и для стека pop.

пример

'* : v           >$ .. @          Prints number in binary followed by the original
                                  decimal number.
     > :2%\2/ :!#^_ \.

превращается в

'* : v           _  .. @          Since we know that the topmost value on the stack
                                  will be 0, we combine `>$` into `_`.
     > :2%\2/ :!#^_ \.
Светляк
источник
6

Не забывайте, что 0это всегда в стеке. Например, это означает, что с пустым стеком gэквивалентно 00gи pэквивалентно 000p.

Джастин
источник
5

Если вам нужно нажать число больше 15, используйте 'для получения значения ASCII следующего символа:

'*

нажать 42, а не:

4a*2+
Джастин
источник
Или 67*тоже работает
Doorknob
4
@ Doorknob Может быть, я должен был выбрать простое число, чтобы прояснить мою точку зрения, но 42 - это большое число.
Джастин
2
Обратите внимание, что этот совет относится только к Befunge-96 и более поздним версиям. Befunge-93 не поддерживал 'инструкцию.
Джеймс Холдернесс
4

Вместо использования |, требующего другой строки (часто с большим количеством лишних пробелов), попробуйте использовать j. Например:

01-`j@more code here

остановился бы, если число на вершине стека было бы отрицательным и продолжил бы в противном случае. Если вам нужно несколько символов, использование n*jкоторых nявляется количество символов , вам нужно , когда значение , передаваемое jявляется 0. Пример:

01-`4*j01-*more code

который отрицал бы отрицательное число.

Джастин
источник
Обратите внимание, что этот совет относится только к Befunge-96 и более поздним версиям. Befunge-93 не поддерживал jинструкцию.
Джеймс Холдернесс
4

В Befunge-93, если первое, что вы помещаете в стек, это строка, вы часто можете сойти с рук, отбросив начальную цитату. Например это:

"!iH",,,@

можно упростить до этого:

!iH",,,@

Попробуйте онлайн!

Происходит то, что интерпретатор сначала пытается выполнить символы в строке без кавычек. В !выполняет безвредный не , и iи Hне являются действительными инструкциями, поэтому они игнорируются (хотя в некоторых реализациях вы можете получить предупреждение).

Когда "встречается, это считается началом строки, но поскольку закрывающей кавычки нет, она оборачивается вокруг игрового поля до тех пор, пока "не встретится во второй раз. То, что в итоге помещается в стек, таково:

,,,@  ···72 spaces···  !iH

Так как мы заботимся только о последних нескольких персонажах, все остальное не имеет значения. Таким образом, после кавычки мы, наконец, получаем выполнение трех ,команд, выписывающих сообщение и @команду, которая завершается.

Обратите внимание, что это обычно не работает в Befunge-98, так как нераспознанная инструкция заставит интерпретатор отражать, а не игнорировать ее.

Джеймс Холдернесс
источник
В Befunge-98 вы можете вместо этого поместить нужную строку в конец строки, вот так; ",,,@!iH, Обратите внимание, что Pyfunge добавляет дополнительный пробел, а FBBI - нет.
Джо Кинг
@JoKing Я не хотел этого предлагать, потому что, как вы указали, поведение отличается от одного переводчика к другому. И даже когда кажется, что это работает, это противоречиво (обратите внимание на дополнительное пространство в FBBI в этом случае ), так что вполне возможно, что ошибка может в конечном итоге быть исправлена.
Джеймс Холдернесс
Хм ... Я думаю, что пространство может быть частью спецификации. Я помню, как читал где-то, что несколько пробелов будут пропущены и засчитаны как один пробел. Пример как в PyFunge, так и в FBBI. Кажется, FBBI дополняет каждую строку до длины самой длинной строки, тогда как PyFunge неявно добавляет дополнительные пробелы.
Джо Кинг
Вы правы - в спецификации сказано, что несколько пробелов в строке следует рассматривать как один пробел. Фактически, это правило было специально предложено для решения проблемы оборачивания строк в бесконечном игровом поле (поэтому PyFunge явно верный AFAIC). Но описание спецификации алгоритма обертки в некоторой степени открыто для интерпретации, поэтому я могу понять, почему некоторые реализации могут действовать по-другому. Но суть в том, что это довольно сложный вопрос, и я думаю, что его лучше рассмотреть в качестве отдельного совета, посвященного Befunge-97/98.
Джеймс Холдернесс
4

В Befunge-93 часто может быть выгодно сгладить цикл в одну строку, причем часть цикла кода выполняется в обоих направлениях.

Например, рассмотрим приведенный ниже код, который выводит букву aвосемь раз:

"a"9>1-:#v_@
    ^\,:\<

Это может быть сведено в одну строку путем разделения последовательности цикла с помощью инструкций моста ( #):

"a"9>1#\-#,:#:>#\_@

Попробуйте онлайн!

Если вы просто смотрите на символы без пробелов, у вас может сложиться впечатление, что это больше, чем оригинал. Но как только вы примете во внимание перевод строки и дополнительный заполнитель, требуемый в двухстрочной версии, вы фактически сохраните четыре байта.

В этом конкретном случае код сжимается еще больше, отмечая, что эту последовательность :#:можно просто заменить на :.

"a"9>1#\-#,:>#\_@

Попробуйте онлайн!

Фактически, когда вы повторяете одну и ту же инструкцию с обеих сторон #команды, вы можете упростить ее до одной инструкции, так что это то, на что вы всегда должны обращать внимание при выравнивании цикла.

Чтобы понять, как это работает, это может помочь записать последовательность циклов дважды, один раз со всеми символами, следующими за #удаленным (то есть, что происходит при выполнении слева направо), и один раз с символами, предшествующими #удаленному (то есть выполнение справа налево) ).

"a"9>1#\-#,:>#\_@
    >1  -  :>  _      ; executing left to right
    >  \  ,:  \_      ; executing right to left

Теперь вы можете ясно видеть, как это соответствует исходной двухстрочной версии кода.

Джеймс Холдернесс
источник
3

Вывод по коду выхода, где это разрешенная форма вывода. Если задача просит вас напечатать один номер, вы можете сохранить байт, завершив программу с помощью qвместо.@

pppery
источник
2
Обратите внимание, что этот совет относится только к Befunge-98 и более поздним версиям. В более ранних версиях Befunge qинструкция имела другую функцию (режим очереди) или не поддерживалась.
Джеймс Холдернесс
3

В Befunge-93 символьная команда ввода ( ~) часто может использоваться в качестве ярлыка для -1, поскольку это значение, которое она возвращает в EOF.

В качестве примера приведенный ниже код выведет -1:

~.@

Попробуйте онлайн!

Это не рекомендуется в рабочем коде, поскольку при запуске в интерактивной среде программа приостанавливает работу и ожидает ввода данных пользователем. И, очевидно, если бы пользователь вводил что-то, результат больше не был бы -1.

Тем не менее, правило на PPCG гласит, что программа может предполагать пустой поток ввода , и именно так она обычно запускается на TIO .

Также обратите внимание, что вы не обязательно лишены возможности использовать этот трюк только потому, что вашей программе нужно что-то прочитать из входного потока. Вам просто нужно убедиться, что вы обрабатываете свои данные заранее, после чего все последующие использования ~должны возвращать -1.

Джеймс Холдернесс
источник
2

Используйте направление IP при работе с _или |вместо использования дополнительного символа для !.

Реальный пример (из этого поста ):

#v~
,>:!#@_

Может быть изменено на

#v~
:<,_@#
Джастин
источник
2

Не забывайте, что 0kне выполняет следующую инструкцию. Это означает, что вместо того, чтобы делать:

;some boolean test;!jv;code if false;
       ;code if true;<

Вы можете сохранить персонажа, выполнив

;some boolean test;kv;code if false;
      ;code if true;<
Джастин
источник
Обратите внимание, что этот совет относится только к Befunge-98 и более поздним версиям. Более ранние версии Befunge не поддерживали kинструкцию.
Джеймс Холдернесс
1

Не забывайте об kоператоре. Вместо того "!dlroW olleH",,,,,,,,,,,,@, чтобы делать "!dlroW olleH"bk,@. Обратите внимание , что kделает операцию на ячейку , что он находится на так 9k,бы печатать не 9 раз , но 10; 9 раз с k, и один раз с ,.

Джастин
источник
1
Обратите внимание, что этот совет относится только к Befunge-98 и более поздним версиям. Более ранние версии Befunge не поддерживали kинструкцию.
Джеймс Холдернесс
1

Выкладывая небольшие числа в стек, вы, вероятно, можете достаточно легко понять, что 45*получит вас 20и 67*получит вас 42. Когда дело доходит до больших чисел, вам действительно нужна программа, которая может рассчитать наиболее эффективное представление для вас.

Самый простой вариант для этого - онлайн-интерфейс Майка Шверера для BefunRep . Вы просто вводите число, и оно выдает эквивалентное представление Befunge. Это не всегда самый оптимальный вариант, но он достаточно близок, и он почти наверняка будет лучше, чем все, что вы можете придумать вручную.

Онлайновая система ограничена числами в диапазоне от 0 до 16777215, поэтому, если вам нужно что-то большее, вам нужно скачать отдельную утилиту BefunRep и выполнить вычисления самостоятельно.

Если вы программируете на Befunge-98, другой вариант - это Fungify . В целом он не так оптимален, как BefunRep, но для некоторых младших чисел, где шестнадцатеричные цифры и символы одинарных кавычек наиболее эффективны, иногда он может давать лучшие результаты.

Джеймс Холдернесс
источник
Нажимая маленькие цифры в Befunge 98, вы будете использовать '. Например, для 42:'*
Джастин
@Justin Я уже упоминал об этом в последнем абзаце, но суть этого совета в том, что вам не нужно знать множество этих приемов для генерации чисел, если вы просто используете инструмент, который сделает это за вас.
Джеймс Холдернесс