混沌滴(构建最小非周期性序列)


9

这里的想法是产生几乎重复的图案。即,正在构建的序列在最后时刻改变,以避免重复某些子序列。应避免使用AA和ABA类型的子序列(其中B不超过A)。

例子:

我将继续列出所有小例子,以使我的描述更加清楚。让我们从0开始。

有效:0

无效:00(AA模式)
有效期:01

无效:010(ABA模式)
无效:011(AA模式)
有效期:012

有效期:0120
无效:0121(ABA模式)
无效:0122(AA模式)

无效:01200(AA模式)
无效:01201(ABA模式; 01-2-01)
无效:01202(ABA模式)
有效期:01203

现在,我坚信4即使我没有证明,也不需要a,因为我很容易找到了仅使用的数百个字符长的序列0123。(这可能与如何只需要三个字符来具有不具有任何AA模式的无限字符串密切相关。此页面上有Wikipedia。)

输入输出

输入是一个非零的正整数n。您可能会认为n <= 1000

输出是一个- n字符序列,没有与禁止模式(AA或ABA)匹配的子序列。

样本输入和输出

>>> 1
0

>>> 2
01

>>> 3
012

>>> 4
0120

>>> 5
01203

>>> 50
01203102130123103201302103120132102301203102132012

规则

  • 0123允许使用字符。
  • B是不超过A.这是为了避免出现这种情况012345一直要遵循6,因为0123451有这样的:1-2345-1。换句话说,该序列将是琐碎且无趣的。
  • n可以通过任何所需的方法输入,硬编码除外
  • 输出可以是列表,也可以是字符串,这取决于哪个更容易。
  • 没有强力 ; 在非常慢的计算机上,运行时间应为几分钟左右,最多为一个小时n=1000。(这旨在取消仅循环遍历的所有n排列的解决方案的资格{0,1,2,3},因此不允许使用技巧和类似技巧。)
  • 像往常一样,不允许出现标准漏洞
  • 得分以字节为单位。这是,因此最短的条目将获胜(可能-见奖金)。
  • 奖励:在每一步中选择允许的最低数字。如果1并且3是序列中下一位数字的可能选择,请选择1。从您的分数中减去5个字节。但是,请注意以下注意事项。

注意!

死胡同是可能的。您的程序或函数必须避免这些。这是一个例子:

树桩:01203102130123103201302103120132102301203102132012302103120130231032012302132031023012032102312013201302103123013203102130120321023013203123021032012310213012031023023013203123021021320123102130120
树桩:01203102130123103201302103120132102301203102132012302103120130231032012302132031023012032102312013201310310301301320310213012032102301320312302103201231021301203102301313123123021320123102130123
树桩:01203102130123103201302103120132102301203102132012302103120130231032012302132031023012032102312013201310310301301320310213012032102301320312302103201231021301203102301320312302132012310320
树桩:0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201320130210312301320310213012032102301320312302103201231021301203102301320312302132012310321301203102130

这些序列中的每一个都不能进一步扩展(不使用4)。但也请注意,前两个与后两个之间存在重要差异。我将用替换共享的初始子序列,X以使其更清楚。

树桩:X2130120
树桩:X2130123
树桩:X320
树桩:X321301203102130

的最后两位数字X10,因此下一位数字的唯一可能选择是23。选择2会导致序列必须终止的情况。贪心算法将不会在这里工作。(无论如何也不是没有回溯的。)


即使在现实时间内不会给出输出,也可以使用蛮力策略测试每个可能的字符串吗?您知道所有解决方案都可以n吗?如果有人给出启发式半贪婪算法,您将如何检查它在很长的时间内没有遇到问题?普遍的问题是一个有趣的问题,在避免模式的限制条件下,我无法找到任何东西,因为我们会限制部分模式的长度。如果有人可以制作一个通用的食谱,我希望这是最好的方法。
xnor

我相信我在规则中不允许使用暴力。我应该强调一下。我没有证据表明所有解决方案都存在n,但是鉴于我的程序发现的树桩每次平均平均要长10位,因此我非常确定存在无限序列。我不确定如何针对任意大序列测试半贪婪算法。我可以将要求限制为n= 1000,而不必担心更高的要求n
El'endia Starman

4
我想AA真的键入ABA哪里B是空的。这也许有助于简化某些解决方案。
mathmandan

Answers:


