图灵全语言翻译员


42

我认为这将是一个很酷的挑战,那就是为您选择的图灵完备语言提供口译服务。

规则很简单:

  1. 您可以使用任何语言来创建此解释器,即使它比此挑战要新。
  2. 您可以使用任何图灵完备的语言,只要它与编写该语言的语言不同即可。
  3. 您可能不能简单地评估代码,例如使用eval函数。
  4. 关于您如何实现此目的的解释会很好,但不是必需的。
  5. 这将以字节计分。
  6. 每个提交都必须完全正常工作,这意味着必须显示您选择的语言所具有的每个功能。

简而言之:

您的任务是为您选择的任何一种图灵完备的语言创建一个有效的口译员。

祝好运!


3
我还将建议一个规则,即所实施的语言必须与用于实现它的语言不同,以防止出现类似琐碎eval的解决方案。
ETHproductions '17

1
实际上,您可能只想禁止eval命令/功能,因为某些语言内置了用于评估另一种语言的代码的功能。
ETHproductions '17

2
@arodebaugh对于未来的挑战,您可以将您的想法发布在沙盒中,在其中可以获取反馈并提出类似的细节,然后再挑战开始进行并得到解答。
马丁·恩德

1
好的,您可能应该更具体一些,说些类似“您不能通过任何方法简单地执行代码”之类的东西,以避免其他琐碎的答案,例如Bash + perl。
ETHproductions '17

Answers:


16

Brachylog(2)→ 帖子对应问题,9个字节

~h=∋ᵐ\cᵐ=

在线尝试!

输入是字符串列表的列表。(在Wikipedia上定义的Post对应问题中,内部列表每个都有两个元素,尽管该程序实际上可以处理任意数量的元素。)该程序按长度顺序强行解决问题,直到找到一个解决方案。已知Post对应问题可以模拟Turing机器,因此针对Turing的蛮力解决方案已经完成。如果以函数而不是程序的形式运行,它实际上也会产生有意义的输出。

上面的TIO链接中的程序是[["a","baa"],["ab","aa"],["bba","bb"]],是我从Wikipedia复制的。解决方案(程序可以很快找到)是["bbaabbbaa","bbaabbbaa"]

说明

这几乎只是Post对应问题到Brachylog的直接翻译。

~h=∋ᵐ\cᵐ=
~h         Find {the shortest possible} list which starts with {the input}
  =        and for which all elements are equal
   ∋ᵐ      such that taking an element of each element,
     \cᵐ   and concatenating elements in corresponding positions,
        =  produces a list all of whose elements are equal.

基本上,我们创建一个列表,该列表重复输入的副本(尽可能少,这意味着在强行使用时不会丢失任何可能性),从每个副本中获取一个元素,然后连接相应的元素(如Post对应关系)问题)。


1
以及通常的“有意义的事情的精简,可以节省字节,但Brachylog解释器无法处理”:前五个字节可以表示为~dp(这并不意味着完全相同的事情,但足够接近而仍然可以图灵完成),只是Brachylog解释器还不知道如何反向d

12

果冻 →“添加最小值进行转置”,5 4个字节

+"Ṃẞ

在线尝试!(仅运行一次迭代,以避免超时)

一个非常简单的图灵完备的构造:我们将一个方阵作为程序,并进行永久循环,确定字典上最小的行,然后将第一行的每个元素增加字典上最小的第一个元素,第二行的每个元素按字典上最小的第二个元素,依此类推。(Jelly程序是“ +"添加{输入的相应元素和} {原始的}最小元素,循环”;这比我以前的程序短一个字节Z+ṂZß,后者做的完全一样。显然,我应该专注于打高尔夫球果冻,而不仅仅是打高尔夫。)

产生的语言是图灵完备的,其原因与 袋鼠基本。每行的第一个元素的行为类似于跳过计数(尽管不是每条命令的跳过计数在被跳过时都会减少,而是在运行时增加每条命令的跳过计数,而是寻找具有最低跳过计数的命令比具有零跳过计数的命令;这是同一回事)。我们确保第一个元素高于其他元素(代表每个命令在每个命令的多集中出现的次数),从而确保第一行永远不会最小。第一行的其余部分可以是垃圾。唯一剩下的麻烦是对具有相等跳过计数的命令按顺序循环运行的方式进行建模,但是我们可以通过将所有跳过计数乘以一个大常量,然后加上小的“初始”来做到这一点。跳到第一列作为抢七。这使我们获得了“第一个未跳过的命令运行”,而不是“未跳过的命令按顺序循环运行”的决胜局,但是袋鼠的图灵完备结构并不关心这种差异。


10

Mathematica诠释Conway的人生游戏,64字节

CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}~Nest~##&

康威的《人生游戏》是图灵完整的。细胞自动机是斯蒂芬·沃尔夫拉姆(Stephen Wolfram)最真实的痴迷。CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}是根据Conway的《人生游戏》的一个步骤转换0和1的二维数组的规则。(我认为默认行为是该数组环绕其边缘,因此实际上是一个离散的圆环。)~Nest~##&将此规则转换为一个函数,当给定初始板状态(任何尺寸)和一个整数n作为参数时,该函数将输出n生命游戏规则的迭代结果。

为了您自己的享受,您可以使用包装的版本

b = RandomInteger[1,{50,50}];
Manipulate[ArrayPlot[
  CellularAutomaton@{224,{2,{t={2,2,2},{2,1,2},t}},{1,1}}~Nest~##&
    [b, n] ]
, {{n,0}, 0, 100, 1}]

并在50x50的板上滚动浏览100代。


