このディレクトリの索引
#  問題
#  数字がひとつ不明な13桁のISBNコードを復元せよ。
#  例(不明な所を?とする)
#  9784062?72211 => 9784062772211
#  978415031?684 => 9784150310684

'数字がひとつ不明な13桁のISBNコードを復元せよ。'(_未知符号を含む13桁のISBNコード,_復元された13桁のISBNコード) :-
        atom_chars(_未知符号を含む13桁のISBNコード,_未知符号を含む13要素のならび),
        '各桁を数値に変換した上で、12要素の数値ならびと最終桁の数に分離し'(_未知符号を含む13要素のならび,_未知符号を解決した12要素の数値ならび,_最終桁の数),
        '12要素の数値ならびを逆順にして、順に3,1を掛けて加算し'(_未知符号を解決した12要素の数値ならび,_加算された数),
        '加算された数を10で割った余りをさらに10から引いたものが最終桁の数になる'(_加算された数,_最終桁の数),
        'ISBNコードを復元する'(_未知符号を解決した12要素の数値ならび,_最終桁の数,_復元された13桁のISBNコード).

'各桁を数値に変換した上で、12要素の数値ならびと最終桁の数に分離し'(L1,L2,_最終桁の数) :-
        各桁を数値に変換したならび(L1,L3),
        append(L2,[_最終桁の数],L3).

各桁を数値に変換したならび([],[]).
各桁を数値に変換したならび([_文字|R1],[_数値または変数|R2]) :-
        数値または変数に変換(_文字,_数値または変数),
        各桁を数値に変換したならび(R1,R2).

数値または変数に変換((?),_数値または変数) :-
        member(_数値または変数,[0,1,2,3,4,5,6,7,8,9]).
数値または変数に変換(A,_数値または変数) :-
        atom_number(A,_数値または変数).

'12要素の数値ならびを逆順にして、順に3,1を掛けて加算し'(_12要素の数値ならび,_加算された数) :-
        reverse(_12要素の数値ならび,_反転した12要素の数値ならび),
        findsum(S,(
                    append(L0,[N1,N2|_],_反転した12要素の数値ならび),
                    要素数が偶数(L0),
                    S is N1 * 3 + N2 * 1),
                _加算された数).

'加算された数を10で割った余りをさらに10から引いたものが最終桁の数になる'(_加算された数,_最終桁の数) :-
        _最終桁の数 is 10 - (_加算された数 mod 10).

要素数が偶数(L) :-
        length(L,_要素数),
        0 is _要素数 mod 2.

'ISBNコードを復元する'(_未知符号を解決した12要素の数値ならび,_最終桁の数,_復元された13桁のISBNコード) :-
        append(_未知符号を解決した12要素の数値ならび,[_最終桁の数],L1),
        atomic_list_concat(L1,_復元された13桁のISBNコード).