Третій флак!


19

Цей виклик було розміщено як частина виклику LotM у квітні 2018 року


Brain-Flak - це виразно-бляшана мова, яка здобула досить велику популярність тут на PPCG. Пам'ять про мову складається з двох стеків, а «прихований» третій стек був виявлений на Wh е в майстра , що призводить до деяких цікавих нових способів мислення програми Brain-зенітної.

Отже, а як надати цій бідній прихованій третій стек більшу видимість? Давайте створимо мову там, де третій стек має визнання, яке заслуговує! Тут я представляю вам Третього Флака .

Мова

У Третього Флака є лише один стек, який називається третім стеком. Оператори працюють на третьому стек таким же чином , що вони роблять в Брейн-Flak, але тут немає [], {}, <>nilads і не {...}монади (так тільки допустимі символи в програмі третього Flak є ()[]<>). Ось що робить кожен оператор (наведено приклади, що представляють третій стек зі списком, де останній елемент є верхом стека):

  • ()є єдиним оператором з двох символів у Third-Flak. Це збільшує верхню частину третього стеку на 1. Приклад: [1,2,3][1,2,4]

  • (, [, <: Все відкриття дужки, що не охоплені в попередньому випадку натиснути 0на третій стек. Приклад: [1,2,3][1,2,3,0]

  • )вискакує два елементи з третього стеку і відштовхує їх суму. Приклад: [1,2,3][1,5]

  • ]вискакує два елементи з третього стека і відштовхує результат віднімання першого з другого. Приклад: [1,2,3][1,-1]

  • >спливає елемент з третього стеку. Приклад [1,2,3][1,2]

