十字路口 + 道路 = 危险 ==> 答案是 ==> 96233 + 62513=158746
我正在寻找一个说明,以便更容易地找到另一个示例的答案。我的一位老师说我们可以用树来找到它。但有时使用树来找到答案是不可能的。
你通常如何找到你的密码解决方案?
十字路口 + 道路 = 危险 ==> 答案是 ==> 96233 + 62513=158746
我正在寻找一个说明,以便更容易地找到另一个示例的答案。我的一位老师说我们可以用树来找到它。但有时使用树来找到答案是不可能的。
你通常如何找到你的密码解决方案?
一种简单的方法:
定义变量(只是为了方便):
vars = Symbol[#] & /@ ("abc" <> ToString[#] & /@ Range[26]) ;
将变量与字母表的每个字母关联:
alphabet = Transpose[{CharacterRange["a", "z"], vars}];
编写一个辅助函数将字符串转换为表达式:
formDigits[astring_] := FromDigits[alphabet[[alphabet[[#, 2]] & /@
Position[alphabet[[All, 1]], #][[1, 1]] & /@ Characters[astring], 2]]]
例子 :
formDigits["cross"]
(* abc19 + 10 (abc19 + 10 (abc15 + 10 (abc18 + 10 abc3))) *)
写出对应于“Cross + road = danger”的方程组:
equation = formDigits["cross"] + formDigits["roads"] == formDigits["danger"]
最后解决具有明显附加约束的系统:
sol = First@FindInstance[{equation, Sequence @@ Thread[Thread[0 <= vars <= 9]],
Not[Apply[And, Thread[vars == 0]]]}, alphabet[[All, 2]], Integers] ;
查看 :
formDigits["cross"] /. sol
formDigits["roads"] /. sol
formDigits["danger"] /. sol
(* 78644
86614
165258 *)
这在 Prolog 中很自然地解决了。另请参阅Prolog 中口头算术的更快实现:
%% unique selection from narrowing domain
selectM([A|As],S,Z):- select(A,S,S1),selectM(As,S1,Z).
selectM([],Z,Z).
%% a puzzle
cryp([[C,R,O,S,S]+[R,O,A,D,S]=[D,A,N,G,E,R]]):-
Dom=[0,1,2,3,4,5,6,7,8,9],
selectM([S],Dom,D0),
N1 is S+S, R is N1 mod 10, R=\=0,
selectM([R,D],D0,D1), D=\=0,
N2 is (N1//10)+S+D, E is N2 mod 10,
selectM([E,O,A,G],D1,D2),
N3 is (N2//10)+O+A, G is N3 mod 10,
N4 is (N3//10)+R+O, N is N4 mod 10,
selectM([N,C],D2,_), C=\=0,
N5 is (N4//10)+C+R, A is N5 mod 10,
D is N5//10.
效率的关键是逐个选择数字的实例化,立即测试以尽快废弃无效的选择。我确信这可以翻译成 Mathematica。
像这个总和的另一个问题是
十字路口 + 道路 = 登格尔
这个问题的解决方案是
68244 + 82714 = 150958