このディレクトリの索引

http://pc12.2ch.net/test/read.cgi/tech/1153585095/918
#  所謂覆面算で 
#  英字一文字が一桁の数字(0-9)で表されるとき 
#  one 
#  + nine 
#  + twenty 
#  + fifty 
#  = eighty 
#  となる組み合わせを検索してください 
#  各行の先頭の文字は0以外です 
# 
% 'one + nine + twenty + fifty = eighty'

覆面算(S,LX) :-
    覆面算(S,_文字数,_先頭文字ならび,_左項式,_右項式),
    順列([0,1,2,3,4,5,6,7,8,9],_文字数,LX2),
    変数を対応させる(_先頭文字ならび,LX2,LX),
    A is _右項式,
    B is _左項式,
    A = B.

覆面算(S,_文字数,_先頭文字ならび,_左項式,_右項式) :-
    split(S,['+',' '],L),
    各項の先頭文字(L,_先頭文字ならび),
    append(L1,LX,L),
    concat_atom(L,S1),
    atom_chars(S1,L2),
    各文字に変数を割り当てる(L2,[],LV),
    length(LV,_文字数),
    式を構成する(L1,LV,_左項式),
    式を構成する(L2,LV,_右項式).

各文字に変数を割り当てる([],X,X).
各文字に変数を割り当てる([A|R1],Y,X) :-
    member(A,[A=_,Y]),
    各文字に変数を割り当てる(R1,Y,X).
各文字に変数を割り当てる([A|R1],Y,X) :-
    not(member([A=_,Y])),
    各文字に変数を割り当てる(R1,[A=_|Y],X).

式を構成する([],_,0).
式を構成する([A|R1],LV,_式 + Y) :-
    atom_chars(A,Chars),
    length(Chars,Len),
    覆面数値式(Len,LV,Chars,_式),
    式を構成する(R1,LV,Y).

覆面数値式(0,_,_,0) :- !.
覆面数値式(N,LV,[A|R1],B + C) :-
    member(A=V,LV),
    B = ((10 ^ (N-1)) * V),
    N2 is N - 1,
    覆面数値式(N2,LV,R1,C).

変数を対応させる(_,[],[]) :- !.
変数を対応させる(_先頭文字ならび,[A|R1],[B=A|R2]) :-
    member(B,_先頭文字ならび),!,
    not(A=0),
    変数を対応させる(_先頭文字ならび,R1,R2).
変数を対応させる(_先頭文字ならび,[A|R1],[B=A|R2]) :-
    not(member(B,_先頭文字ならび)),
    変数を対応させる(_先頭文字ならび,R1,R2).

各項の先頭文字(L,_先頭文字ならび) :-
    findall(C,(member(A,L),sub_atom(A,0,1,_,C)),_先頭文字ならび).