第三弹!


19

此挑战是2018年4月LotM挑战的一部分


Brain-Flak是一种图灵化的语言,在PPCG上享有很高的声誉。语言的记忆是由两个堆栈组成,而是一个“隐藏”的第三组被发现é在向导,导致大脑思维,高射炮方案的一些有趣的新方式。

那么,如何给那个可怜的隐藏第三堆栈更多的可见性呢?让我们创建一种语言,使第三个堆栈具有应有的识别力!在这里,我向您介绍Third-Flak

语言

在Third-Flak中,只有一个堆栈,称为第三堆栈。运营商在他们的脑高射炮做同样的方式在第三堆栈上工作,但这里没有[]{}<>nilads没有{...}单子(所以在第三高射炮程序的唯一受理字符()[]<>)。这是每个运算符的工作(将给出示例,该示例表示第三个堆栈,并带有列表,其中最后一个元素是堆栈的顶部):

  • ()是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的语义,它们将始终是noop,但实际上它们在Brain-Flak中具有不同的含义,无法在此处重新创建)。

  • 括号总是需要平衡的,除非程序末尾的结尾的括号可能会丢失。例如,[()<(()是一个有效的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?否则[()]会违反我们不必担心从空堆栈中弹出的规则
Jo King

1
@JoKing Yep:“在执行开始时,第三个堆栈仅包含一个0”。也许我应该强调一下这一部分,我担心它太容易错过了。
狮子座

糟糕,我不知道我怎么想念
乔·金

7
划掉的e仍然是e。
小麦巫师

2
如果任何人都无法看到,打叉的e在这里
user202729 '18

Answers:


21

Brain-Flak,276个字节

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

在线尝试!

您必须知道即将到来。


4

视网膜0.8.264个 48 46字节

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

在线尝试!从下到上输出堆栈。仅适用于非负整数,并且最后一个测试用例太慢,因此该链接仅包含三个测试用例。说明:堆栈隐式位于程序之前,因此它从空字符串开始,它代表一个零。()Nilad变成了一个_用来计数一元数的小数,而其他开括号变成了换行符,当遇到零时将零推入堆栈。然后一次处理一个右括号,以便使堆叠正确。在)删除先前的换行符,加入顶部的两个元件一起,在]删除该顶部元件和从堆栈上的前一个元素匹配它因而减去它,并且>只是删除顶部元素。最后,堆栈将转换为十进制。编辑:由于@Leo,节省了2个字节。


有什么$3用 (无论如何,都是最好的答案!)
Leo

@Leo这是以前打高尔夫球的遗留物。感谢您发现它!
尼尔

4

Python 3中145个144 132 122 116 109 104字节

-7个字节,感谢Leo!

并且-5感谢Lynn!

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}

在线尝试!

我的初始代码在精神上与Jo King的Python回答类似,因此在循环遍历源字符之前,我们将所有()子字符串替换为另一个字符,作为不同的运算符。

但是,至少在Ruby中,事实证明高尔夫球手不是这样做,而是采用稍微麻烦一些的方法。在这里,我们维护了一个额外的索引器,以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然后计算代码点mod 8以获取不同的数值,这比字符串更容易使用。

使用R中的向量的开头要更精打细算,因此我们以这种方式构造堆栈。

然后,它会看到一个)k==1,这时会在堆栈顶部添加一个额外的零,因为它是高尔夫球手,可以添加和删除它。


1

CJam,29个字节

0q")]>([<""+-;U"er"U+"/')*~]p

在线尝试!

0q                              Push 0, input
  ")]>([<""+-;U"er              Translate )]>([< to +-;UUU
                  "U+"/')*      Replace U+ by )
                          ~     Eval as CJam code
                           ]p   Wrap and pretty-print stack

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;}

在线尝试!

(由于Leo的建议,节省了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;
}

在线尝试!


我不太了解锡兰,但也许您可以删除开关的第一种情况,然后使用else部分来管理所有开口括号:)
Leo

嗯,我想那可能行得通……它将改变无效输入的行为,但这不是问题。
圣保罗Ebermann
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.