另一种解决方案
我认为,这是该网站上最有趣的问题之一。我要感谢Deadcode使其重新回到顶部。
^((^|xx)(^|\3\4\4)(^|\4x{12})(^x|\1))*$
39个字节,没有任何条件或断言...之类的。在使用(^|
)时,交替是一种有条件的方式,可以在“第一次迭代”和“不是第一次迭代”之间进行选择。
可以看到此正则表达式在这里工作:http : //regex101.com/r/qA5pK3/1
PCRE和Python都正确地解释了正则表达式,并且它也在Perl中经过了n = 128的测试,包括n 4 -1和n 4 +1。
定义
通用技术与已发布的其他解决方案中的技术相同:定义一个自引用表达式,该表达式在每个后续迭代中都使用无限量词()匹配等于前向差分函数D f的下一项的长度*
。前向差分函数的正式定义:
此外,还可以定义高阶差分函数:
或更笼统地说:
前向差分函数具有许多有趣的特性。排序是对连续函数的导数。例如,d ˚F的Ñ次多项式将始终是一个N-1次多项式,并且对于任何我,如果d ˚F 我 = d ˚F i + 1的,则该函数˚F是指数的,在大致相同的方式e x的导数等于自身。最简单的离散函数为其˚F = d ˚F是2 Ñ。
f(n)= n 2
在研究上述解决方案之前,让我们从一些简单的事情开始:一个正则表达式,它匹配长度为完美平方的字符串。检查前向差异函数:
意,在第一迭代应匹配长度的串1,长度的第二字符串3,长度的第三串5等等,并且通常,每个迭代应比以前的匹配的字符串两个较长。相应的正则表达式几乎直接来自此语句:
^(^x|\1xx)*$
可以看出,第一次迭代将只匹配一个x
,而每个后续迭代将匹配一个比前一个字符串长两倍的字符串,这完全符合指定。这也意味着在perl中一个非常短的完美平方测试:
(1x$_)=~/^(^1|11\1)*$/
该正则表达式可以进一步推广为匹配任何n个角长度:
三角数:
^(^x|\1x{1})*$
平方数:
^(^x|\1x{2})*$
五角形数:
^(^x|\1x{3})*$
六角数:
^(^x|\1x{4})*$
等等
f(n)= n 3
转到n 3,再次检查前向差分函数:
如何实现这一点可能尚不明显,因此我们还要检查第二个差异函数:
因此,前向差分函数不会增加一个常数,而是一个线性值。D f 2的初始(“ -1 th”)值为零很好,这样可以节省第二次迭代的初始化时间。生成的正则表达式如下:
^((^|\2x{6})(^x|\1))*$
与之前一样,第一次迭代将匹配1,第二次迭代将匹配更长的字符串6(7),第三次将匹配更长的字符串12(19),依此类推。
f(n)= n 4
n 4的前向差分函数:
第二个前向差函数:
第三个正向差异函数:
现在很丑。D f 2和D f 3的初始值分别均为非零,2和12,这需要加以考虑。您现在可能已经知道正则表达式将遵循以下模式:
^((^|\2\3{b})(^|\3x{a})(^x|\1))*$
因为D f 3在第二次迭代中必须匹配12的长度,所以a一定是12。但是由于每项增加24,因此下一个更深层的嵌套必须使用其先前的值两次,这意味着b = 2。最后要做的是初始化D f 2。由于D f 2直接影响D f,这最终就是我们要匹配的D f,因此在这种情况下,可以通过将适当的原子直接插入正则表达式来初始化其值(^|xx)
。最终的正则表达式将变为:
^((^|xx)(^|\3\4{2})(^|\4x{12})(^x|\1))*$
高阶
五阶多项式可以与以下正则表达式匹配:
^((^|\2\3{c})(^|\3\4{b})(^|\4x{a})(^x|\1))*$
f(n)= n 5是一个相当容易的练习,因为第二个和第四个正向差分函数的初始值为零:
^((^|\2\3)(^|\3\4{4})(^|\4x{30})(^x|\1))*$
对于六阶多项式:
^((^|\2\3{d})(^|\3\4{c})(^|\4\5{b})(^|\5x{a})(^x|\1))*$
对于七阶多项式:
^((^|\2\3{e})(^|\3\4{d})(^|\4\5{c})(^|\5\6{b})(^|\6x{a})(^x|\1))*$
等等
注意,如果任何必要的系数不是整数,则并非所有多项式都可以完全按照这种方式进行匹配。例如,n 6要求a = 60,b = 8和c = 3/2。在这种情况下,可以解决此问题:
^((^|xx)(^|\3\6\7{2})(^|\4\5)(^|\5\6{2})(^|\6\7{6})(^|\7x{60})(^x|\1))*$
在这里,我将b更改为6,将c更改为2,它们的乘积与上述值相同。重要的是,乘积不要改变,因为a·b·c·…控制着常数差函数,对于六阶多项式,常数差函数为D f 6。存在两个初始化原子:一个用于将D f初始化为2(与n 4一样),另一个将第五个差分函数初始化为360,同时将b中缺少的两个相加。