Ось інші правила мови:

  • На початку виконання третій стек містить лише один 0.

  • Забороняється мати порожню []або <>всередині програми (вони все одно були би шумими, якщо слідувати семантиці Третього Флака, але вони насправді мають інше значення в «Мозговому-Флаку», яке тут неможливо відтворити).

  • Дужки завжди потрібно збалансувати, за винятком того, що кінцеві дужки в кінці програми можуть бути відсутніми. Як приклад, [()<(()є дійсна програма Third-Flak (і третій стек в кінці програми буде [1,0,1]).

  • Програма може містити лише шість дозволених символів ()[]<>. Програми гарантовано не пустують.

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

Змагання

Простий, написати перекладача для Third-Flak. Ваша програма повинна прийняти за вхід програму Third-Flak і повернути як вихід стан третього стеку в кінці програми.

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

Ваш вибір виходу може обмежувати діапазон чисел, якими ви можете керувати, доки це не призведе до тривоги виклику (оскільки це буде лазівка ​​за замовчуванням ).

Тестові справи

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

[()<(()
0 1 0 1

[((((()()()()()))
0 0 0 5

((([()][()][()])))
-3

[<<(((()()()())(((((
0 0 0 0 0 4 0 0 0 0 0

[()]<(([()])><[()]
-1 0 -1

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()()
718 2

Чи стек ініціалізований з 0? В іншому випадку [()]порушено правило, що нам не потрібно турбуватися про вискакування з порожнього стека
Джо Кінг,

1
@JoKing Yep: "На початку виконання третій стек містить лише один 0". Можливо, я повинен трохи підкреслити цю частину, я боявся, що це буде занадто легко пропустити.
Лев

На жаль, я не знаю, як я пропустив це
Джо Кінг,

7
Закреслена е - це все-таки e.
Пшеничний майстер

2
Якщо хто -то не можуть бачити , що перекреслені eзнаходиться тут .
користувач202729

Відповіді:


21

Мозок-Флак , 276 байт

{({}<>)<>}<>{(((()()()()()){})((({}){})())(({})({}{}([{}])(<>))))((()()(){[()]<{}>}{}){()<{{}}>}{}<<>({}({})())>{()(<{}>)}{}<>)<>}<>{(([{}]()<>)){{}({}())((){[()](<({}())((){[()](<({}())((){[()](<{}([{}]{})>)}{}){(<{}{}>)}{}>)}{}){(<{}({}{})>)}{}>)}{}){(<{}{}({}())>)}}{}<>}<>

Спробуйте в Інтернеті!

Ви повинні були знати, що це відбувається.


4

Сітківка 0,8.2 , 64 48 46 байт

\(\)
_
[([<]
¶
+1`¶(.*)\)|(.*)¶\2]|¶.*>
$1
%`_

Спробуйте в Інтернеті! Виводить стек знизу вгору. Працює лише з невід’ємними цілими числами, а останній тестовий випадок занадто повільний, тому посилання включає лише три тестові випадки. Пояснення: Стек неявно передує програмі, тому він починається як порожній рядок, який представляє один нуль. ()Nilad перетворюються в _який використовується для підрахунку в унарна, в той час як інші відкритих дужках перетворилися в символи нового рядка , які штовхають нуль в стек , оскільки вони зустрічаються. Потім закриті дужки обробляються по черзі, щоб стек був правильним; )видаляє попередній рядок, додавши зверху два елементи разом, ]видаляє верхній елемент і відповідає його від попереднього елемента в стек , таким чином , віднімаючи його, і>просто видаляє верхній елемент. Нарешті стек перетворюється на десятковий. Редагувати: збережено 2 байти завдяки @Leo.


Для чого $3? (чудова відповідь, все одно!)
Лев

@Leo Це залишилось від попереднього гольфу. Дякуємо, що помітили його!
Ніл

4

Python 3 , 145 144 132 122 116 109 104 байт

-7 байт завдяки Леву!

І - 5 завдяки Лінн!

s=[0]
for i in input().replace('()',' '):s+=i in']>) 'and(i<'!'or(2-ord(i)%5)*s.pop())+s.pop(),
print(s)

Спробуйте в Інтернеті!

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

Деякі спроби однолінійки:

  • 124 байти (анонімна функція):

    lambda c:[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())or s for s in[[0]]for i in c.replace('()',' ')][0]
  • 115 байт (повна програма):

    s=[0];[s.append(i in']>) 'and(i<'!'or~-']>)'.index(i)*s.pop())+s.pop())for i in input().replace('()',' ')];print(s)

Додаток прикро більше, ніж звичайне завдання


~-']>)'.index(i)можна (2-ord(i)%5)зберегти 4 байти.
Лінн

2

Рубі , 98 91 байт

->s{a=[i=0];s.chars{|c|a<<("([<"[c]?s[i,2]["()"]?1:0:a.pop*~-"]>)".index(c)+a.pop);i+=1};a}

Спробуйте в Інтернеті!

Мій початковий код працював аналогічно за думкою відповіді Python Джо Кінга, так що перед циклом проходження через вихідні символи ми замінили всі ()підрядки іншим символом, як окремий оператор.

Однак, принаймні, в Рубі виявилося, що гравці не роблять цього, а скоріше йдуть на трохи більш громіздкий підхід. Тут ми підтримуємо додатковий індексатор, iвідслідковуючи наше положення у вихідному рядку, і кожного разу, коли виникає дужка, що відкривається, ми робимо перевірку пошуку, якщо наші поточні + наступні символи s[i,2]утворюють ()оператора. У цьому випадку ми натискаємо 1 замість 0 на вершині стека, і нехай закриття )виконує свою роботу на наступному кроці.


1

05AB1E , 25 байт

΄()1:v"0+0\0->"žuykè.V})

Спробуйте в Інтернеті!

Пояснення

Î                           # initialize the stack with 0 and the input
 „()1:                      # replace any occurrence of "()" in the input with 1
      v                }    # for each char y in this string
                žuyk        # get its index in the string "()[]<>{}"
       "0+0\0->"    è       # use this to index into the string "0+0\0->"
                     .V     # eval
                        )   # wrap the stack in a list


1

R , 182 177 байт

function(P){for(k in utf8ToInt(gsub("\\(\\)",7,P))%%8){if(k%in%0:4)F=c(0,F)
if(k==7)F[1]=F[1]+1
if(k==1)F=c(F[2]+F[3],F[-3:0])
if(k==5)F=c(F[2]-F[1],F[-2:0])
if(k==6)F=F[-1]}
F}

Спробуйте в Інтернеті!

Повертає стек, де перша частина стека - перша, а нижня частина стека - остання.

Свопи ()з , 7а потім обчислює кодові точки по модулю 8 , щоб отримати різні числові значення, які легше і golfier для роботи з чим рядка.

Це гольфіст працювати з початком вектора в R, тому ми будуємо стек таким чином.

Потім він бачить a ), або коли k==1, він додає додатковий нуль у верхню частину стека, оскільки його гравця потрібно додати та видалити.



1

Цейлон, 285 266 байт

function f(variable String c){variable Integer[]s=[0];value o=>[s[0]else nothing,s=s.rest][0];void u(Integer i)=>s=[i,*s];while(c!=""){if(c[0:2]=="()"){u(1);c=c.rest;}switch(c[0])case(')'){u(o+o);}case(']'){u(-o+o);}case('>'){noop(o);}else{u(0);}c=c.rest;}return s;}

Спробуйте в Інтернеті!

(Збережено 19 байт завдяки пропозиції Лео.)

Відформатовано та прокоментовано:

// Interpreter for ThirdFlak
// Question:    /codegolf//q/163242/2338
// This answer: /codegolf//a/163403/2338
//
// This function takes the code as a string, and returns the value
// of the stack as a sequence of Integers.
function f(variable String c) {
    // stack, in the beginning just a single 0.
    // Top element of the stack is the first, because push + pop is easier this way.
    variable Integer[] s = [0];
    // pop – used like an Integer variable (not a function – this saves the `()`), but has side effects.
    value o =>
        // `s[0]` is the first element of the stack. We tell the compiler
        // that it is non-null (otherwise we'll get an error at run time)
        // using the `else nothing`. `s.rest` is `s` without its first element.
        // Both together are wrapped into a 2-tuple, of which we then take just
        // the first element, to have both together in an expression instead
        // the longer way using an accessor block with a temporary variable and a return.
        // value o {
        //   value r = s[0] else nothing;
        //   s = s.rest;
        //   return r;
        // }
        [s[0] else nothing, s = s.rest][0];
    // push
    void u(Integer i) =>
        // a tuple enumeration, using the spread argument.
        s = [i, *s];
    // the main loop
    while (c != "") {
        if (c[0:2] == "()") {
            // »`()` is the only two-characters operator in Third-Flak. It increases the top of the third stack by 1.«
            // As `)` alone adds the two top elements together, we can just push a one here, and let the handling for `)` do the rest.
            u(1);
            c = c.rest;
        }
        switch (c[0])
        case (')') {
            // »`)` pops two elements from the third stack and pushes back their sum.«
            u(o + o);
        }
        case (']') {
            // »`]` pops two elements from the third stack and pushes back the result of subtracting the first from the second.«
            // As the o written first is the first one, we can't write this as a subtraction.
            u(-o + o);
        }
        case ('>') {
            // »`>` pops an element from the third stack.«
            // `o;` alone is not a valid statement, so we pass it to the `noop` function.
            noop(o);
        }
        else {
            // all other valid code characters are `(`, `[`, `<`, which all just push a 0.
            u(0);
        }
        c = c.rest;
    }
    return s;
}

Спробуйте в Інтернеті!


Я не дуже знаю Цейлон, але, можливо, ви можете зняти перший корпус вимикача та скористатися іншою частиною для керування всіма дужками, що відкриваються :)
Лев,

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