浏览令人敬畏 的整数序列在线百科全书(参见en.wikipedia.org),我偶然发现了以下整数序列:
A031877:非平凡反转数(反转数的整数倍),不包括回文数和 10 的倍数。
通过重用我为回答相关问题“ Prolog 中语言算术的更快实现”而编写的一些代码,我可以毫不费力地写下一个解决方案——感谢clpfd!
:- use_module(library(clpfd)).
我们基于
(之前定义的)定义核心关系 :a031877_ndigits_/3
digits_number/2
a031877_ndigits_(Z_big,N_digits,[K,Z_small,Z_big]) :-
K #> 1,
length(D_big,N_digits),
reverse(D_small,D_big),
digits_number(D_big,Z_big),
digits_number(D_small,Z_small),
Z_big #= Z_small * K.
核心关系是确定性的,只要
是具体整数,就会普遍终止。N_digit
请亲自查看 ! 的前 100 个值N_digit
。
?- time((N in 0..99,indomain(N),a031877_ndigits_(Z,N,Zs),false)).
% 3,888,222 inferences, 0.563 CPU in 0.563 seconds (100% CPU, 6903708 Lips)
false
让我们运行一些查询!
?- a031877_ndigits_(87912000000087912,17,_)。 true % 成功,正如预期的那样 ; 错误的。 ?- a031877_ndigits_(87912000000 9 87912,17,_)。 错误的。% 失败,正如预期的那样
接下来,让我们找到一些恰好包含四个十进制数字的非平凡反转数:
?- a031877_ndigits_(Z,4,Zs), labeling([],Zs).
Z = 8712, Zs = [4,2178,8712]
; Z = 9801, Zs = [9,1089,9801]
; false.
好的!让我们测量证明上述查询的普遍终止所需的运行时间!
?- time((a031877_ndigits_(Z,4,Zs),labeling([],Zs),false)).
% 11,611,502 inferences, 3.642 CPU in 3.641 seconds (100% CPU, 3188193 Lips)
false. % terminates universally
现在,这太长了!
我能做些什么来加快速度?使用不同和/或其他约束?甚至可能是多余的?或者也许识别并消除削减搜索空间大小的对称性?不同的 clp(*) 域(b、q、r、set)呢?还是不同的一致性/传播技术?或者更确切地说是 Prolog 风格的协程?
有想法吗?我要他们所有!提前致谢。