交差 + 道路 = 危険 ==> 答え ==> 96233 + 62513=158746
別の例で答えを見つけやすくするための指示を探しています。私の先生の一人は、木を使ってそれを見つけることができると言いました。しかし、ツリーを使用して答えを見つけることが不可能な場合があります。
通常、自分が暗号演算ソリューションであるとどのように判断しますか?
交差 + 道路 = 危険 ==> 答え ==> 96233 + 62513=158746
別の例で答えを見つけやすくするための指示を探しています。私の先生の一人は、木を使ってそれを見つけることができると言いました。しかし、ツリーを使用して答えを見つけることが不可能な場合があります。
通常、自分が暗号演算ソリューションであるとどのように判断しますか?
1 つの簡単な方法:
変数を定義します (便宜上):
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))) *)
「交差点 + 道路 = 危険」に対応する連立方程式を書きます。
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.
効率化の鍵は、数字のインスタンス化を 1 つずつ段階的に選択し、すぐにテストして無効な選択をできるだけ早く破棄することです。これは Mathematica に翻訳できると確信しています。