总结?那是我的优势!


18

介绍

Forte是一种非常奇特的深奥语言,基于修改数字值的概念。在Forte中,数字不是常数而是变量,您可以使用LET指令为其分配新值。

例如,LET 2=4-1从现在开始执行后,2假设值为3,这意味着只要2表达式中的值出现,它就会由代替3。该表达式(1+1)*2现在将计算为9

Forte中的此指令既用于存储信息,又用于流控制(对行进行编号,并通过更改其编号的值可以确定其执行顺序)。在这个挑战中,我们将不处理第二个方面。

挑战

您需要为Forte LET表达式的简化子集编写解释器。

您将收到以下遵循以下语法的输入行:

<line>::= <number>=<expression>

<expression>::= <number>|<expression>+<number>

注意:此语法无效,因为它缺少行号,LET和括号(它们始终是必需的)

也就是说,您只需要处理求和和为数字分配值。括号不会出现在输入中,并且每个表达式都需要从左到右求值:请注意部分结果会受到重新定义的影响!

数字将始终是非负整数,直到您的语言的本机整数类型的限制(或2 ^ 32,以较高者为准)。

对于每一行,您应该输出表达式的结果,并将该结果分配给第一个数字的(可能是重新分配的)值,这将影响如何解释以下各行。

这是,最短的代码(以字节为单位)获胜!

其他规定

  • 输入格式是灵活的,例如,您可以采用带换行符的单个字符串,字符串列表,数字列表...输出也一样,只要清楚每个表达式中的结果是什么输入。
  • 您可以提交要在REPL环境中运行的函数,完整程序或解决方案,每行调用一次。
  • 禁止出现标准漏洞,特别是您不能在代码中调用外部Forte解释器。

例子

这些都是同一输入的一部分。在每行之后,显示相对于该行的预期输出,有时还会显示注释,指示相关的重新分配(不是必需输出的一部分)。

5=4
4
6=5
4        # 5 -> 4
7=1+2+5
7
7=5+2+1
4        # Order of operations matters! 5+2 -> 4+2 -> 6 -> 4
18=5+6+7
12
5=3
3        # Remember: 5 -> 4
10=6+4
3        # 6 -> 4 -> 3, 3+3 = 6 -> 3

0有效号码吗?
orlp

@orlp 0是有效的(“数字始终是非负整数”)
Leo

我们应该接受任何算术运算符吗?
bacchusbeale

@bacchusbeale不,只是求和。
Leo

是否有特定的最大数字,或者与语言的本机整数类型一样大?另外,返回数字列表将是无效的输出,其中一个是结果,对吗?(例如打印将号码转到哪个号码的字典/地图)
zgrep

Answers:


4

果冻,28个字节

®y$ÐL
ṪÇ+Ç¥/Ṅ;®⁸Ǥ;©
⁸©ḷƓÇ€¤

在线尝试!

这是为数不多的从标准输入中获取输入的Jelly程序之一。这是一个完整的程序(编写一个函数会更短一些,但由于PPCG规则第二次不能正确运行,因此它被PPCG规则禁止)。输入格式如下:

[[5,[4]],[6,[5]],[7,[1,2,5]],[7,[5,2,1]],[18,[5,6,7]],[5,[3]],[10,[6,4]]]

说明

辅助函数 1Ŀ(将整数转换为其值)

®y$ÐL
   ÐL   Repeatedly, until there are no further changes,
  $       apply the following unary function to {the input}:
 y          replace values using the mapping table
®             stored in the register.
        {Then return the eventual result.}

更为方便的是,由于y定义的方式,该辅助函数将可以在单个值或值列表上正常工作。如果为单个值给出了多个映射,则从表中获取第一个映射。映射表存储在寄存器中(基本上只是一个变量; Jelly只有一个变量)。

辅助功能 2Ŀ(评估一条LET指令)

ṪÇ+Ç¥/Ṅ;®⁸Ǥ;©
Ṫ               On the last element of {the input},
 Ç              Run 1Ŀ,
     /          left fold it via
    ¥             the following binary function:
  +                 add {the two arguments}
   Ç                and run 1Ŀ on {the result},
      Ṅ         write {the result} (and a newline) to standard output,
       ;®       append the value of the register,
            ;   prepend
           ¤      the following value:
         ⁸          {the input, without its last element}
          Ç         with 1Ŀ run on it
             ©  and store that value in the register {and return it}.

我们真的不想要这里的返回值。我们只是因为它的副作用而运行它(更新寄存器并输出分配的值)。不过,果冻函数总是返回一个值,所以我们只让映射表被返回,这是最糟糕的。

主程序

⁸©ḷƓÇ€¤
 ©       Initialize the mapping table
⁸        with the empty string (which is also the empty list)
  ḷ      then evaluate and discard
      ¤  the following value:
   Ɠ       a line from standard input, parsed into a data structure
    Ç€     with each element transformed via 2Ŀ
         {and leave the empty string to be printed implicitly}

通常,在此上下文中运行时会给我们第一个命令行参数,但是没有一个(我们从标准输入中获取输入),因此它以提供空字符串的替代模式运行。需要初始化寄存器(从其默认值0,将导致崩溃y)意味着我们不能隐式提及用户的输入,这意味着从标准输入(Ɠ)中获取它与从a中获取它一样便宜。命令行参数(³),并且能够访问手段的替代使用,这意味着不寻常的(对于Jelly)输入形式实际上短了一个字节。

这可能是可改进的。我仍然不知道为什么第二行需要说⁸Ǥ;而不是仅仅说;@Ç,就我所知的果冻而言,鉴于缺乏使用µ/ ,两者应该是等效的ð /ø -但由于 /会导致崩溃。同样,还有其他各种方法可以在不丢失字节的情况下重新安排程序,因此我可能错过了使事情变得更短的一种方法。

