我想枚举满足给定条件的 3 个或更多有限值变量的所有组合(值的元组)。在数学符号中:
例如(受Project Euler 问题 9启发):
一次两个变量的真值表很简单:
a ∘.≤ b
1 1 1 1
0 1 1 1
0 0 1 1
b ∘.≤ c
1 1 1 1 1
0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
经过一番摸索,我设法将它们结合起来,通过计算前者的每个 4 值行的 ∧ 和后者的每个 4 值列,并在正确的轴上显示 (⊃),介于 1 和 2 之间:
⎕← tt ← ⊃[1.5] (⊂[2] a ∘.≤ b) ∘.∧ (⊂[1] b ∘.≤ c)
1 1 1 1 1
0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
0 0 0 0 0
0 1 1 1 1
0 0 1 1 1
0 0 0 1 1
0 0 0 0 0
0 0 0 0 0
0 0 1 1 1
0 0 0 1 1
然后我可以使用它的 ravel 过滤所有可能的值元组:
⊃ (,tt) / , a ∘., b ∘., c
1 1 1
1 1 2
1 1 3
1 1 4
1 1 5
1 2 2
1 2 3
...
3 3 5
3 4 4
3 4 5
这是解决 APL 中这类特定问题的最佳方法吗?
此示例或一般情况是否有更简单或更快的公式?
更一般地说,将我上面的(天真的?)数组方法与传统的标量语言进行比较,我可以看到我正在将每个循环转换为一个额外的维度:3 个嵌套循环成为一个 3 秩真值表:
for c in 1..NC:
for b in 1..min(c, NB):
for a in 1..min(b, NA):
collect (a,b,c)
但是在标量语言中,可以在此过程中进行优化,例如尽快中断循环,或动态选择循环边界。在这种情况下,我什至不需要测试 a ≤ b ≤ c,因为它隐含在循环边界中。
在此示例中,两种方法都具有 O(N³) 复杂度,因此它们的运行时间只会相差一个因素。但我想知道:如果需要,如何以更优化的方式编写数组解决方案?
是否有任何解决 APL 算法问题或最佳实践的好书或在线资源?