如果我理解正确,那么电路板尺寸是否固定?在那种情况下,我认为它不可能是图灵完备的,是吗?
DLosc

任何对该函数的特定调用都具有固定的电路板尺寸,但是该电路板尺寸可以任意大。(请注意,文章的后半部分描述了一个观察正在执行的代码的示例,而不是实际的代码本身。)
Greg Martin

我要说的是,要使GoL成为图灵完整的,它就必须具有无限增长的模式。(例如滑翔机枪。)如果此实现不能将数组从一个步骤扩展到另一个步骤,而是将其环绕起来,则它会通过无限增长测试。
DLosc

可以肯定的是,这是一个合理的观点。但是物理计算机上的编程语言实现甚至无法满足该测试要求!一种可能是对(假设的)一系列物理计算机感到满意,这些物理计算机具有越来越多的内存,每台计算机都能够计算出该可计算功能的另一个值;不过,到那时,对于这样一个GoL程序的(假设的)输入序列应该同样满意。
格雷格·马丁

9

Turtlèd解释性CT,49字节

我也许可以打高尔夫球

另外,这不会输出任何有用的信息。它只是在给定的CT程序停止时才停止。

这实际上是我前一段时间做的(然后现在打了一些)

!-l[*+.r_]' !l[ l]r[ u.(;d' u)d(1[ r].[ l])( r)+]

这个怎么运作:

Turtlèd使用网格单元。当我说“在网格上写一些东西”时,是指在网格上放置了一组连续的字符。例

[ ][ ][ ][ ][ ][ ][ ]
[ ][H][E][L][L][O][ ]
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]

进入程序

首先输入数据:

!-l[*+.r_]' 

这本质上是一个猫程序。它将输入写入网格。

然后输入命令:

!

这些命令的作用:

这些命令是“产品”。如果最左边的数据位为1,则将生产内容复制到数据字符串的末尾。否则什么也不会发生。然后最左边的数据位被删除,它使用下一个最左边的数据位的下一个产生。当数据字符串中没有位时,程序将暂停。完成这些生产的一种方法是分别处理生产的零碎部分。这就是我们的程序所做的。它分别将命令字符串中的位复制到数据字符串的末尾,并分别从数据字符串中删除位

关于该程序如何执行的。输入命令后,乌龟/网格指针将移回数据字符串的最左位。然后进入循环