顺便说一句,将最后一行中的更改为可以;使您对程序的内部工作有一个有趣的了解,因为它随后将输出由的返回值隐式输出的“寄存器的历史记录” 2Ḷ


5

Perl 5 5,92个字节

90个字节的代码+ -pl标志。

sub f{($b=$h{$a=pop}//$a)!=$a?f($b):$a}s%(\d+)\+(\d+)%f($1)+f$2%e&&redo;/=/;$_=$h{f$`}=f$'

在线尝试!

我使用哈希表%h存储数字之间的映射。
函数(subf返回其输入映射到的数字(如果没有映射,则返回其输入):$h{$a=pop}检索输入映射到的数字。如果不存在,则感谢//$a,其值为($b=$h{$a=pop}//$a)输入($a)。我们确保此值不是无限循环的输入本身(!=$a)。然后,我们递归调用f或返回输入。
主程序包括两个步骤:
- s%(\d+)\+(\d+)%f($1)+f$2%e&&redo评估右侧的第一个加法,同时仍然有一个加法:用x+y的评估结果代替f(x)+f(y)
- /=/;$_=$h{f$`}=f$'做作业:/=/允许使用来访问左侧$`和右侧$',然后$h{f$`}=f$'进行分配。并且我们还将其分配给$_每行之后隐式打印的内容。


5

JavaScript(Node.js),81字节

v=x=>(v[x]=v[x]||x,v[x]-x?v(v[x]):x)
f=x=>l=>v[v(x)]=l.reduce((p,x)=>v(v(x)+p),0)

在线尝试!

通过调用f和要分配的值来接收输入,然后使用要添加的值数组调用该结果。(即f(5)([4]))重复多行。

v用作计算数字的当前实际值的函数,还用作存储实际值的对象。首先v[x]=v[x]||x确保v[x]已定义。v[x]-x执行比较以确定这是否是实际数字。如果数字未映射到其自身,则v(v[x])递归重试,否则返回x

f 执行计算和赋值,并保存一个字节,第二个调用返回该值。


3

Haskell116113108106字节

(#)=until=<<((==)=<<)
e?((n,s):r)|m<-foldl1(\a b->e#(e#a+e#b))s=m:(\x->last$m:[e#x|x/=e#n])?r
e?r=[]
(id?)

在线尝试! 每个方程式4=3+1+5都记为元组(4,[3,1,5])。匿名函数(id?)获取此类元组的列表,并返回所有中间结果的列表。

#是一个函数,用于查找给定函数的固定点e和起始值x

该函数?采用评估函数e并递归求解每个方程。foldl1(\a b->e#(e#a+e#b))s计算等式的右侧,并将结果保存到m,例如用于4=3+1+5计算eval(eval(eval 3 + eval 1) + eval 5),其中每个eval是的不动点应用e。然后修改eval函数,以考虑到的新分配n(\x->last$m:[e#x|x/=e#n])与相同\x -> if x == eval n then m else eval x

初始评估函数是id将每个整数映射到自身的函数。


感谢ØrjanJohansen提供了更短的定点功能,节省了2个字节!


不错的工作!顺便说一句,您需要返回所有中间结果,因此可以删除last.
Leo

2
(#)e=until((==)=<<e)e或者(#)=until=<<((==)=<<)更短。
与Orjan约翰森

@ØrjanJohansen非常感谢!
Laikoni '17

3

OK,48个字节

a:[];s:{*(a@x;x)^0N}/;f:{a[s@x]:y:{s@x+y}/s'y;y}

用法: f[5;1 2 3] / 5=1+2+3

在线尝试!


如果您不介意可以使用的数字有上限,例如仅使用0998,则可以满足以下要求(41个字节 ±几个,取决于最大值):

a:!999;s:(a@)/;f:{a[s@x]:y:{s@x+y}/s'y;y}

说明:

; 分隔了三个定义。

a是数字的字典/地图。在第一种情况下,它是一个实际的空字典[],在第二种情况下,它是0to 的数字列表998

s是给定数字时查找“结果”数字的函数。/函数末尾的on表示它将自身应用于自己的输出,直到输出停止更改为止。

最后一位f表示:

f:{                      } /function called f, input number x, list y
                    s'y    /apply s to every number in the list
                   /       /fold through the list
            {s@x+y}        /    sum the two numbers, apply s
   a[s@x]:                 /set the s(x) to map to the final sum
          y:           ;y  /redefine y to be the final sum, then return it

3

Python 3中,146 132 130字节

@Dada节省了14个
字节@@ mbomb007节省了2个字节

d={}
g=lambda x:d.get(x)and x!=d[x]and g(d[x])or x
def f(t):
 for n,(s,*r)in t:
  for b in r:s=g(g(s)+g(b))
  d[g(n)]=s;yield g(n)

在线尝试!

接收输入为等式元组[ x = y + z + was (x, (y, z, w))],通过生成器输出。


您可以显示一个调用示例,以便对其进行测试吗?
Leo

1
@Leo添加了TIO。
Uriel's

1
g大概可以写成g=lambda x:d.get(x)and d[x]!=x and g(d[x])or x。而且我认为您可以使用1个空格来缩进而不是2个缩进。那应该使您达到[132字节](在线尝试!)。
达达

1
@Dada谢谢!太糟糕了,他们没有半角空格缩进:P
Uriel

1
没有半角空格缩进,但是另一个巧妙的技巧是使用单个制表符而不是两个空格。只要缩进不同,Python就很高兴(例如,您可以将space-tab和tab-space用作其他嵌套级别上的缩进)。这可以为您节省两个字节:)
Leo
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.