我有一个关于我的个人项目的问题,这困扰了我。
目标是生成一组 8 个数字的所有合法组合,并分成 4 对。为了使组合被认为是合法的,每对的总和必须达到 6、5、4 或 3,而且每个数字都是正整数。含义 - 假设第一对数字之和为 6,则为 1:5、2:4、3:3、4:2 或 5:1;第二个(总和为 5)将为 1:4、2:3、3:2 或 4:1 等。这意味着在这种排列中有 5 * 4 * 3 * 2(或 5!) 的组合。我能够生成这 120 种组合(我希望是正确的),但这只是其中一种可能性。这些对可以对总和进行任意排列,因此可以有 24(或 4!)种方式对列对进行排列,从而给出 8 个数字的集合的总共 2880 种组合 - 这就是我想要的。
我无法找到有效且无需手动密集的解决方案。你们中有人能帮忙吗?您可以使用我为其创建的工作表: https://docs.google.com/spreadsheets/d/1jST8RJunGoMgA14CjHpjNG1rUwa0I6uGWIJzyS9FMY8/edit?usp=sharing
以6为例,生成数字
1..5
生成数字
5..1
将它们组合起来得到
1|5
2|4
等等
然后对每个总计(示例中的 5,4 和 3)递归重复此操作,将它们与每个阶段的先前结果相结合。每个阶段。
公式为
=ArrayFormula(let(pairs,lambda(self,i,size,if(i>columns(size),"",tocol(sequence(index(size,i)-1)&"|"&index(size,i)-sequence(index(size,i)-1)&"|"&transpose(self(self,i+1,size))))),split(pairs(pairs,1,{3,4,5,6}),"|")))
有多种方法,但对于小n来说最简单的方法是生成四个数字的所有可能组合(包括重复数字的组合)并过滤它们。
所得公式为:
=let(perms,makearray(256,4,lambda(r,c,mod(quotient(r,4^(4-c)),4)+3)),filter(perms,byrow(perms,lambda(r,countunique(r)))=4))
对每个排列的结果进行 Vstack,如下所示:
=ArrayFormula(let(perms,makearray(256,4,lambda(r,c,mod(quotient(r,4^(4-c)),4)+3)),fperms,filter(perms,byrow(perms,lambda(r,countunique(r)))=4),
pairs,lambda(self,i,size,if(i>columns(size),"",tocol(sequence(index(size,i)-1)&"|"&index(size,i)-sequence(index(size,i)-1)&"|"&transpose(self(self,i+1,size))))),
reduce({"","","","","","","",""},sequence(rows(fperms)),lambda(a,c,vstack(a,split(pairs(pairs,1,index(fperms,c,0)),"|"))))))