Algorithm 如何为';破解密码';?

Algorithm 如何为';破解密码';?,algorithm,math,puzzle,Algorithm,Math,Puzzle,在一本益智书中,我发现了以下益智: 标题是荷兰语,但我可以很快地描述它: 在0…6范围内有一个数字序列,未给出 有6个数学陈述(如下所列)是正确的 通过使用逻辑并划掉某些你知道肯定不是它的数字,任何玩这个游戏的人都可以找到数字序列(代码) 例如,在图中的例子中,我们知道A+C=5,因此我们可以推断A和C都不能是6。通过反复执行这些操作,您将找到序列 现在,我的问题是:我如何编写一个生成这些谜题值的算法? 我试着提出一个随机序列,并用6个类似的数学语句来描述它,但在某些情况下,这个难题将无法

在一本益智书中,我发现了以下益智:

标题是荷兰语,但我可以很快地描述它:

  • 在0…6范围内有一个数字序列,未给出
  • 有6个数学陈述(如下所列)是正确的
  • 通过使用逻辑并划掉某些你知道肯定不是它的数字,任何玩这个游戏的人都可以找到数字序列(代码)
例如,在图中的例子中,我们知道A+C=5,因此我们可以推断A和C都不能是6。通过反复执行这些操作,您将找到序列

现在,我的问题是:我如何编写一个生成这些谜题值的算法? 我试着提出一个随机序列,并用6个类似的数学语句来描述它,但在某些情况下,这个难题将无法解决


例如,当序列为012345时,这种无法解决的情况/语句是语句
A+B=1
B+C=3
C+D=5
D+E=7
E+F=9
F+A=5
首先,让我们为这个问题详细说明一个解决方案
s

对于每个变量,创建一个集{0,1,2,3,4,5,6}及其可能的值

分析每个方程式,并根据方程式从变量集合中得出切割值

示例:A+B=3(我们可以从A和B组中剪切4、5和6)

当所有集合只有一个元素时,这就是你的答案

另一方面,如果所有的方程式都经过分析,并且没有改变集合,这是不可能的

现在,知道如何解决问题,我会用以下方法制作谜题:

随机选择一个答案

示例:(4、1、3、2、0、5)

用它生成6个随机方程

使用此方程式运行
S

如果
S
结束,则可能有一组方程式

否则,请重新启动


7^6=117649
可能的代码。对于6个问题,我们只需要每个问题删除6/7的搜索空间。如果前几个做得更多,那就更好了

这三个问题很简单。当你观察求和或求差的方法的分布时,你会发现,得到答案的方法最多只能是
7/49=49
,通常更少。把A,B,C,D,E,F分成3对2,提供随机操作,剩下的可能答案不超过343个

以你的例子,我随机生成了
D-A=4
C+F=7
D-B=2
。第一对我们有3种可能性,第二对我们有6种,第三对我们有5种

现在我们需要做的是构造所有的可能性(在本例中有90个)。然后,您可以构造随机语句,并且只接受位于解决方案1路径上的语句。也就是说,剩下3个问题,你至少要减去一个方根因子(本例中不超过20个可能性),再减去2个平方根因子(不超过4个),然后再减去一个可能性


假设一个随机问题平均会减少你的搜索空间至少6/7,那么随机问题很容易做到这一点。(挑战在于验证答案。)

这似乎只不过是简单的代数替换。此外,方程式中运算的选择并不重要。从

(D, B) (B, C)
我们得到

(D, C)
(D, A)
然后从

(D, C) (C, A)
我们得到

(D, C)
(D, A)
(A,D)的方程已经存在,所以我们可以同时求解这两个方程。从那里,很容易看到如何完成解决方案

为了创造一个难题,从任何这样的双方程开始,比如

(E, F) (E, F)
然后把其中一个分成更模糊的部分,比如

(E, B) (B, F)
这就给出了六个方程中的三个(记住,运算的选择可能是完全随机的)。我留给读者更多的思考来完成

我不期望完成和实现是微不足道的,但希望这能让我们了解如何在不回溯的情况下非常谨慎地完成这项工作

JavaScript代码:

const vars=[“A”、“B”、“C”、“D”、“E”、“F”];
函数getOps(对){
返回对。包括(0)[“+”,“-”]:[“+”,“-”,“*”];
}
函数getRandom(k,list){
让结果=[];
for(设i=0;i 0.5)
[a,b]=[b,a];
返回`${vars[idxs[a]]}${op}${vars[idxs[b]]}=${getNum(a,b,op)}`;
}
函数f(){
让剩余=[0,1,2,3,4,5,6];
让结果=[];
//删除一个条目
剩余的.拼接(~~(Math.random()*7),1);
//洗牌
剩余=getRandom(6,剩余);
const idxs=Object.fromEntries(
剩余.map((x,i)=>[x,i]);
//选择方程对
常数[a,b]=getRandom(2,剩余);
const[c,d]=getRandom(2,剩余);
结果:推(
getEquation(a,c,getRandom(1,getOps([a,c])),idxs),
getEquation(a,d,getRandom(1,getOps([a,d])),idxs),
getEquation(b,c,getRandom(1,getOps([b,c])),idxs),
getEquation(b,d,getRandom(1,getOps([b,d])),idxs)
);
const[e]=getRandom(1,剩余);
常数[f]=剩余;
const[aa]=getRandom(1[a,b,c,d]);
结果:推(
getEquation(e,f,getRandom(1,getOps([e,f])),idxs),
getEquation(e,aa,getRandom(1,getOps([e,aa])),idxs)
);
const legend=Object.entries(idxs)
.map(([x,i])=>[vars[i],Number(x)])
.map(([a,b])=>`(${a}${b})`)
.sort()
.加入(“”);
返回{
方程:getRandom(6,结果).join('\n'),
传奇:传奇
};
}
var result=f();
console.log(结果方程);
控制台日志(“”);

console.log(result.legend)这不是无法解决的,如果需要猜测,有时需要分支以找到解决方案(因此,请填写一个值,并进一步推理,如果这是一个死胡同,请删除该值并重试)。我认为更重要的是用给定的规则验证是否存在一个且只有一个解决方案。