[ u.(;d' u)d(1[ r].[ l])( r)+]

它在此循环中的作用是从最左边的数据字符串向上移动,并记下当前命令字符(u。)。如果是;,则表示生产结束,它将向下移动并删除其下面最左边的数据位,然后向上移动((;d' u))。然后,无论哪种方式,它都向下移动一个()。然后,命令指针将递增,因此我们将在循环的下一次迭代中写下下一个命令。如果没有更多的数据字符串,这意味着我们将处于一个空格,循环将结束。否则,我们将重新运行循环。d)。如果该位没有被删除,则意味着它必须在最后检查是否从命令中复制一个位。因此,如果此字符(即最左边的数据位)为1,它将移至数据字符串右端的末尾,从命令字符串中复制该位,然后移回最左侧数据的空间位((1[ r].[ l]))。现在,它位于最左边的数据位(为零)或最左边的数据位的左边。因此,如果在空格上,我们向右移动(( r)


尝试更多地打高尔夫球!
arodebaugh

9

Perl三星级编程器变体,26 +1 = 27字节

++$a[$a[$a[$_]]]for@F;redo

在线尝试!(此链接包含一个标头,该标头在设置一定的迭代次数后退出程序(这样TIO不会超时),并在每次迭代时打印内部状态(以便它可以观察到)。)

运行时-a(罚款1个字节,因为您可以在-M5.010产生之前将其放入-aM5.010)。

具体来说,这实现了三星级程序员,其中命令之间用空格隔开,并且文件中没有I / O扩展名的注释是不允许的。(显然,这些更改对语言的Turing完整性没有影响。)在线上没有三星级程序员的Turing完整性证明,但它是Turing完全证明(我一直在分享其Turing的草图证明。 -与其他esoprogrammer完全相同,但是当我发现一旦克服了最初的震惊,实际上就很容易编程时,就停止使用该语言。

该程序实际上并不需要太多解释。三星级编程器有一个非常简单的规范,这是它的直接翻译。唯一的妙处:@F是数组形式的程序输入(这是的结果-a);并且redo将重复整个程序,因为它是在隐含的循环(也有后果-a)。


1
我认为箭头比“解释”更有意义。
quintopia'5

9

x86程序集(Intel语法/ MASM)-Brainfuck 2127字节。

还是高尔夫

.386
.model flat,stdcall
.stack 4096
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
ExitProcess proto,dwExitCode:dword
.data
bfsrc BYTE 200 dup(0) 
bfcells BYTE 100 dup(0) 
loopStack DD 5 dup(0) 
charBuf BYTE 5 dup(0) 
newline BYTE 10,0 
prompt BYTE "$",0 
hr BYTE 50 dup('-'),0 
space BYTE ' ',0
.code
EvalBf proc
    start:
    invoke StdOut, addr prompt
    invoke StdIn, addr bfsrc,200
    cmp bfsrc,0
    je exit
    mov eax,0 
    mov ebx,0 
    mov ecx,0 
    processInstruction:
    cmp BYTE PTR bfsrc[ebx], '+'
    je plus
    cmp BYTE PTR bfsrc[ebx], '-'
    je minus
    cmp BYTE PTR bfsrc[ebx], '>'
    je fwd
    cmp BYTE PTR bfsrc[ebx], '<'
    je back
    cmp BYTE PTR bfsrc[ebx], '['
    je open
    cmp BYTE PTR bfsrc[ebx], ']'
    je close
    cmp BYTE PTR bfsrc[ebx], '.'
    je dot
    jmp processNextInstruction
    plus:
    inc BYTE PTR bfcells[eax]
    jmp processNextInstruction
    minus:
    dec BYTE PTR bfcells[eax]
    jmp processNextInstruction
    fwd:
    inc eax
    jmp processNextInstruction
    back:
    dec eax
    jmp processNextInstruction
    open:
    mov loopStack[ecx*4],ebx
    inc ecx
    jmp processNextInstruction
    close:
    dec ecx
    cmp BYTE PTR bfcells[eax], 0
    je processNextInstruction
    mov ebx,loopStack[ecx*4]
    inc ecx
    jmp processNextInstruction
    dot:
    mov dl, BYTE PTR bfcells[eax]
    mov BYTE PTR charBuf[0], dl
    mov BYTE PTR charBuf[1],0anything
    push eax
    push ecx
    invoke StdOut, addr charBuf
    pop ecx
    pop eax
    jmp processNextInstruction
    processNextInstruction:
    inc ebx
    cmp BYTE PTR bfsrc[ebx], 0
    je done
    jmp processInstruction
    done:
    invoke StdOut, addr newline
    mov eax, 0
    printNext:
    cmp eax, 100
    jge reset
    push eax
    invoke dwtoa, BYTE PTR bfcells[eax], addr charBuf
    invoke StdOut, addr charBuf
    invoke StdOut, addr space
    pop eax
    inc eax
    jmp printNext
    reset:
    invoke StdOut, addr newline
    invoke StdOut, addr hr
    invoke StdOut, addr newline
    jmp start

    exit:
    invoke ExitProcess,0
EvalBf endp
end EvalBf

3
通常,汇编答案会根据生成的机器代码的大小来计算,因此您根本不需要打高尔夫球,只需最小化指令的数量/大小即可。
罗伯特·弗雷泽

@RobertFraser呃,我不知道该如何计算:P
Christopher

3
实际上,起初我以某种方式将标题读为“在Brainfuck中实现的x86 asm”,并给人留下了深刻的印象:)
quetzalcoatl

@Quetzalcoatl这将是令人印象深刻
克里斯托弗·

1
请高尔夫变量/标签名称ty
ASCII码,仅适用

8

解释循环标签系统,16字节

YqWyyPBg@++vXPOy

将标记系统的生产作为命令行参数,并将标准输入的数据字符串从stdin中获取。

上面的代码有点难以验证,因为它不会产生任何输出(因此,唯一可观察到的行为是“终止”与“不终止”)。因此,这是一个非高尔夫版本,在每个步骤之后输出数据字符串,并在20个步骤之后终止,因此TIO不必处理无限循环产生的大量输出:在线尝试!

循环标签系统

循环标签系统是一个非常简单但又具有图灵完备的计算模型。它们由定义对数据字符串的操作的产品列表组成。生产和数据字符串由1和0组成。

在每个步骤中,都将删除数据字符串的最左侧字符。

  • 如果字符为1,则当前生成的内容将附加到数据字符串的右侧。
  • 如果字符为0,则不附加任何内容。

无论哪种情况,当前生产都会循环移动到列表中的下一个生产:如果我们在最后一个生产中,则循环到第一个生产。执行将继续直到数据字符串为空。

说明

                  g is list of cmdline args; v is -1 (implicit)
 q                Read a line of stdin for the data string
Y                 and yank it into the y variable
  Wy              While data string is nonempty:
       g@++v       Retrieve the next production from g (using cyclic indexing)
             POy   Pop the first character of y
            X      String-multiply: result is the production if the first character of y
                   was 1, or empty string if it was 0
    yPB            Push that string to the back end of y

嘿,我只记得您不需要输入数据字符串;它可以只是1来源:esolangs链接到此arxiv.org/abs/1312.6700。我将很快编辑我的答案,如果这对您的答案有所帮助,您应该(实际上您的输入似乎足够精通)
Destructible Lemon

8

迭代的通用Collat​​z函数 -> Python 2,46字节

a,b,x,m=input()
while-~x%m:x=x/m*a[x%m]+b[x%m]

用一个m-1个a和b,一个起始值x和一个除数m的列表来调用此函数,它们共同构成了IGCF的“程序”。当模数为m-1时,这不会停止,而是采用第三个数组来指示要停止的模数。这种简化意味着将给定的Fractran程序转换为该变体可能要花费一些额外的精力,但确实在解释器中节省了几个字节。

在线尝试!该TIO演示了如何用此语言添加5 + 5。程序a = [3],b = [0],m = 2进行加法运算,从7776 = 2 ^ 5 * 3 ^ 5开始最终产生59049 = 3 ^ 10。


老板真不错 我希望赢得赏金,但又要做好
Christopher

7

重复变体-> Python个字节

l=input()
while l:l=l[2+l[0]:]+l[2:2+l[0]]*l[1]

此函数解释ResPlicate的变体

  • 对于这个程序,它是一个偶数长度的python列表,偶数元素的偶数索引。
  • 没有I / O。
  • 为此,尝试复制比队列其余部分中更多的值只是复制队列的其余部分(即,复制的位不会用零填充到所需的长度)。

最后的更改意味着某些ResPlicate程序(满足第一个条件)在此变体中的行为将不同,但是幸运的是,BCT解释器不需要删除的功能,因此该语言仍为TC。

在线尝试!该TIO上刻有一张打印纸,以表明它可以正常工作,还有一个标头,该标头在1秒钟后杀死了该程序,还有一个示例产生了比TIO在那一秒钟内可以处理的更多输出的示例。


2
为什么不l=input()呢?会短一个字节。
feersum

7

Perl -aI / D机器,24字节

$p=$a[$p]+=$_ for@F;redo

在线尝试!(包含一个标头,该标头打印内部状态并在10次迭代后暂停,以便可以观察到该行为)

关于语言

我花了几天的时间在I / D机器上工作,这是我关于非常简单的编程语言的最新想法之一。它的工作方式如下:数据存储区由无限制的RAM组成,最初为全零。每个元素都可以存储一个无界整数(尽管实际上,大多数I / D机器程序将在其中大多数中仅存储小整数,并且仅将无界整数用作寻址具有大地址的单元的一种方式)。还有一个数据指针,它指向一个单元格(即,将地址保存为一个单元格)。最初也是零。

只有两个命令:

  • I:递增数据指针指向的单元格。(数据指针本身保持不变。)
  • D:取消引用数据指针,即读取数据指针指向的单元格的值。然后将您读回的结果值存储到数据指针中。

执行只是永远重复地在循环中运行程序。

如此简单的语言是图灵完备的语言,这真是令人惊讶,因此我一直在努力证明这一点。这是证明。它与三星程序员的证明非常相似(但比其简单得多),这是一种非常相似的语言(并且实际上,此提交围绕该程序使用了相同的基本OISC“外壳”,仅在实际实现的指令上有所不同)。

关于程序

用法

输入应在标准输入上给出,并且是一个不带注释且使用RLE / OISC语法的I / D机器程序。(I / D机器有两种不同的等效语法,但是出于高尔夫的目的,该程序仅支持其中一种。)在这种语法中,程序是一个十进制数字序列,代表I命令在D命令之间的运行长度。(您可以D通过放置“ 0游程” 来指定两个或多个连续命令I在它们之间命令的,因此语法是完全通用的。)

说明

从该程序可以看出,这并不是单独实现Iand D命令。实际上,它是一个(非常轻微的)优化的解释器(完全是因为以这种方式编写的时间较短)。关键是要看到运行n个增量命令会使数据指针的目标增加n倍,即向其添加n;并且还可以用这种方式实现运行0个增量命令,因为将0加到内存中无效。因此,我们实际实现的操作是在实现游标I和之间交替进行D。换句话说,“加n到数据指针所指向的值(将其存储回数据指针所指向的值),然后读取数据指针所指向的值并将其存储在数据指针中。”显然,它比所需的更为冗长,我们可以进一步简化为“加n加到数据指针所指向的值,然后将该值存储在数据指针的目标和数据指针本身中”。

这就是我们程序的核心。我们正在使用一个数组$a来存储RAM,并$p作为数据指针(索引到数组中):

$p=$a[$p]+=$_
         + $_  add {the run length}
   $a[$p]      to the element of $a pointed to by $p
   $a[$p] =    storing the result back into that element
$p=            and also in the pointer itself

方便地,当Perl被当作数字对待时,Perl会将未初始化的数组元素解释为0,因此对我们来说,该数组将被延迟初始化为零,而无需任何明确的代码。(一个潜在的问题是数字变大时的数字精度;但是,只有在使用的数组数量超过机器的地址空间(Perl整数足以容纳指针)时,才会发生这种情况。在理想的机器上。)

最后,我们需要做的就是将该程序放入几个循环中。该for@F循环与-a命令行选项结合,将在标准输入的字段上循环(此处的“ field”的默认定义将在空白处分割)。该redo循环会将整个程序置于一个隐式循环中(而不是方便地读取标准输入),这将导致该程序根据I / D机器的语义重复在一个循环中运行。


欢迎回来!我们不再需要为口译员评分标志,只需注意这是“ Perl with -a”。codegolf.meta.stackexchange.com/a/14339/9365
唐·黑斯廷斯

6

果冻2标签系统,8字节

µḢị⁴⁸;Ḋß

在线尝试!

我有一个偏爱实用语言的赏金计划,但我想我最好还是在赢得原始任务时就去争取(因为我无法完全赢得自己的赏金)。

实现不带暂停状态的标记系统变体,因为图灵完整性不需要它。状态从1开始连续编号,并且初始字符串位于程序之前。

例如,维基百科给出了一个标签系统的示例{ abc},{ abcbacaaa}的初始串aaa; 在此输入格式,这就是[1,1,1][[2,3],[1],[1,1,1]]。(标记系统没有固定的语法,这似乎是一种合理的方法。)

TIO链接添加了 (“写入内部状态并向stdout插入换行”),以表明该程序实际上正在运行。

说明

µḢị⁴⁸;Ḋß
           {implicit: initialise internal state from first argument}
µ          Disregard the second command-line argument by default
 Ḣ         Take the first element, removing it from the internal state
  ị⁴       Use the value to index into the second argument
    ⁸;     Prepend (the rest of) the internal state
      Ḋ    Discard the first element of the internal state
       ß   Loop forever

6

在图灵机中实现的“ BF / P”,842字节

过渡表(由于长度而链接)

过渡桌,少打高尔夫球

我使用的图灵机模拟器

当然,这不会赢得任何奖项,但这是我一直想做的事情,因为BF与图灵机非常相似。每个单元格存储一个来自0x0- 的值0xF。但是,Turing Machine网站的宽度可以使浏览器不崩溃。在,.功能(输入和输出)没有被定义,所以这是更有点像P”不是真正的BF。

要运行它,请将过渡表粘贴到Turing Machine模拟器中,将输入设置为某些BF代码,然后按run。

TM的磁带同时存储BF代码和BF数据,中间有一个空格。它通过修改当前正在运行的字符([-> (等)以及在数据中的位置来跟踪其在代码中的位置。^在单元格前面。读取命令字符后,它会移动直到碰到插入符号,将一个单元格移到右侧,然后执行适当的功能。然后返回,在BF代码中查找“已修改”命令字符之一,然后继续进行下一个操作,重复整个过程。一旦代码用完,它将停止。

理解其工作方式的最佳方法是运行非高尔夫版本,将其置于步进模式,并观察哪些行导致哪些行以及每个状态/行块做什么。

高尔夫版本和非高尔夫版本在工作方式上完全相同,但非高尔夫版本具有更人性化的名称,并分为多个部分。


1
后长度限制是绰绰有余,以适应转换表
ASCII-仅

6

C实现(2,3)Turing Machine236 205个字节(如果您不关心笨拙的输入,则少46 31 个字节)

感谢-11字节的Appleshell,-12字节的VisualMelon和-7字节的Johan du Toit。

CeilingCat制作了仅使用144个字节的版本,请参见此处

(我在这里添加了一些换行符,因此您不必滚动,但通常大多数将被删除)

#define c char
j;i;k;c s,d[256];c main(){c*p=d+128;gets(d);
for(;k<256&&d[k];)d[k++]-=48;for(;++j<256;)
{c t=*p;*p=-t*t+(2-s)*t+1+s;p+=(s^t==0)*2-1;s=s?t%2:!t%3;
for(i=0;++i<256;)printf("%d",d[i]);puts("");}}

在线尝试!

使用方法:输入最多256个1、0和2的字符串以初始化磁带。任何未初始化的值将为零。(0、1和2以外的值可能会导致未定义的行为。)该程序将迭代256个步骤。可以通过修改代码来增加迭代步骤的数量,但是显然这需要更多的字符。

这是相当长的篇幅,但这是我第一次做这些事情,而且我没有使用专用的高尔夫语言。我玩得很开心,即使结果比我预期的更长。

许多字节来自处理输入和输出,我通过使其接受0、1和2而不是NUL,SOH,STX丢失了整个42个字节。(要进行更改,请k;从前面删除for(;k<256&&d[k];)d[k++]-=48;第二行中。)

晶体管表,尤其是线*p=-t*t+(2-s)*t+1+s;(用于设置磁带上的值)也可能会被压缩得更多。


1
哇,这是您的第一个高尔夫代码!精彩!
扎卡里

您可以缩短全局变量的声明是这样的:k,j;c s,d[256];int在C隐式的,那么你也可以移动i到全局声明节省3个字节以上)
Appleshell

@Appleshell谢谢,我会做到的。
a52

您可以将字符串null-terminal check移到for循环内。内联k++并删除{}保存会节省更多的字节:for(;k<256&d[k];)d[k++]-=-48;因为j这只是一个计时器(从未使用过的值),所以您可以通过向后计数来替换它(和ik:您知道k==256在第一个循环之后,因此在第二个循环中递减为零for(;k>0;),它的叶子k==-1,所以最后一个环就呈现for(;++k<256;)。(免责声明:我通常打高尔夫球C#,但这似乎可以编译)。
VisualMelon

1
@VisualMelon我确定了问题。我需要使用k<256&&d[k],而不是&,因为d[k]正在接受评估k==256。另外,由于k不再保证256在该循环之后,因此我必须在之后重新设置它以保证256个步骤。(如果您(也就是VisualMelon)还有其他建议,我们可能应该将其放在聊天中,这样我们就不会收到太多评论了)
a52

5

RODA实施Fractran114个 112 106字节

@fergusq通过重新排列参数节省了1个字节

f&n,a{x=1{x=0;(a/" ")()|[_/`/`]|[parseInteger(_[0],_1[1])]|{|q,w|{n*=q/w;x=1}if[n%w<1,x<1]}_,_}while[x>0]}

在线尝试!

调用像这样的功能:f reference_to_input program。输出将存储在的位置input


之后的分号e[1]是多余的。您也可以通过更改参数顺序来节省一个字节:f&n,a
fergusq

@fergusq感谢您的f&n,atrick 俩,当您发表评论时,我正打算删除该分号:)
Kritixi Lithos's

5

Clojure,82 81字节(车床)

更新:从中删除了一个空格t{} s

#(loop[p 0 t{}s 1](if-let[[S M N](%[(or(t p)0)s])](recur(+ p M)(assoc t p S)N)t))

将图灵机实现为循环,在达到暂停状态时返回磁带。在状态转换规则中,这可以通过省略转换状态来表示。由于未从输入hash-map中找到相应的状态转换,因此设置Nnil,随后if-let将终止%。实际上,此状态的任何值都可以,例如:abort0或-1。

Ungolfed一个示例3态2码元从忙海狸维基百科

(def f #(loop[pos 0 tape {} state 1]
          (if-let [[sym move next-state](%[(get tape pos 0)state])]
            (do (println [pos tape state])
                (recur(+ pos move)(assoc tape pos sym)next-state))
            tape)))

(f {[0 1] [1  1 2]
    [0 2] [1 -1 1]
    [0 3] [1 -1 2] 
    [1 1] [1 -1 3]
    [1 2] [1  1 2]
    [1 3] [1  1]})

{0 1, 1 1, -1 1, -2 1, -3 1, 2 1}

在线尝试

在6700K的单核上,这将在大约29秒(或160万步/秒)中运行5状态2符号繁忙海狸(4710万步)。


5

中号尖端,4个字节

Ṅ×ịß

在线尝试!

TIO链接添加了一个页脚,以使用Esolang页面上显示的示例Tip程序示例调用该函数(M的“自动包装器”调用函数,就好像它们不能处理有理数或定点数,或者至少我没有还没有弄清楚如何告诉它怎么做,所以我需要手工将该功能变成一个完整的程序才能运行它。)

实际上,这会打印出有用的调试输出。该程序不能用M中的3个字节编写,因为正好由三个双字符组成的程序会触发解析器中的特殊情况,因此我不得不添加一条额外的命令来避免特殊情况。使其(使用换行符打印)至少使其有用。

ı一世=-1个)。

不实现I / O(暂停/不暂停除外)。I / O是Tip的扩展(不是语言本身的一部分),并且不是Turing完整性所必需的。

说明/背景

Ṅ×ịß
Ṅ     Print {the left argument} and a newline; also resolves a parser ambiguity
  ị   {The left argument}th element of {the right argument}, wrapping on OoB
 ×    Multiply {the left argument} by {the chosen element}
   ß  Recursive call; arguments: {the product} and {the same right argument}

[1,2,3][1,2,3,1,2,3,1,2,3,…][RX+s,这是一个多项式,而许多高尔夫语言内置的“基本转换”实际上是一种变相的通用多项式评估器。因此,我们要做的就是索引到数字列表中,对它们进行基转换,就可以了,对吗?

XX

XXÿXÿ。当然,我们可以将链接行为覆盖到几乎所有我们想要的东西,但这将花费整个字节,并且此问题的高尔夫球语言条目太短,以至于一个字节很多。

因此,我回头重新评估了一下。我们可以使用任何运算来代替多项式求值吗?理想情况下,它们是可交换的,因此我们不必担心参数顺序?不久之后,我意识到Collat​​z函数比它们所需的更为复杂。

s

当然,与基数转换()不同,乘法(×)是可交换的,因此参数放置的顺序无关紧要。因此,我们只需要编写×ị,然后使用,将程序放入无限递归中ß,我们有一种图灵完备的语言。对?

XÿXÿ¹×ịß¹¹ ; 是一个不错的选择,因为它会产生有用的调试输出。

三个字节可以吗?除非我有所遗漏,否则不能通过这种特定的实现语言和实现语言来选择,但是在这一点上肯定可以通过某种方式实现,因为有很多方法可以在四个图灵中完成您可以实现的语言。


再考虑一下之后,我们可以使用而不是×and 将其减少到三个字节。最终的语言与Tip并不完全相同,但是出于相同的原因,它非常相似,并且几乎可以肯定是Turing-complete。不幸的是,它没有在M中实现,并且当输入中的任何一个都是非整数实数时,我找不到任何方法使Jelly执行任意精度计算。但是,如果有人知道任何其他高尔夫语言可以在这种构造下工作,请随时尝试一下。
ais523

4

C解释Brainfuck,187字节

t[999],*p=t,c,i,l;f(char*t){for(i=0;c=t[i];i++){c^62?c^60?c^43?c^45?c^46?c^44?c^91:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;if(c==93&&*p)for(l=1;l>0;)c=t[--i],c==91?l--:c==93?l++:0;}}

在线尝试


3
Welp,一定有使用BF的答案。
扎卡里

4

Lua解释Brainf ***,467字节

b,r,a,i,n,s=0,io.read,{0},1,1,"><+-.,[]"c,f=r(),{function()n=n+1;a[n]=a[n]or 0;end,function()n=n-1;a[n]=a[n]or 0;end,function()a[n]=a[n]+1;end,function()a[n]=a[n]-1;end,function()io.write(string.char(a[n]))end,function()a[n]=io.read():byte()end,function()i=a[n]~=0 and i or c:find("]",i)end,function()if a[n]~=0 then b,x=1,""repeat i=i-1 x=c:sub(i,i)b=x=="["and b-1 or x=="]"and b+1 or b until b==0 and x=="["end end}repeat f[s:find(c:sub(i,i),1,1)]()i=i+1 until i>#c

我知道以后还可以做一些减肥,但这是我的第一遍结束的地方。从标准输入中获取Brainf代码。


2
为+1 brains,当高尔夫球手分配一个变量列表时,这总是很有趣。
扎卡里

4

CJam→ResPlicate变体,15 14 13字节

-1字节感谢@ ais523

l~{(/((*+e_}h

该变体与此答案中的变体相同,除了从队列中取出的项目数比队列中的最高数少一。

l~{ ... }h部件仅将一个数组作为输入并重复直到该数组为空。

主循环说明:

    e# Stack:             | [3 2 1 1 2 2 2 1]
(   e# Pop first element: | [2 1 1 2 2 2 1] 3
/   e# Split chunks:      | [[2 1 1] [2 2 2] [1]]
(   e# Pop first:         | [[2 2 2] [1]] [2 1 1]
(   e# Pop first:         | [[2 2 2] [1]] [1 1] 2
*   e# Repeat array:      | [[2 2 2] [1]] [1 1 1 1]
+   e# Concatenate:       | [[2 2 2] [1] 1 1 1 1]
e_  e# Flatten:           | [2 2 2 1 1 1 1 1]

您实际上不需要在这里增加。只需指定在原始程序中将块长度增加1即可;但这不会损害ResPlicate的Turing完整性(存在TC结构中,块长度和重复计数永远不会相互混合)。

3

芯片,20 + 3 = 23字节(规则110)

AZZ
>}/a
`)\'E~Zte*f

国旗为+3 -z

在线尝试!

该提议是不完美的,因为芯片没有(还)有任何循环能力,所以输出必须作为输入模拟多代,以传递这样的事情(当然,你可以无限期地运行循环,并且Chip可以处理任意长的输入,因此此组合为Turing Complete)。

此实现采用ASCII 0s和1s 形式的输入和给定输出。这里的逻辑如下:

p := value of left neighbor cell    AZZ
q := value of current cell          AZ
r := value of right neighbor cell   A

q' := ((r xor q) and p) or          >}/a
      ((r or q) and ~p)             `)\'

其余元素用于内部管理:e*f导致ASCII数字输出,并E~Zt在输入耗尽后两个字节终止执行(因为宽度每一代增加2)。


3

Clojure,75字节(循环标签系统)

更新1:替换some?nil?

更新2:修复的Selse分支中缺少的内容if s

#(loop[[p & P](cycle %)[s & S]%2](if(nil? s)S(recur P(if s(concat S p)S))))

实现循环标签系统nil如果程序停止返回,否则永远循环。Clojure确实在这里散发出无限的惰性序列(例如循环)和破坏力。一和零表示为真值和假值。当数据字符串用完时s变为nil

取消高尔夫:

(def f #(loop[[p & P] (cycle %) [s & S] %2 i 5]
          (do
            (pprint [p (concat [s] S)])
            (if (and (some? s) (pos? i))
              (recur P (if s (concat S p) S) (dec i))))))

结果示例:

(f [[false]] [true true])
[[false] (true true)]
[[false] (true false)]
[[false] (false false)]
[[false] (false)]
[[false] (nil)]

(f [[false true true] [true false] [true false true]] [true])
[[false true true] (true)]
[[true false]      (false true true)]
[[true false true] (true true)]
[[false true true] (true true false true)]
[[true false]      (true false true false true true)]
[[true false true] (false true false true true true false)]

2

JavaScript解释规则 110,131个字节(99个字节?,28个字节?)

a=(p,q,r)=>q+r+q*r+p*q*r
b=l=>{r="";for(i=0;i<l.length-2;i++)r+=a(l[i],+l[i+1],+l[i+2])%2;return r}
c=(l,n)=>!n?l:c(b(0+l+0),n-1)

如您所见,该代码定义了3个函数, abc。也许可以通过将字节合并到1个函数中来保存字节(我不知道怎么做),但是最好分开,因为每个字节在某种意义上已经完成了这一挑战。

函数a采用3个数字作为输入,并计算其中的一些怪异多项式。当这3个数字为0或时,1它们可以视为规则110单元。输出的奇偶校验a然后可以视为下一代中间单元的值。因此从某种意义上说,这个简单的功能已经是规则110的“解释器”(28个字节):

a=(p,q,r)=>(q+r+q*r+p*q*r)%2

然后,我们可以创建一个新函数b,该函数a对一和零字符串的每个字符求值。b那么,这比a使用Rule 110解释器。在评估保存后采用mod 2保存方括号(99字节):

a=(p,q,r)=>q+r+q*r+p*q*r
b=l=>{r="";for(i=0;i<l.length-2;i++)r+=a(l[i],+l[i+1],+l[i+2])%2;return r}

要使用规则110实际计算功能,用户必须指定起始状态和生成的代数,之后输出将“出现”。我们可以制作第三个函数c,该函数采用一串零和一,以及一个正整数n,然后b对该字符串n求和。像这样,我们真的可以将规则110视为一种编程语言,其中程序是初始状态和数字n,而输出是n后代状态。该函数c现在是该编程语言的实际解释器,因此针对该挑战的最终代码就是我上面介绍的内容。


这是否在适当的背景下计算110?我的一个较早的答案被删除,因为它没有背景。
小麦巫师

@WheatWizard背景是输入的一部分,因此您的答案不应该被删除
Jens Renders

背景应该是无限的,您可以接受无限的输入吗?
小麦巫师

@WheatWizard它不必一定是无限的,它必须能够任意地变大,并且可以
Jens Renders

1
如果您事先决定世代,那么规则110并不是图灵完备的,并且您确实需要在我了解的构造中进行无限次输入。即使有人发现初始状态有限的构造,您也无法知道程序运行前所需的内存或时间,因为这样您就可以解决停止问题。
与Orjan约翰森

2

JS->换行符854字节

(function(d){var b=0;var n=!0;var c=[];var h=[];var e=0;var l=[];var m=0;var f=2;var a=0;var g=!1;var k=function(a){if(a===1)return!1;if(a%2===0&&a!==2)return!1;if(a%3===0&&a!==3)return!1;if(a%5===0&&a!==5)return!1;if(a%7===0&&a!==7)return!1;for(var b=7;b<d.round(d.sqrt(a))+1;b++)if(a%b===0)return!1;return f=a,!0;};var j=0;var i=0;var o=function(q){var o=d.__split(q,'\n');d.println(o);for(var n=0;n<o.length;n++)if(n>=f^2&&n<=f+1^2&&k(n)){f=n;for(var p=0;p<o[n].length;p++){if(o[n]==='+'&&(a+=c[b],b++),o[n]==='-')if(g===!0&&a<=0)break;else a-=c[b],b++;if(o[n]==='*'&&(a*=c[b],b++),o[n]==='/'&&(a/=c[b],b++),o[n]==='s'&&(a=d.sqrt(a)),o[n]==='%'&&(a%=c[b],b++),o[n]==='a'&&l.push(a),o[n]==='g'&&(a=c[b],b++),o[n]==='q'&&c.push(a),o[n]==='i'&&a++,o[n]==='d')if(g===!0&&a<=0)break;else a--;o[n]==='r'&&(g=!0),o[n]==='w'&&(g=!1),o[n]==='['&&(j=n),o[n]===']'&&a>0&&(n=j,h[e]--),o[n]==='{'&&(i=n),o[n]==='}'&&h[e]>0&&(n=i,h[e]--),m=a,o[n]==='k'&&e++;}}};});

超级打高尔夫球,感谢Google。


我认为您将此答案发布给了错误的挑战。您是要发布此挑战吗?

1
在这种情况下,您需要修改实现以针对不同的胜利条件。这是代码高尔夫球,而不是普及竞赛。例如,您有很多变量名可能明显短一些,这意味着该解决方案并不是一个有力的竞争者。您可能暂时将其删除,然后在有时间打高尔夫球时取消删除。

1
但是,未认真尝试针对胜利条件进行优化的答案是违反规则的。这是删除它的充分充分的理由,直到您使其符合规则。

1
您可以将所有var语句组合在一起:var b=0,n=!0,c=[],h=[],e=0,l=[],m=0,f=2,a=0,g=!1;
硕果累累

1
请删除所有varty
仅ASCII的

1

Clojure,87个字节(规则110)

功劳 奇偶校验码进入延呈现!我真的很努力地表达这一点,我打算[p q r]从二进制转换为整数并使用查找表。

#(iterate(fn[S](for[[p q r](partition 3 1(concat[0]S[0]))](mod(+ q(* q(+ 1 p)r)r)2)))%)

这里 partition和Clojure的解构使逻辑应用程序非常简单。该函数返回无限的状态序列,因此调用者可以对take所需数量负责,或者仅nth跳到特定状态。如果填充为零的填充是两个元素而不是一个元素,那么胶带将不断增长,从而避免了边界问题。现在,它保持原始宽度。

例:

(def f #(iterate(fn[S](for[[p q r](partition 3 1(concat[0]S[0]))](mod(+ q(* q(+ 1 p)r)r)2)))%))

(pprint (take 5 (f '(0 0 0 0 0 1 1 1 0 0 1 0 0))))
((0 0 0 0 0 1 1 1 0 0 1 0 0)
 (0 0 0 0 1 1 0 1 0 1 1 0 0)
 (0 0 0 1 1 1 1 1 1 1 1 0 0)
 (0 0 1 1 0 0 0 0 0 0 1 0 0)
 (0 1 1 1 0 0 0 0 0 1 1 0 0))

1
如果您仅使用原始宽度,则该图不可能是图灵完备的,因为它的存储空间有限。(实际上,规则110中所有已知的图灵完备结构都需要使用“填充”来扩大宽度,因为程序继续进行时要具有根据用户输入指定的模式,并且左右两侧有所不同,而不是只是使用零。)

我知道,这使其仿真变得相当困难。Clojure cycle可以构建无限的填充模式,但是执行第一步将花费无数的时间:/
NikoNyrh

想到这一点,将这些填充模式用作其他参数并向左和向右扩展1块模拟磁带并不会太棘手。此处的信息速度为1个块/迭代,因此我们只需要模拟具有不对称结构的中心块周围的“光锥”。(CMIIW)
NikoNyrh

1

APL(Dyalog)Fractran变体,15字节

(⊃0~⍨××0=1|×)⍣≡

在线尝试!

该函数将有理数作为一个数字列表而不是两个包含分子和分母的列表,并在程序结束时输出结果。这实现了Fractran的变体,该变体在程序结束时具有有理数1/1(= 1)。(据我所知)1不会影响Turing完备性,因为只有当其他有理都不起作用时,程序的输入才会落在1上,而当其他有理都不起作用时,输入不会更改。仅用于使函数知道何时结束。

TIO链接在第一个输入上运行该函数2次迭代(因此您可以看到输出,因为程序没有结束),然后运行第二个输入直到完成,然后返回输出。

(⊃0~⍨××0=1|×)⍣≡ 将有理数列表作为左参数,称为⊣,将输入作为右参数,称为⊢

(⊃0~⍨××0=1|×) 功能训练

  • 1|×得到×⊣和⊢ 的乘积小数点后的部分(模1)

  • 0= 等于0吗?

  • ×× 将此结果与⊣×⊢相乘,只要有理×not不是整数,就将其替换为0

  • 0~⍨ 删除所有0

  • 得到第一个元素

循环直到输入不变,请注意将的结果(⊃0~⍨××0=1|×)重新用作输入,因此,如果它停止更改(最后为1的结果),程序将停止


1

JavaScript:Lambda微积分(123

在Duples中使用Debruijn指数表示。

V=function b(c,d){if(!isNaN(c)){for(;--c;)d=d[1];return d[0]}return 0==c[0]?e=>b(c[1],[e,d]):b(c[0],d)(b(c[1],d))}

S组合器是 [0, [0, [0, [[3, 1], [2, 1]]]]]

K是 [0, [0, 2]]

我是 [0, 1]

编辑:剃光了9个字节,替换"number"==typeof c!isNaN(c)


0

APL(Dyalog Unicode),15 字节SBCS

完整程序,用于实现广义的一维元胞自动机执行器。这包括图灵完成的规则110。提示stdin初始状态,迭代次数(或继续直到稳定或{⍵≡⎕←⍺}显示所有中间值直到稳定)和规则集。

⎕∊⍨∘(⊢∘⊂⌺3)⍣⎕⊢⎕

在线尝试!(规则110的4次迭代)

 提示输入初始状态并

 产生的结果(将状态与迭代次数分开)

⍣⎕ 提示输入迭代次数,并多次应用以下函数:

() 应用以下默认功能:

  ⌺3 获取所有长度为3的邻域(以及有关它们是否在边缘的信息),并对每个对应用以下默认函数:

    包围社区

    和

    产生(放弃有关处于边缘的信息)

 然后

∊⍨ 检查他们是否是

 提示您输入要在下次迭代中启用的社区列表

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.