Prolog - merge digits to number

2020-04-15 20:50发布

I want to merge list of digits to number.

[1,2,3] -> 123

My predicate:

merge([X], X).
merge([H|T], X) :- 
   merge(T, X1),
   X is X1 + H * 10.

But now I get: [1,2,3] -> 33

标签: prolog
2条回答
闹够了就滚
2楼-- · 2020-04-15 21:28

Another way to do it would be to multiply what you've handled so far by ten, but you need an accumulator value.

merge(Digits, Result) :- merge(Digits, 0, Result).

merge([X|Xs], Prefix, Result) :-
    Prefix1 is Prefix * 10 + X,
    merge(Xs, Prefix1, Result).
merge([], Result, Result).
查看更多
我欲成王,谁敢阻挡
3楼-- · 2020-04-15 21:28

The math is off. You're rule says you have to multiply H by 10. But really H needs to be multiplied by a power of 10 equivalent to its position in the list. That would be * 100 for the 1, and * 10 for the 2. What you get now is: 10*1 + 10*2 + 3 which is 33. The problem is that your recursive clause doesn't know what numeric "place" the digit is in.

If you structure the code differently, and use an accumulator, you can simplify the problem. Also, by using CLP(FD) and applying some constraints on the digits, you can have a more general solution.

:- use_module(library(clpfd)).

digits_number(Digits, X) :-
    digits_number(Digits, 0, X).

digits_number([], S, S).
digits_number([D|Ds], S, X) :-
    D in 0..9,
    S1 #= S*10 + D,
    digits_number(Ds, S1, X).

?- digits_number([1,2,3], X).
X = 123

?- digits_number(L, 123).
L = [1, 2, 3] ;
L = [0, 1, 2, 3] ;
L = [0, 0, 1, 2, 3] ;
L = [0, 0, 0, 1, 2, 3] ;
L = [0, 0, 0, 0, 1, 2, 3]
...

?-
查看更多
登录 后发表回答