このディレクトリの索引
#  
#  お題:整数同士の掛け算の筆算の計算過程を表示するプログラム
#  

整数同士の掛け算の筆算の計算過程を表示する(_整数_1,_整数_2) :-
        それぞれの整数を数値ならびに変換(_整数_1,_整数_2,_整数ならび_1,_整数ならび_2),
        掛け算の筆算の計算過程を表示する(_整数ならび_1,_整数ならび_2).

それぞれの整数を数値ならびに変換(_整数_1,_整数_2,_整数ならび_1,_整数ならび_2) :-
        number_chars(_整数_1,Chars_1),
        number_chars(_整数_2,Chars_2),
        数字ならびを数値ならびに変換(Chars_1,_整数ならび_1),
        数字ならびを数値ならびに変換(Chars_2,_整数ならび_2).

数字ならびを数値ならびに変換([],[]).
数字ならびを数値ならびに変換([A|R1],[N|R2]) :-
        atom_number(A,N),
        数字ならびを数値ならびに変換(R1,R2).

掛け算の筆算の計算過程を表示する(_整数ならび_1,_整数ならび_2) :-
        reverse(_整数ならび_1,_反転した整数ならび_1),
        reverse(_整数ならび_2,_反転した整数ならび_2),
        '掛け算の筆算の計算過程(下の桁から掛ける)を表示する'(0,_反転した整数ならび_1,_反転した整数ならび_2,_前段の数ならび),
        各桁の加算を表示する(_全段の数ならび).

'掛け算の筆算の計算過程(下の桁から掛ける)を表示する'(_,_,[],[]).
'掛け算の筆算の計算過程(下の桁から掛ける)を表示する'(_n,L1,[_m|R2],[L2|R4]) :-
        乗数がn桁目の掛算(_n,_m,L1,L2),
        '掛け算の筆算の計算過程の表示'(_n,_m,L1,L2),
        _n_2 is _n + 1,
        '掛け算の筆算の計算過程(下の桁から掛ける)を表示する'(_n_2,L1,R2,R4).

'掛け算の筆算の計算過程の表示'(_n,_m,L1,L2) :-
        reverse(L1,L1_2),
        atomic_list_concat(L1_2,S1),
        reverse(L2,L2_2),
        atomic_list_concat(L2_2,S2),
        writef('%t×%t=% t ... (%t)\n',[S1,_m,S,_n2]).

乗数がn桁目の掛算(_n,_m,L1,L2) :-
        length(L4,_n),
        all(L4,0),
        append(L4,L1,L1_2),
        段の掛算(_m,L1_2,0,[],L2),!.

段の掛算(_,[],0,L,L) :- !.
段の掛算(_,[],C,L1,[C|L1]) :- !.
段の掛算(M,[N|R2],C,L3,L) :-
        九九掛算(M,N,N1,N2),
        D is (N1 * 10 + C + N2) // 10,
        M2 is (C + N2) mod 10,
        段の掛算(M,R2,D,[M2|L3],L).

各桁の加算を表示する(_全段の数ならび) :-
        全段を逆順に並べ直す(_全段の数ならび,_逆順の全段の数ならび),
        length(_全段の数ならび,Len),
        各桁の加算を表示する(_逆順の全段の数ならび,Len,0).

各桁の加算を表示する([],Len,S) :-
        findall(S,(
                    between(1,Len,N),
                    swritef(S,'(%w)',[N])),
                L),
        atomic_list_concat(L,'+',S1),
        writef('%w=%w\n',[S1,S]),!.
各桁の加算を表示する(_逆順の全段の数ならび,Len,S) :-
        下の桁から加算する(_逆順の前段の数ならび,0,S1,R2),
        各桁の加算を表示する(R2,Len,S1).

全段を逆順に並べ直す([],[]).
全段を逆順に並べ直す([L1|R1],[L2|R2]) :-
        reverse(L1,L2),
        全段を逆順に並べ直す(R1,R2).

下の桁から加算する([],S,S,[]).
下の桁から加算する([[M|R1_1]|R1],S1,S,[R1_1|R2]) :-
        S2 is S1 + M,
        下の桁から加算する(R,S2,S,R2),!.
下の桁から加算する([[]|R1],S1,S,R2) :-
        下の桁から加算する(R,S1,S,R2).

九九掛算(M,N,X_1,X_2) :-
        length(L1,M),
        length(L2,N),
        append(L1,L2,L3),
        ならびの割り算(L3,[_,_,_,_,_,_,_,_,_,_],L4,L5),
        length(L4,X_1),
        length(L5,X_2).

九九掛算(0,0,0,0).
九九掛算(0,1,0,0).
九九掛算(0,2,0,0).
九九掛算(0,3,0,0).
九九掛算(0,4,0,0).
九九掛算(0,5,0,0).
九九掛算(0,6,0,0).
九九掛算(0,7,0,0).
九九掛算(0,8,0,0).
九九掛算(0,9,0,0).
九九掛算(1,0,0,0).
九九掛算(1,1,0,1).
九九掛算(1,2,0,2).
九九掛算(1,3,0,3).
九九掛算(1,4,0,4).
九九掛算(1,5,0,5).
九九掛算(1,6,0,6).
九九掛算(1,7,0,7).
九九掛算(1,8,0,8).
九九掛算(1,9,0,9).
九九掛算(2,0,0,0).
九九掛算(2,1,0,2).
九九掛算(2,2,0,4).
九九掛算(2,3,0,6).
九九掛算(2,4,0,8).
九九掛算(2,5,1,0).
九九掛算(2,6,1,2).
九九掛算(2,7,1,4).
九九掛算(2,8,1,6).
九九掛算(2,9,1,8).
九九掛算(3,0,0,0).
九九掛算(3,1,0,3).
九九掛算(3,2,0,6).
九九掛算(3,3,0,9).
九九掛算(3,4,1,2).
九九掛算(3,5,1,5).
九九掛算(3,6,1,8).
九九掛算(3,7,2,1).
九九掛算(3,8,2,4).
九九掛算(3,9,2,7).
九九掛算(4,0,0,0).
九九掛算(4,1,0,4).
九九掛算(4,2,0,8).
九九掛算(4,3,1,2).
九九掛算(4,4,1,6).
九九掛算(4,5,2,0).
九九掛算(4,6,2,4).
九九掛算(4,7,2,8).
九九掛算(4,8,3,2).
九九掛算(4,9,3,6).
九九掛算(5,0,0,0).
九九掛算(5,1,0,5).
九九掛算(5,2,1,0).
九九掛算(5,3,1,5).
九九掛算(5,4,2,0).
九九掛算(5,5,2,5).
九九掛算(5,6,3,0).
九九掛算(5,7,3,5).
九九掛算(5,8,4,0).
九九掛算(5,9,4,5).
九九掛算(6,0,0,0).
九九掛算(6,1,0,6).
九九掛算(6,2,1,2).
九九掛算(6,3,1,8).
九九掛算(6,4,2,4).
九九掛算(6,5,3,0).
九九掛算(6,6,3,6).
九九掛算(6,7,4,2).
九九掛算(6,8,4,8).
九九掛算(6,9,5,4).
九九掛算(7,0,0,0).
九九掛算(7,1,0,7).
九九掛算(7,2,1,4).
九九掛算(7,3,2,1).
九九掛算(7,4,2,8).
九九掛算(7,5,3,5).
九九掛算(7,6,4,2).
九九掛算(7,7,4,9).
九九掛算(7,8,5,6).
九九掛算(7,9,6,3).
九九掛算(8,0,0,0).
九九掛算(8,1,0,8).
九九掛算(8,2,1,6).
九九掛算(8,3,2,4).
九九掛算(8,4,3,2).
九九掛算(8,5,4,0).
九九掛算(8,6,4,8).
九九掛算(8,7,5,6).
九九掛算(8,8,6,4).
九九掛算(8,9,7,2).
九九掛算(9,0,0,0).
九九掛算(9,1,0,9).
九九掛算(9,2,1,8).
九九掛算(9,3,2,7).
九九掛算(9,4,3,6).
九九掛算(9,5,4,5).
九九掛算(9,6,5,4).
九九掛算(9,7,6,3).
九九掛算(9,8,7,2).
九九掛算(9,9,8,1).

all([],0).
all([A|R],A) :-
    all(R,A).

ならびの割り算([],_,[],[]) :- !.
ならびの割り算(_被除算項,_除算項,[_|_R3],_剰余項) :-
    length(_除算項,N),
    length(_除算項_2,N),
    append(_除算項_2,R,_被除算項),
    ならびの割り算(R,_除算項_2,_R3,_剰余項),!.
ならびの割り算(L,_,[],_剰余項) :-
    length(L,N),
    length(_剰余項,N),!.