Компактна програма Befunge


17

Befunge - це двовимірна езотерична мова програмування. Основна ідея полягає в тому, що (односимвольні) команди розміщуються на двовимірній сітці. Контрольний потік проходить по сітці, виконуючи команди, які він передає, та змінюючи напрямок, коли він потрапляє на стрілку ( >^<v). Команди засновані на стеці; дивись цей список . Дивіться також http://esolangs.org/wiki/Befunge .

Доступна специфікація для Befunge-98 .

Проблема

Напишіть програму, яка перетворює програму Befunge у більш компактне подання. Наприклад, друкуються такі програми 0:

>   0   v

>   @   .

^       <

У цьому випадку це можна ущільнити, не змінюючи поведінку програми, видаляючи рядки пробілів, щоб дати

>0v
>@.
^ <

Більш складні перетворення можуть обертати або відображати дзеркальні послідовності команд та усунути непотрібні команди управління потоком, щоб ущільнити програму. Наприклад, за допомогою цієї програми:

>12345v
      6
v....7<
.
.
.
@

ви можете засунути кінець програми в лунку:

>12345v
>...@ 6
^....7<

У першому прикладі можлива найбільш компактна програма

>0.@

Ви можете використовувати будь-які перетворення до тих пір, поки вихідна програма дасть однаковий результат.

Вхідні програми

Програми введення є дійсними програмами Befunge-98.

Ви можете припустити, що програма введення детермінована. Тобто, він не використовує команди, які читають зовнішній стан: команди введення користувача &і ~, рандомізатор ?, і команди, що змінюють код, pі g.

Ви можете припустити, що програма введення припиняється.

Оцінка балів

Це не кодовий гольф, а проблема написання програми, яка виконує гольф з кодом.

Вхід - це набір тестових випадків (програми Befunge, які задовольняють вищевказаним обмеженням). Загальний бал - це сума балів за тестові приклади.

Оцінка за кожен тестовий випадок

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

>   v
 @  <

отримує оцінку 9,5.

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

Якщо програма тестування має інший результат (або не завершиться) після обробки з вашою програмою, бал - це бал програми введення плюс штраф у 100 балів.


8
Що заважає запускати програму до завершення та писати програму Befunge, яка друкує той самий вихід?
Кіт Рендалл

5
Чи дозволено "дістати" та "поставити"? Якщо ви дозволите "поставити" (самовиправляючий код), зробити це буде важко.
Кіт Рендалл

2
З чого починається страта? Лівий верхній кут? Якщо так, чи можете ви пояснити вихід 2-го прикладу? .означає ціле число виводу, але якщо ви починаєте з верхнього лівого кута, то в стеку немає цілого числа для виведення.
elssar

1
@elssar так, .виводить ціле число. Але також, коли на стеку недостатньо параметрів, befunge робить вигляд, що натомість є достатня кількість нулів. Отже, другий приклад мав би результат 000.
daniero

@KeithRandall: Написання нової програми з тим же виходом працює лише для програм з невеликим виходом. gі pзаборонено (вибачте, забули про них; відредаговано).
Механічний равлик

Відповіді:


12

Я витратив довгу їзду на літаку, кодуючи це. Я написав компілятор псевдофункції, який запускає програму befunge, витягує основні блоки та викладає їх у компактному поданні.

Посилання на програму .

Під час запуску цієї програми з 99 пляшок:

92+9*                           :. v  <
>v"bottles of beer on the wall"+910<
,:
^_ $                             :.v
            >v"bottles of beer"+910<
            ,:
            ^_ $                     v
>v"Take one down, pass it around"+910<
,:
^_ $                           1-v
                                 :
        >v"bottles of beer"+910.:_          v
        ,:
        ^_ $                          ^
                    >v" no more beer..."+910<
                    ,:
                    ^_ $$ @

Він генерує такий вихід:

92+9*:.019+"llaw eht no "v
v  _v# :"bottles of beer"<
>    ,:    v
^  _v#     <
    >$:.019+"reeb f"v
 v _  v#:"bottles o"<
 >     ,:  v
 ^ _  v#   <
      >$019+"dnuo"v
     v"pass it ar"<
     >" ,nwod eno"v
 v _    v#:"Take "<
 >       ,:v
 ^ _    v# <
        >$1-:v
 v _      v# <
 >         :.019+"reeb "v
  v_  v#   :"bottles of"<
  >        ,v
  ^_  v#   :<
      >    $019+"llaw"v
           v" on the "<
           >"reeb fo "v
^  _^#      :"bottles"<
          >019+"...r"v
v  _v#:" no more bee"<
>    ,:    v
^  _v#     <
    >$$@    

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

Програма викладена з лінією області маршрутизації та основним вмістом блоку справа. Базовий блок, як правило, викладається парною кількістю рядків, тому вхід і вихід примикають до області маршрутизації. В кінці кожного основного блоку гаджет #^_vта варіанти, викладені справа наліво, виконують умовну гілку та маршрут в стовпчики. На початку кожного основного блоку ці стовпчики переносяться у рядки для базового блоку призначення.

Крім того, якщо вихід короткий, він явно генерує висновок, як це:

"output">:#,_@

Я нічого не зробив для оптимізації самих основних блоків, просто компонування. Зробити.

То де тести?


1
Здається, посилання на вихідний код наразі становить 500. Неправильне налаштування сервера?
Джон Дворак

1
@JanDvorak: справді. Виправлено.
Кіт Рендалл

1

Сід, 5 символів

Отже, навіть якщо це не кодогольф, ось рішення, яке матиме досить хороший коефіцієнт довжини коду та балів, але не обов'язково хороший бал.

/^$/d

Він просто видаляє порожні рядки.


10
Ваш код невірний! Не можна просто видаляти порожні рядки. Я не можу написати 2d-код у коментарі. Але розглянемо випадок, який спрямований вниз, і починається постійний рядок ( "). Кожен порожній рядок на шляху повинен трактуватися як пробільний символ. Якщо ми роздрукуємо цей рядок, у створеного вами коду немає таких пробілів!
saeedn

3
Подивіться на код в ideone.com/BdcRcf Він повинен надрукувати b a. Але після вашого скорочення він надрукує ba.
saeedn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.