Поради щодо гольфу в Бефунге


12

Які загальні поради щодо гольфу в Бефунге? Я шукаю ідеї, які можна застосувати до коду проблем із гольфом взагалі, які принаймні дещо специфічні для Befunge (наприклад, "видалити коментарі" - це не відповідь). Будь ласка, опублікуйте одну пораду на відповідь.


Я не впевнений, чи варто це взагалі змінити на Befunge, але Befunge 93 набагато менш ідеально підходить для гри в гольф, ніж 98.
Джастін

6
У нас була нещодавня тема Befunge 93 , але я думаю, що краще було б узагальнити цю тему. Це було б гаразд? (і, можливо, позначте, які поради корисні для якої версії / ів, так само, як підказки Python говорять, чи є вони Python 2 / Python 3 конкретними)
Sp3000

Відповіді:


9

Використовуючи багаторядковий цикл, спробуйте використовувати якомога більше його:

>1234....v
^        <

проти

>1234v
^....<

7

Потрібно скинути значення після умовного (наприклад, тому, що інший шлях залежить від значення, але цей немає)? Замість того, щоб використовувати >$або $<, скористайтеся тим, що ви знаєте значення істинності змінної, і використовуйте _замість того, щоб змінити напрямок і поп-стек.

Приклад

'* : 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 - ні.
Jo King

@JoKing Я не хотів цього пропонувати, оскільки, як ви вказали, поведінка відрізняється від одного перекладача до іншого. І навіть коли це, здається, працює, непослідовно (зверніть увагу на додатковий простір у FBBI у цьому випадку ), тому цілком можливо помилка, яка може виявитись виправлена ​​в якийсь момент.
Джеймс Холдернес

Хм ... Я думаю, що простір може бути фактично частиною специфікації. Я пам'ятаю, як десь читав, що декілька пробілів буде пропущено і зараховано до єдиного пробілу. Приклад і в PyFunge, і в FBBI. FBBI, здається, пробиває кожен рядок на довжину найдовшої лінії, тоді як PyFunge додає додаткові пробіли неявно.
Jo King

Ви маєте рацію - специфікація говорить про те, що кілька пробілів у рядку слід розглядати як єдиний пробіл. Насправді це правило було спеціально запропоновано вирішувати проблему загортання рядків у нескінченне ігрове поле (тому 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замість.@


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:'*
Джастін

@ Джустін я згадував про це в останньому абзаці, але вся суть цієї поради - вам не потрібно знати цілу кількість цих хитрощів для генерації чисел, якщо ви просто використовуєте інструмент, щоб зробити це за вас.
Джеймс Холдернесс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.