6

视网膜,86字节-5 = 81

$
_
(r`^(?<-2>.)+_((.)+)\b$
$1!
\b$
0
3#
#
0#
1
1#
2
2#
3
)r`\1(?<-2>.)*((.)+)$
$0#
!
<empty>

其中<empty>代表空的尾随线。您可以从带有-s标志的单个文件中运行以上代码。

输入应以一元形式给出,例如111111。我还没有测试过数千种输出的输出-一段时间后,两个正则表达式可能会变慢-但它可以在几秒钟内轻松处理几百个。

说明

这是一个简单的回溯解决方案。

  1. 附加一个0
  2. 当前序列无效时,删除所有尾随的3s并增加最后一个non- 3
  3. 重复直到我们得到所需长度的有效序列。

这种回溯是通过一个正则表达式替换循环实现的,一旦字符串在一次迭代中保持不变,该循环就会中止。

$
_

这会将a附加_到输入中,用于将一元输入与我们正在构建的序列分开。

(r`^(?<-2>.)+_((.)+)\b$
$1!

这是循环中的第一个替换项(由前导指示()。如果a)字符串末尾有单词字符(即数字),则表示该正则表达式匹配(这意味着字符串有效-我们将在下面看到无效序列用尾部标记#),并且b)至少存在序列中的字符数与输入中的字符数相同(使用平衡组进行检查)。如果是这种情况,我们将删除输入并附加一个!。这样!可以使循环中的所有正则表达式均失败,从而使其终止。

\b$
0

如果结尾处有一个单词字符(即序列有效,并且循环未由上一步终止),请附加一个0

3#
#

如果(相反)序列被标记为无效并以结尾3,则我们将其删除3(但将序列保留为无效,因为当前前缀无法继续执行,因此下一个字符也需要回溯)。

0#
1
1#
2
2#
3

如果序列标记为无效并且3末尾以外的任何数字,我们将递增该数字并删除标记。

)r`\1(?<-2>.)*((.)+)$
$0#

循环中的最后一个替换(如所示))。它检查字符串是否以ABA(结尾B不超过A但可能为空)结尾。的相对长度AB使用的平衡组再次检查,并且重复A与简单反向引用检查。

如果此正则表达式匹配,则通过附加将序列标记为无效#

!
<empty>

循环终止后,我们要做的就是删除!和,然后留下所需的输出。


2

Python 2 175-5 = 170字节

n=input();s='';u=j=-1
while n>len(s):
 while u>2:u=int(s[0]);s=s[1:]
 u+=1;t=`u`+s;m=c=0
 while t[c:]*0**m:c+=1;i=t[c:].find(t[:c]);m=j<i<=c
 if c>=len(t):s=t;u=j
print s[::j]

这是带有回溯的贪婪算法。我希望它短一些。我希望它是正确的(见下文)。

它一次构建一个数字的字符串。给定d已找到的一串数字,它会尝试将a附加0(d+1)第一个数字。如果这不起作用,则尝试按1,然后按2,然后按3。如果这些都不起作用,那么它将返回到d第一个数字并对其进行递增(如果小于3)或将其删除(如果等于3,在这种情况下,它将递增前一个,依此类推)。

有效性检查就是其中的一行.find。万一有人决定阅读我的代码,我应该说这个程序实际上是在向后存储字符串,这意味着它将数字添加到前面。因此,检查涉及寻找字符串中后面几位再次出现第一位 c数字的位置(第一位c数字之后的任何位置),以及是否存在这样的位置,中间长度是否最大c

(当然,它会在打印之前反转字符串。)

它也很容易更快。我最初是为了提高效率而使它早早退出各种循环,但那会浪费宝贵的字节。不过,它在的范围内仍然可以n=1000

无论如何,该程序似乎确实表现出对较小数字的偏爱,但这并不是一个很强的偏爱。例如,使用运行它n=2000给了我一个带有523零,一502497二和478三的字符串,以结尾30210312013021。因此,如果其他人正在研究贪婪算法,也许他们可以确认这一结果。或与n=1000我得到[263, 251, 248, 238]的数字计数。

最后,我想提的是,这些计数是那种对称的暗示,几乎(虽然不完全),就好像我们已经开始与均匀分布,然后转换了一些3年代到0的和少数人的2‘s到1’ s。但这显然只是巧合。我不知道!


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.