简体   繁体   中英

Prolog: decompose number into its digits

I am studying prolog and I am faced with a problem that I cannot deal with.

Given a number, I have to check if the sum of the factorial of each digit that composes it is equal to the number itself.

Example:

145

1! + 4! + 5! = 1 + 24 + 120

Now my problem is just how to decompose the number so that I can factorial and sum each digit.

EDIT1.

thank to @slago I understand how decompose the number, but now I have a problem to sum the factorial terms:

fact(N):-
    fact(N, N, _ListNumber).
fact(N, 0, ListNumber):-
    factorial(ListNumber, 1, Sum),

    Sum == N.
fact(N, Number, [D|R]):-
    D is Number mod 10,
    Number1 is Number div 10,
    fact(N, Number1, R).

factorial([], Counter, Counter).
factorial([D|R], Counter, Sum):-
    print([D|R]),
    checksum(D, Counter),
        factorial(R, Counter, Sum).
checksum(D, Counter):-
    Counter1 is Counter * D,
    M is D - 1,
    M >= 2, !,
    checksum(M, Counter1).

I have tried like this, but I noticed [D|R] results empty, and I don't understand why.

Your code is organized in a very confusing way. It is best to code independent predicates (for more specific purposes) and, after that, use them together to get the answer you want.

Start by creating a predicate to decompose a natural number into digits.

decompose(N, [N]) :- N<10, !.
decompose(N, [D|R]) :- N>=10, D is N mod 10, M is N//10, decompose(M, R).

Example of decomposition:

?- decompose(145, D).
D = [5, 4, 1].

Then, create a predicate to compute the factorial of a natural number.

fact(N, F) :- fact(N, 1, F).

fact(0, A, A) :- !.
fact(N, A, F) :- N>0, M is N-1, B is N*A, fact(M, B, F).

Example of factorial:

?- fact(5, F).
F = 120.

After that, create a predicate to map each number of a list into its corresponding factorial (alternatively, you could use the predefined predicatemaplist/3 ).

map_fact([], []).
map_fact([X|Xs], [Y|Ys]) :- fact(X,Y), map_fact(Xs, Ys).

Example of mapping:

?- decompose(145, D), map_fact(D, F).
D = [5, 4, 1],
F = [120, 24, 1].

You must also create a predicate to compute the sum of the items of a list (alternatively, you could use the predefined predicate sum_list/2 ).

sum(L, S) :- sum(L, 0, S).

sum([], A, A).
sum([X|Xs], A, S) :- B is A+X, sum(Xs, B, S).

Example of summation:

?- decompose(145, D), map_fact(D, F), sum(F, S).
D = [5, 4, 1],
F = [120, 24, 1],
S = 145.

Finally, create the predicate to check the desired number property.

check(N) :- decompose(N, D), map_fact(D, F), sum(F, N).

Example:

?- check(145).
true.

?- check(146).
false.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM