首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最快的迷你-Flak Quine

最快的迷你-Flak Quine
EN

Code Golf用户
提问于 2016-12-30 22:00:32
回答 1查看 2.4K关注 0票数 26

Mini是脑Flak语言的一个子集,其中不允许<><...>[]操作.严格地说,它不能与以下正则表达式相匹配:

代码语言:javascript
复制
.*(<|>|\[])

迷你Flak是已知最小的图灵完整的脑-Flak子集.

不久前,我能够用奎因制作迷你Flak,但它在宇宙的生命周期中运行得太慢了。

所以我对你的挑战是制造一个更快的奎因。

评分

为了对代码打分,在代码的末尾放置一个@cy标志,并使用-d标志在红宝石解释器中运行它(在网上试试使用ruby解释器)。您的分数应打印到STDERR,如下所示:

代码语言:javascript
复制
@cy <score>

这是您的程序终止前的周期数,并且在运行期间是相同的。由于每个周期所需的运行时间都是相同的,所以您的分数应该与运行程序所需的时间直接相关。

如果Quine太长,无法在计算机上合理运行,则可以手工计算周期数。

计算循环数并不是很困难。循环数等于单次运行数的2倍加上运行的nilad数。这与用单个字符替换每个nilad并计算运行的字符总数是一样的。

示例评分

  • (()()())得分5分,因为它有1个单数和3个零值。
  • (()()()){({}[()])}评分29分,因为第一部分和之前相同,5分,而循环包含6个单打和2个nilads,得分8分。循环运行3次,所以我们计算它的分数3次。1*5 + 3*8 = 29

Requirements

你的程序必须..。

  • 至少是两个字节
  • 使用-A标志在Brain中执行时打印其源代码
  • 与regex .*(<|>|\[])不匹配

贴士

  • 起重机-Flak解释器绝对比ruby解释器快,但缺少一些特性。我建议您先使用Crane-Flak测试代码,然后在您知道有效时在ruby解释器中对其进行评分。我也强烈建议不要在TIO中运行您的程序。TIO不仅比桌面解释器慢,而且在大约一分钟内就会超时。如果有人能在TIO超时之前运行他们的程序,这将是非常令人印象深刻的。
  • [(...)]{}(...)[{}]的工作方式与<...>相同,但不违反受限的源代码要求。
  • 如果您想了解如何应对这一挑战,可以查看脑Flak迷你Flak Quines。
EN

回答 1

Code Golf用户

发布于 2017-01-05 00:46:06

128,673,515循环

在网上试试

解释

Miniflak quines注定要慢下来的原因是Miniflak缺乏随机访问。为了解决这个问题,我创建了一个代码块,它接受一个数字并返回一个数据。每个数据表示一个字符,就像以前一样,主代码只是一次查询每个块。这实际上是一个随机访问内存块。

这段代码有两个要求。

  • 它必须使用一个数字,并且只输出该字符的字符代码。
  • 在Brain-Flak中,必须很容易地一点一点地再现查找表。

为了构造这个块,我实际上重用了一个证明Miniflak是的方法。对于每个数据,都有如下代码块:

代码语言:javascript
复制
(({}[()])[(())]()){(([({}{})]{}))}{}{(([({}{}(%s))]{}))}{}

这将从堆栈顶部的数字中减去一个,如果零将数据推到%s下面。因为每一段的大小都会减少一个,如果你从堆栈上的n开始,你就会得到第n个数据。

这是一个很好的和模块化的,所以它可以很容易地由一个程序编写。

接下来,我们必须设置将内存转换为源的机器。这包括以下三个部分:

代码语言:javascript
复制
(([()]())())
{({}[(
  -Look up table-
 )]{})
 1. (({}[()])[(())]()){(([({}{})]{}))}{}{([({}{}(([{}]))(()()()()()))]{})}{}

 2. (({}[()])[(())]()){(([({}{})]{}))}{}{([({}{}
      (({}[(
      ({}[()(((((()()()()()){}){}){}))]{}){({}[()(({}()))]{}){({}[()(({}((((()()()){}){}){}()){}))]{}){({}[()(({}()()))]{}){({}[()(({}(((()()()()())){}{}){}))]{}){([(({}{}()))]{})}}}}}{}
      (({}({}))[({}[{}])])
     )]{}({})[()]))
      ({[()]([({}({}[({})]))]{})}{}()()()()()[(({}({})))]{})
    )]{})}{}

 3. (({}[()])[(())]()){(([({}{})]{}))}{}{([({}{}
     (({}(({}({}))[({}[{}])][(
     ({}[()(
      ([()](((()()[(((((((()()()){})())){}{}){}){})]((((()()()()())){}{}){})([{}]([()()](({})(([{}](()()([()()](((((({}){}){}())){}){}{}))))))))))))
     )]{})
     {({}[()(((({})())[()]))]{})}{}
     (([(((((()()()()){}){}()))){}{}([({})]((({})){}{}))]()()([()()]({}(({})([()]([({}())](({})([({}[()])]()(({})(([()](([({}()())]()({}([()](([((((((()()()())()){}){}){}()){})]({}()(([(((((({})){}){}())){}{})]({}([((((({}())){}){}){}()){}()](([()()])(()()({}(((((({}())())){}{}){}){}([((((({}))){}()){}){}]([((({}[()])){}{}){}]([()()](((((({}())){}{}){}){})(([{}](()()([()()](()()(((((()()()()()){}){}){}()){}()(([((((((()()()())){}){}())){}{})]({}([((((({})()){}){}){}()){}()](([()()])(()()({}(((((({}){}){}())){}){}{}(({})))))))))))))))))))))))))))))))))))))))))))))))
     )]{})[()]))({()()()([({})]{})}{}())
    )]{})}{}

   ({}[()])
}{}{}{}
(([(((((()()()()){}){}())){}{})]((({}))([()]([({}())]({}()([()]((()([()]((()([({})((((()()()()){}){}()){})]()())([({})]({}([()()]({}({}((((()()()()()){}){}){}))))))))))))))))))

机器由四个部分组成,它们按顺序运行,从1开始,以3结尾。我在上面的代码中给它们贴上了标签。每个部分还使用与编码相同的查找表格式。这是因为整个程序包含在一个循环中,我们不希望每次运行循环时都运行每个部分,因此我们在每次运行时都使用相同的RA结构并查询我们希望的部分。

1

第1节是一个简单的设置部分。

该程序告诉第一次查询第1节和数据0。datum 0不存在,因此它不是返回该值,而是对每个数据只减少一次查询。这很有用,因为我们可以使用结果来确定数据的数量,这在以后的章节中将变得非常重要。第1节通过否定结果和查询记录数据的数量,第2节和最后的数据。唯一的问题是我们不能直接查询第2节。由于还有另一个减量,我们需要查询一个不存在的节5。事实上,每次我们在另一个节中查询一个节时,都会出现这种情况。但是,在我的解释中,我将忽略这一点,但是,如果您正在查看代码,只需记住5表示返回一节,而4表示再次运行相同的部分。

2

第2节将数据解码为数据块后组成代码的字符。每次它都希望堆栈显示为这样:

代码语言:javascript
复制
Previous query
Result of query
Number of data
Junk we shouldn't touch...

它将每个可能的结果(从1到6之间的数字)映射到6个有效的Miniflak字符((){}[])中的一个,并将其放置在数据数量以下,并使用“我们不应该碰的垃圾”。这给我们带来了一个堆栈,就像:

代码语言:javascript
复制
Previous query
Number of data
Junk we shouldn't touch...

从这里开始,我们需要查询下一个数据,或者如果我们已经查询了所有数据,则转移到第3部分。以前的查询实际上不是发送出去的确切查询,而是查询减去块中的数据数。这是因为每个数据都会将查询减少一个,所以查询的结果非常糟糕。要生成下一个查询,我们添加一个数据的副本并减去一个。现在,我们的堆栈看起来如下:

代码语言:javascript
复制
Next query
Number of data
Junk we shouldn't touch...

如果我们的下一个查询为零,我们已经读取了第3节所需的所有内存,因此我们再次将数据数添加到查询中,然后在堆栈的顶部按4以移动到第3节。如果下一个查询不是零,我们会在堆栈上放一个5来再次运行第2部分。

3

第3节和第3节一样,通过查询我们的RAM来生成数据块。

为了简洁起见,我将省略第3节的大部分细节。它几乎与第2节相同,除非不是将每个数据转换为一个字符,而是将每个数据转换为一个表示其在RAM中的条目的长代码块。当第3节完成时,它会告诉程序退出循环。

在循环运行之后,程序只需按quine ([()]())(()()()()){({}[(的第一个比特即可。我使用以下代码来实现标准的Kolmogorov-复杂性技术。

代码语言:javascript
复制
(([(((((()()()()){}){}())){}{})]((({}))([()]([({}())]({}()([()]((()([()]((()([({})((((()()()()){}){}()){})]()())([({})]({}([()()]({}({}((((()()()()()){}){}){}))))))))))))))))))

我希望这是清楚的。如果你对任何事情感到困惑,请发表评论。

票数 18
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/105127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档